diff --git a/app/corpora/json_routes.py b/app/corpora/json_routes.py
index 4fd3a042a9bd681d90516de7a1713e8a4c71969c..79283aafa7aff677d6cb5105753825dddb30e75e 100644
--- a/app/corpora/json_routes.py
+++ b/app/corpora/json_routes.py
@@ -61,7 +61,7 @@ def build_corpus(corpus_id):
 @bp.route('/stopwords')
 @content_negotiation(produces='application/json')
 def get_stopwords():
-    nltk.download('stopwords')
+    nltk.download('stopwords', quiet=True)
     languages = ["german", "english", "catalan", "greek", "spanish", "french", "italian", "russian", "chinese"]
     stopwords = {}
     for language in languages:
diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js
index c182019b706fa9346b90c45b6036657fab354289..2bdfac58a8619a20e4d796ae7324dfde983690ec 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js
@@ -25,12 +25,12 @@ class CorpusAnalysisApp {
   async init() {
     this.disableActionElements();
     this.elements.m.initModal.open();
-  
+
     try {
       // Setup CQi over SocketIO connection and gather data from the CQPServer
       const statusTextElement = this.elements.initModal.querySelector('.status-text');
       statusTextElement.innerText = 'Creating CQi over SocketIO client...';
-      const cqiClient = new cqi.CQiClient('/cqi_over_sio');
+      const cqiClient = new cqi.Client('/cqi_over_sio');
       statusTextElement.innerText += ' Done';
       statusTextElement.innerHTML = 'Waiting for the CQP server...';
       const response = await cqiClient.api.socket.emitWithAck('init', this.corpusId);
diff --git a/app/static/js/CorpusAnalysis/Utils.js b/app/static/js/CorpusAnalysis/Utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..1ffe1dc027e37066b6b13914b8e050a9c2abd19e
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/Utils.js
@@ -0,0 +1,53 @@
+  /**
+   * @param {cqi.models.corpora.Corpus} corpus
+   * @param {number[]} cposList
+   * @returns {Promise<object>}
+   */
+async function lookupsByCpos(corpus, cposList) {
+  let lookups = {};
+  lookups['cpos_lookup'] = {};
+  for (let cpos in cposList) {
+    lookups['cpos_lookup'][cpos] = {};
+  }
+
+  let pAttrs = await corpus.positionalAttributes.list();
+  for (let attr in pAttrs) {
+    let values = await attr.valuesByCpos(cposList);
+    for (let i = 0; i < cposList.length; i++) {
+      let cpos = cposList[i];
+      let value = values[i];
+      lookups['cpos_lookup'][cpos][attr.name] = value;
+    }
+  }
+
+  let sAttrs = await corpus.structuralAttributes.list();
+  for (let attr in sAttrs) {
+    // We only want to iterate over non subattributes, identifiable by
+    // sAttr.hasValues == false
+    if (attr.hasValues) {continue;}
+
+    let idList = await attr.idsByCpos(cposList);
+    for (let i = 0; i < cposList.length; i++) {
+      let cpos = cposList[i];
+      let id = idList[i];
+      if (id == -1) {continue;}
+      lookups['cpos_lookup'][cpos][attr.name] = id;
+    }
+
+    let occuredIdList = Array.from(new Set(idList.filter(x => x != -1)));
+    if (occuredIdList.length == 0) {continue;}
+  
+    let subattrs = sAttrs.filter(x => x.name.startsWith(`${attr.name}_`));
+    if (subattrs.length == 0) {continue;}
+
+    let lookupName = `${attr.name}_lookup`;
+    lookups[lookupName] = {};
+    for (let id in occuredIdList) {
+      lookups[lookupName][id] = {};
+    }
+    
+    
+  }
+
+  return lookups;
+}
diff --git a/app/static/js/app/index.js b/app/static/js/app/index.js
deleted file mode 100644
index 8a7ef15240b3b87548080ee70b9aa8853a8fbbf9..0000000000000000000000000000000000000000
--- a/app/static/js/app/index.js
+++ /dev/null
@@ -1 +0,0 @@
-App = {};
diff --git a/app/static/js/cqi/api/client.js b/app/static/js/cqi/api/client.js
index 23695987057aaba1c9e07af927f5a3784250718a..64495873be24142db2d82b114e8a95df645d5fa4 100644
--- a/app/static/js/cqi/api/client.js
+++ b/app/static/js/cqi/api/client.js
@@ -1,4 +1,4 @@
-cqi.api.APIClient = class APIClient {
+cqi.api.Client = class Client {
   /**
    * @param {string} host
    * @param {number} [timeout=60] timeout
diff --git a/app/static/js/cqi/client.js b/app/static/js/cqi/client.js
index b1d2944708133430b216170ad00e2737bae07e80..dab97828a79e357d38361f8097758e83f9f274b7 100644
--- a/app/static/js/cqi/client.js
+++ b/app/static/js/cqi/client.js
@@ -1,12 +1,12 @@
-cqi.CQiClient = class CQiClient {
+cqi.Client = class Client {
   /**
    * @param {string} host
    * @param {number} [timeout=60] timeout
    * @param {string} [version=0.1] version
    */
   constructor(host, timeout = 60, version = '0.1') {
-     /** @type {cqi.api.APIClient} */
-    this.api = new cqi.api.APIClient(host, timeout, version);
+     /** @type {cqi.api.Client} */
+    this.api = new cqi.api.Client(host, timeout, version);
   }
 
   /**
diff --git a/app/static/js/cqi/models/attributes.js b/app/static/js/cqi/models/attributes.js
index 8a0b987c21e10426837afb61b7dd57bfab1a30f9..3347146b0565660279d697c52f7742d48c80beef 100644
--- a/app/static/js/cqi/models/attributes.js
+++ b/app/static/js/cqi/models/attributes.js
@@ -37,7 +37,7 @@ cqi.models.attributes.AttributeCollection = class AttributeCollection extends cq
   static model = cqi.models.attributes.Attribute;
 
   /**
-   * @param {cqi.CQiClient} client
+   * @param {cqi.Client} client
    * @param {cqi.models.corpora.Corpus} corpus
    */
   constructor(client, corpus) {
diff --git a/app/static/js/app/app.js b/app/static/js/nopaque/app.js
similarity index 96%
rename from app/static/js/app/app.js
rename to app/static/js/nopaque/app.js
index fefabd1a80cd076820e760a509527cbf8a51d676..c4e837c4a8b7680fef535b796d67dd7fe2761e90 100644
--- a/app/static/js/app/app.js
+++ b/app/static/js/nopaque/app.js
@@ -1,9 +1,4 @@
-// IDEA: Split the App logic into seperate units
-//       - App.Data
-//       - App.IO (name is WIP)
-//       - App.UI
-
-App.App = class App {
+nopaque.App = class App {
   constructor() {
     this.data = {
       promises: {getUser: {}, subscribeUser: {}},
@@ -139,9 +134,9 @@ App.App = class App {
       }
       optgroupElement.remove();
     }
-
     // #endregion
 
+
     /* Initialize Materialize Components */
     // #region
   
@@ -190,10 +185,12 @@ App.App = class App {
     );
     // #endregion
 
-    // #region Nopaque Components
+
+    /* Initialize nopaque Components */
+    // #region 
     ResourceDisplays.AutoInit();
     ResourceLists.AutoInit();
     Forms.AutoInit();
-    // #endregion Nopaque Components
+    // #endregion
   }
 };
diff --git a/app/static/js/nopaque/index.js b/app/static/js/nopaque/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..0d7bc55f16a87de3d7ef8d3a219e49fccba765d8
--- /dev/null
+++ b/app/static/js/nopaque/index.js
@@ -0,0 +1 @@
+var nopaque = {};
diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2
index a1897b5672d5fa1583f6c804aed839580210e233..9683485dca1eb054085edb242af4b475a0e534b1 100644
--- a/app/templates/_scripts.html.j2
+++ b/app/templates/_scripts.html.j2
@@ -7,8 +7,8 @@
 {%- assets
   filters='rjsmin',
   output='gen/app.%(version)s.js',
-  'js/app/index.js',
-  'js/app/app.js'
+  'js/nopaque/index.js',
+  'js/nopaque/app.js'
 %}
 <script src="{{ ASSET_URL }}"></script>
 {%- endassets %}
@@ -118,7 +118,7 @@
 
 <script>
   // TODO: Implement an app.run method and use this for all of the following
-  const app = new App.App();
+  const app = new nopaque.App();
   app.init();
 
   // Check if the current user is authenticated
diff --git a/app/templates/corpora/corpus.html.j2 b/app/templates/corpora/corpus.html.j2
index 0a00fbeef106d650b20fe387944bd3de02e21ff4..978b87bb7678722ebe47177640895859de9fe5a7 100644
--- a/app/templates/corpora/corpus.html.j2
+++ b/app/templates/corpora/corpus.html.j2
@@ -281,7 +281,6 @@ let users = {
     {% if not loop.last %},{% endif %}
   {% endfor %}
 };
-console.log(users);
 
 let inviteUserModalSearch = M.Chips.init(
   inviteUserModalSearchElement,