diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js
index 2bdfac58a8619a20e4d796ae7324dfde983690ec..f364d816cf22d20bf28e8e748da8747bf79f375b 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js
@@ -30,7 +30,7 @@ class CorpusAnalysisApp {
       // 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.Client('/cqi_over_sio');
+      const cqiClient = new nopaque.corpus_analysis.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/CorpusAnalysisConcordance.js b/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
index 2263fbde0f9cbe7cfea779a8c127821caeb29d18..fd32c49c9f1a43d554aca259a0cd01f3dc7af33c 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
@@ -33,7 +33,7 @@ class CorpusAnalysisConcordance {
 
   async submitForm(queryModeId) {
     this.app.disableActionElements();
-    let queryBuilderQuery = Utils.unescape(document.querySelector('#corpus-analysis-concordance-query-preview').innerHTML.trim());
+    let queryBuilderQuery = nopaque.Utils.unescape(document.querySelector('#corpus-analysis-concordance-query-preview').innerHTML.trim());
     let expertModeQuery = this.elements.expertModeForm.query.value.trim();
     let query = queryModeId === 'corpus-analysis-concordance-expert-mode-form' ? expertModeQuery : queryBuilderQuery;
     let form = queryModeId === 'corpus-analysis-concordance-expert-mode-form' ? this.elements.expertModeForm : this.elements.queryBuilderForm;
@@ -171,11 +171,11 @@ class CorpusAnalysisConcordance {
     this.elements.subcorpusActions.querySelector('.subcorpus-export-trigger').addEventListener('click', (event) => {
       event.preventDefault();
       let subcorpus = this.data.subcorpora[this.settings.selectedSubcorpus];
-      let modalElementId = Utils.generateElementId('export-subcorpus-modal-');
-      let exportFormatSelectElementId = Utils.generateElementId('export-format-select-');
-      let exportSelectedMatchesOnlyCheckboxElementId = Utils.generateElementId('export-selected-matches-only-checkbox-');
-      let exportFileNameInputElementId = Utils.generateElementId('export-file-name-input-');
-      let modalElement = Utils.HTMLToElement(
+      let modalElementId = nopaque.Utils.generateElementId('export-subcorpus-modal-');
+      let exportFormatSelectElementId = nopaque.Utils.generateElementId('export-format-select-');
+      let exportSelectedMatchesOnlyCheckboxElementId = nopaque.Utils.generateElementId('export-selected-matches-only-checkbox-');
+      let exportFileNameInputElementId = nopaque.Utils.generateElementId('export-file-name-input-');
+      let modalElement = nopaque.Utils.HTMLToElement(
         `
           <div class="modal" id="${modalElementId}">
             <div class="modal-content">
diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisReader.js b/app/static/js/CorpusAnalysis/CorpusAnalysisReader.js
index 2a231ce214c46fb6a9724e25efcd7d678af61ee6..bbafbc277eb9adc96a7bb491ceba714b7c3cd2a7 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisReader.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisReader.js
@@ -112,7 +112,7 @@ class CorpusAnalysisReader {
     if (this.data.corpus.p.pages === 0) {return;}
     let pageElement;
     // First page button. Disables first page button if on first page
-    pageElement = Utils.HTMLToElement(
+    pageElement = nopaque.Utils.HTMLToElement(
       `
         <li class="${this.data.corpus.p.page === 1 ? 'disabled' : 'waves-effect'}">
           <a class="corpus-analysis-action pagination-trigger" ${this.data.corpus.p.page === 1 ? '' : 'data-target="1"'}>
@@ -123,7 +123,7 @@ class CorpusAnalysisReader {
     );
     this.elements.corpusPagination.appendChild(pageElement);
     // Previous page button. Disables previous page button if on first page
-    pageElement = Utils.HTMLToElement(
+    pageElement = nopaque.Utils.HTMLToElement(
       `
         <li class="${this.data.corpus.p.has_prev ? 'waves-effect' : 'disabled'}">
           <a class="corpus-analysis-action pagination-trigger" ${this.data.corpus.p.has_prev ? 'data-target="' + this.data.corpus.p.prev_num + '"' : ''}>
@@ -135,7 +135,7 @@ class CorpusAnalysisReader {
     this.elements.corpusPagination.appendChild(pageElement);
     // First page as number. Hides first page button if on first page
     if (this.data.corpus.p.page > 6) {
-      pageElement = Utils.HTMLToElement(
+      pageElement = nopaque.Utils.HTMLToElement(
         `
           <li class="waves-effect">
             <a class="corpus-analysis-action pagination-trigger" data-target="1">1</a>
@@ -143,14 +143,14 @@ class CorpusAnalysisReader {
         `
       );
       this.elements.corpusPagination.appendChild(pageElement);
-      pageElement = Utils.HTMLToElement("<li style='margin-top: 5px;'>&hellip;</li>");
+      pageElement = nopaque.Utils.HTMLToElement("<li style='margin-top: 5px;'>&hellip;</li>");
       this.elements.corpusPagination.appendChild(pageElement);
     }
 
     // render page buttons (5 before and 5 after current page)
     for (let i = this.data.corpus.p.page - this.settings.pagination.innerWindow; i <= this.data.corpus.p.page; i++) {
       if (i <= 0) {continue;}
-      pageElement = Utils.HTMLToElement(
+      pageElement = nopaque.Utils.HTMLToElement(
         `
           <li class="${i === this.data.corpus.p.page ? 'active' : 'waves-effect'}">
           <a class="corpus-analysis-action pagination-trigger" ${i === this.data.corpus.p.page ? '' : 'data-target="' + i + '"'}>${i}</a>
@@ -161,7 +161,7 @@ class CorpusAnalysisReader {
     };
     for (let i = this.data.corpus.p.page +1; i <= this.data.corpus.p.page + this.settings.pagination.innerWindow; i++) {
       if (i > this.data.corpus.p.pages) {break;}
-      pageElement = Utils.HTMLToElement(
+      pageElement = nopaque.Utils.HTMLToElement(
         `
           <li class="${i === this.data.corpus.p.page ? 'active' : 'waves-effect'}">
           <a class="corpus-analysis-action pagination-trigger" ${i === this.data.corpus.p.page ? '' : 'data-target="' + i + '"'}>${i}</a>
@@ -172,9 +172,9 @@ class CorpusAnalysisReader {
     };
     // Last page as number. Hides last page button if on last page
     if (this.data.corpus.p.page < this.data.corpus.p.pages - 6) {
-      pageElement = Utils.HTMLToElement("<li style='margin-top: 5px;'>&hellip;</li>");
+      pageElement = nopaque.Utils.HTMLToElement("<li style='margin-top: 5px;'>&hellip;</li>");
       this.elements.corpusPagination.appendChild(pageElement);
-      pageElement = Utils.HTMLToElement(
+      pageElement = nopaque.Utils.HTMLToElement(
         `
           <li class="waves-effect">
             <a class="corpus-analysis-action pagination-trigger" data-target="${this.data.corpus.p.pages}">${this.data.corpus.p.pages}</a>
@@ -184,7 +184,7 @@ class CorpusAnalysisReader {
       this.elements.corpusPagination.appendChild(pageElement);
     }
     // Next page button. Disables next page button if on last page
-    pageElement = Utils.HTMLToElement(
+    pageElement = nopaque.Utils.HTMLToElement(
       `
         <li class="${this.data.corpus.p.has_next ? 'waves-effect' : 'disabled'}">
           <a class="corpus-analysis-action pagination-trigger" ${this.data.corpus.p.has_next ? 'data-target="' + this.data.corpus.p.next_num + '"' : ''}>
@@ -195,7 +195,7 @@ class CorpusAnalysisReader {
     );
     this.elements.corpusPagination.appendChild(pageElement);
     // Last page button. Disables last page button if on last page
-    pageElement = Utils.HTMLToElement(
+    pageElement = nopaque.Utils.HTMLToElement(
       `
         <li class="${this.data.corpus.p.page === this.data.corpus.p.pages ? 'disabled' : 'waves-effect'}">
           <a class="corpus-analysis-action pagination-trigger" ${this.data.corpus.p.page === this.data.corpus.p.pages ? '' : 'data-target="' + this.data.corpus.p.pages + '"'}>
diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js b/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js
index 4d51b01431cfe5af046ef2b12cc1359cc164c902..3865512cd25d94fb460b57a7bb608fa088cb479f 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js
@@ -75,7 +75,7 @@ class CorpusAnalysisStaticVisualization {
 
   getStopwords() {
     this.data.promises.getStopwords = new Promise((resolve, reject) => {
-      Requests.corpora.entity.getStopwords()
+      nopaque.requests.corpora.entity.getStopwords()
         .then((response) => {
           response.json()
             .then((json) => {
@@ -104,7 +104,7 @@ class CorpusAnalysisStaticVisualization {
   renderTextInfoList() {
     let corpusData = this.data.corpus.o.staticData;
     let corpusTextInfoListElement = document.querySelector('.corpus-text-info-list');
-    let corpusTextInfoList = new ResourceLists.CorpusTextInfoList(corpusTextInfoListElement);
+    let corpusTextInfoList = new nopaque.resource_lists.CorpusTextInfoList(corpusTextInfoListElement);
     let texts = corpusData.s_attrs.text.lexicon;
     let textData = [];
     for (let i = 0; i < Object.entries(texts).length; i++) {
@@ -213,7 +213,7 @@ class CorpusAnalysisStaticVisualization {
 
   async renderTokenList() {
     let corpusTokenListElement = document.querySelector('.corpus-token-list');
-    let corpusTokenList = new ResourceLists.CorpusTokenList(corpusTokenListElement);
+    let corpusTokenList = new nopaque.resource_lists.CorpusTokenList(corpusTokenListElement);
     let filteredData = this.filterData();
     let stopwords = this.data.stopwords;
     if (this.data.stopwords === undefined) {
@@ -358,7 +358,7 @@ class CorpusAnalysisStaticVisualization {
     if (stopwordLanguageSelection.children.length === 0) {
       Object.keys(stopwords).forEach(language => {
         if (language !== 'user_stopwords') {
-          let optionElement = Utils.HTMLToElement(`<option value="${language}" ${language === 'english' ? 'selected' : ''}>${language}</option>`);
+          let optionElement = nopaque.Utils.HTMLToElement(`<option value="${language}" ${language === 'english' ? 'selected' : ''}>${language}</option>`);
           stopwordLanguageSelection.appendChild(optionElement);
         }
       });
@@ -367,7 +367,7 @@ class CorpusAnalysisStaticVisualization {
     // Render user stopwords over input field.
     if (this.data.stopwords['user_stopwords'].length > 0) {
       for (let word of this.data.stopwords['user_stopwords']) {
-        let chipElement = Utils.HTMLToElement(`<div class="chip">${word}<i class="close material-icons">close</i></div>`);
+        let chipElement = nopaque.Utils.HTMLToElement(`<div class="chip">${word}<i class="close material-icons">close</i></div>`);
         chipElement.addEventListener('click', (event) => {
           let removedListItem = event.target.closest('.chip').firstChild.textContent;
           this.data.stopwords['user_stopwords'] = structuredClone(this.data.stopwords['user_stopwords'].filter(item => item !== removedListItem));
@@ -433,7 +433,7 @@ class CorpusAnalysisStaticVisualization {
     let stopwordLanguageChipList = document.querySelector('#stopword-language-chip-list');
     stopwordLanguageChipList.innerHTML = '';
     for (let word of stopwords) {
-      let chipElement = Utils.HTMLToElement(`<div class="chip">${word}<i class="close material-icons">close</i></div>`);
+      let chipElement = nopaque.Utils.HTMLToElement(`<div class="chip">${word}<i class="close material-icons">close</i></div>`);
       chipElement.addEventListener('click', (event) => {
         let removedListItem = event.target.closest('.chip').firstChild.textContent;
         this.data.stopwords[language] = structuredClone(this.data.stopwords[language].filter(item => item !== removedListItem));
diff --git a/app/static/js/CorpusAnalysis/Utils.js b/app/static/js/CorpusAnalysis/Utils.js
deleted file mode 100644
index 1ffe1dc027e37066b6b13914b8e050a9c2abd19e..0000000000000000000000000000000000000000
--- a/app/static/js/CorpusAnalysis/Utils.js
+++ /dev/null
@@ -1,53 +0,0 @@
-  /**
-   * @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/cqi/api/client.js b/app/static/js/CorpusAnalysis/cqi/api/client.js
similarity index 91%
rename from app/static/js/cqi/api/client.js
rename to app/static/js/CorpusAnalysis/cqi/api/client.js
index 64495873be24142db2d82b114e8a95df645d5fa4..4603a1f35cfbe03256daae26f17a45f3faeae8d2 100644
--- a/app/static/js/cqi/api/client.js
+++ b/app/static/js/CorpusAnalysis/cqi/api/client.js
@@ -1,4 +1,4 @@
-cqi.api.Client = class Client {
+nopaque.corpus_analysis.cqi.api.Client = class Client {
   /**
    * @param {string} host
    * @param {number} [timeout=60] timeout
@@ -30,10 +30,10 @@ cqi.api.Client = class Client {
     } else if (response.code === 500) {
       throw new Error(`[${response.code}] ${response.msg}`);
     } else if (response.code === 502) {
-      if (response.payload.code in cqi.errors.lookup) {
-        throw new cqi.errors.lookup[response.payload.code]();
+      if (response.payload.code in nopaque.corpus_analysis.cqi.errors.lookup) {
+        throw new nopaque.corpus_analysis.cqi.errors.lookup[response.payload.code]();
       } else {
-        throw new cqi.errors.CQiError();
+        throw new nopaque.corpus_analysis.cqi.errors.CQiError();
       }
     }
   }
@@ -41,22 +41,22 @@ cqi.api.Client = class Client {
   /**
    * @param {string} username
    * @param {string} password
-   * @returns {Promise<cqi.status.StatusConnectOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusConnectOk>}
    */
   async ctrl_connect(username, password) {
     const fn_name = 'ctrl_connect';
     const fn_args = {username: username, password: password};
     let payload = await this.#request(fn_name, fn_args);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
-   * @returns {Promise<cqi.status.StatusByeOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusByeOk>}
    */
   async ctrl_bye() {
     const fn_name = 'ctrl_bye';
     let payload = await this.#request(fn_name);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
@@ -68,12 +68,12 @@ cqi.api.Client = class Client {
   }
 
   /**
-   * @returns {Promise<cqi.status.StatusPingOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusPingOk>}
    */
   async ctrl_ping() {
     const fn_name = 'ctrl_ping';
     let payload = await this.#request(fn_name);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
@@ -208,13 +208,13 @@ cqi.api.Client = class Client {
    * try to unload a corpus and all its attributes from memory
    * 
    * @param {string} corpus
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async corpus_drop_corpus(corpus) {
     const fn_name = 'corpus_drop_corpus';
     const fn_args = {corpus: corpus};
     let payload = await this.#request(fn_name, fn_args);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
@@ -250,13 +250,13 @@ cqi.api.Client = class Client {
    * unload attribute from memory
    * 
    * @param {string} attribute
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async cl_drop_attribute(attribute) {
     const fn_name = 'cl_drop_attribute';
     const fn_args = {attribute: attribute};
     let payload = await this.#request(fn_name, fn_args);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
@@ -482,13 +482,13 @@ cqi.api.Client = class Client {
    * @param {string} mother_corpus
    * @param {string} subcorpus_name
    * @param {string} query
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async cqp_query(mother_corpus, subcorpus_name, query) {
     const fn_name = 'cqp_query';
     const fn_args = {mother_corpus: mother_corpus, subcorpus_name: subcorpus_name, query: query};
     let payload = await this.#request(fn_name, fn_args);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
@@ -524,7 +524,7 @@ cqi.api.Client = class Client {
 
   /**
    * Dump the values of <field> for match ranges <first> .. <last>
-   * in <subcorpus>. <field> is one of the cqi.constants.FIELD_* constants.
+   * in <subcorpus>. <field> is one of the nopaque.corpus_analysis.cqi.constants.FIELD_* constants.
    * 
    * @param {string} subcorpus
    * @param {number} field
@@ -542,13 +542,13 @@ cqi.api.Client = class Client {
    * delete a subcorpus from memory
    * 
    * @param {string} subcorpus
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async cqp_drop_subcorpus(subcorpus) {
     const fn_name = 'cqp_drop_subcorpus';
     const fn_args = {subcorpus: subcorpus};
     let payload = await this.#request(fn_name, fn_args);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
@@ -561,9 +561,9 @@ cqi.api.Client = class Client {
    *
    * returns <n> (id, frequency) pairs flattened into a list of size 2*<n>
    * field is one of
-   * - cqi.constants.FIELD_MATCH
-   * - cqi.constants.FIELD_TARGET
-   * - cqi.constants.FIELD_KEYWORD
+   * - nopaque.corpus_analysis.cqi.constants.FIELD_MATCH
+   * - nopaque.corpus_analysis.cqi.constants.FIELD_TARGET
+   * - nopaque.corpus_analysis.cqi.constants.FIELD_KEYWORD
    *
    * NB: pairs are sorted by frequency desc.
    * 
@@ -610,13 +610,13 @@ cqi.api.Client = class Client {
 
   /**
    * @param {string} corpus
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async ext_corpus_update_db(corpus) {
     const fn_name = 'ext_corpus_update_db';
     const fn_args = {corpus: corpus};
     let payload = await this.#request(fn_name, fn_args);
-    return new cqi.status.lookup[payload.code]();
+    return new nopaque.corpus_analysis.cqi.status.lookup[payload.code]();
   }
 
   /**
diff --git a/app/static/js/CorpusAnalysis/cqi/api/index.js b/app/static/js/CorpusAnalysis/cqi/api/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..98093ade4f5cb50495be1abe79343d004c1602ef
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/cqi/api/index.js
@@ -0,0 +1 @@
+nopaque.corpus_analysis.cqi.api = {};
diff --git a/app/static/js/cqi/client.js b/app/static/js/CorpusAnalysis/cqi/client.js
similarity index 54%
rename from app/static/js/cqi/client.js
rename to app/static/js/CorpusAnalysis/cqi/client.js
index dab97828a79e357d38361f8097758e83f9f274b7..2b983e7b6747673a895d588970764aa6be2fa78c 100644
--- a/app/static/js/cqi/client.js
+++ b/app/static/js/CorpusAnalysis/cqi/client.js
@@ -1,23 +1,23 @@
-cqi.Client = class Client {
+nopaque.corpus_analysis.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.Client} */
-    this.api = new cqi.api.Client(host, timeout, version);
+     /** @type {nopaque.corpus_analysis.cqi.api.Client} */
+    this.api = new nopaque.corpus_analysis.cqi.api.Client(host, timeout, version);
   }
 
   /**
-   * @returns {cqi.models.corpora.CorpusCollection}
+   * @returns {nopaque.corpus_analysis.cqi.models.corpora.CorpusCollection}
    */
   get corpora() {
-    return new cqi.models.corpora.CorpusCollection(this);
+    return new nopaque.corpus_analysis.cqi.models.corpora.CorpusCollection(this);
   }
 
   /**
-   * @returns {Promise<cqi.status.StatusByeOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusByeOk>}
    */
   async bye() {
     return await this.api.ctrl_bye();
@@ -26,14 +26,14 @@ cqi.Client = class Client {
   /**
    * @param {string} username
    * @param {string} password
-   * @returns {Promise<cqi.status.StatusConnectOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusConnectOk>}
    */
   async connect(username, password) {
     return await this.api.ctrl_connect(username, password);
   }
 
   /**
-   * @returns {Promise<cqi.status.StatusPingOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusPingOk>}
    */
   async ping() {
     return await this.api.ctrl_ping();
@@ -49,7 +49,7 @@ cqi.Client = class Client {
   /**
    * Alias for "bye" method
    * 
-   * @returns {Promise<cqi.status.StatusByeOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusByeOk>}
    */
   async disconnect() {
     return await this.api.ctrl_bye();
diff --git a/app/static/js/CorpusAnalysis/cqi/constants.js b/app/static/js/CorpusAnalysis/cqi/constants.js
new file mode 100644
index 0000000000000000000000000000000000000000..e45f761b7bec0e0fe12a92818090699759d4c8d6
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/cqi/constants.js
@@ -0,0 +1,43 @@
+nopaque.corpus_analysis.cqi.constants = {};
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_KEYWORD = 9;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_MATCH = 16;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_MATCHEND = 17;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET = 0;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_0 = 0;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_1 = 1;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_2 = 2;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_3 = 3;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_4 = 4;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_5 = 5;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_6 = 6;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_7 = 7;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_8 = 8;
+
+/** @type {number} */
+nopaque.corpus_analysis.cqi.constants.FIELD_TARGET_9 = 9;
diff --git a/app/static/js/CorpusAnalysis/cqi/errors.js b/app/static/js/CorpusAnalysis/cqi/errors.js
new file mode 100644
index 0000000000000000000000000000000000000000..216294ce3d74dab0a82b166ea557baa4996d5a49
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/cqi/errors.js
@@ -0,0 +1,185 @@
+nopaque.corpus_analysis.cqi.errors = {};
+
+
+/**
+ * A base class from which all other errors inherit.
+ * If you want to catch all errors that the CQi package might throw,
+ * catch this base error.
+ */
+nopaque.corpus_analysis.cqi.errors.CQiError = class CQiError extends Error {
+  constructor(message) {
+    super(message);
+    this.code = undefined;
+    this.description = undefined;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.Error = class Error extends nopaque.corpus_analysis.cqi.errors.CQiError {
+  constructor(message) {
+    super(message);
+    this.code = 2;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.ErrorGeneralError = class ErrorGeneralError extends nopaque.corpus_analysis.cqi.errors.Error {
+  constructor(message) {
+    super(message);
+    this.code = 513;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.ErrorConnectRefused = class ErrorConnectRefused extends nopaque.corpus_analysis.cqi.errors.Error {
+  constructor(message) {
+    super(message);
+    this.code = 514;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.ErrorUserAbort = class ErrorUserAbort extends nopaque.corpus_analysis.cqi.errors.Error {
+  constructor(message) {
+    super(message);
+    this.code = 515;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.ErrorSyntaxError = class ErrorSyntaxError extends nopaque.corpus_analysis.cqi.errors.Error {
+  constructor(message) {
+    super(message);
+    this.code = 516;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLError = class Error extends nopaque.corpus_analysis.cqi.errors.CQiError {
+  constructor(message) {
+    super(message);
+    this.code = 4;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLErrorNoSuchAttribute = class CLErrorNoSuchAttribute extends nopaque.corpus_analysis.cqi.errors.CLError {
+  constructor(message) {
+    super(message);
+    this.code = 1025;
+    this.description = "CQi server couldn't open attribute";
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLErrorWrongAttributeType = class CLErrorWrongAttributeType extends nopaque.corpus_analysis.cqi.errors.CLError {
+  constructor(message) {
+    super(message);
+    this.code = 1026;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLErrorOutOfRange = class CLErrorOutOfRange extends nopaque.corpus_analysis.cqi.errors.CLError {
+  constructor(message) {
+    super(message);
+    this.code = 1027;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLErrorRegex = class CLErrorRegex extends nopaque.corpus_analysis.cqi.errors.CLError {
+  constructor(message) {
+    super(message);
+    this.code = 1028;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLErrorCorpusAccess = class CLErrorCorpusAccess extends nopaque.corpus_analysis.cqi.errors.CLError {
+  constructor(message) {
+    super(message);
+    this.code = 1029;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLErrorOutOfMemory = class CLErrorOutOfMemory extends nopaque.corpus_analysis.cqi.errors.CLError {
+  constructor(message) {
+    super(message);
+    this.code = 1030;
+    this.description = 'CQi server has run out of memory; try discarding some other corpora and/or subcorpora';
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CLErrorInternal = class CLErrorInternal extends nopaque.corpus_analysis.cqi.errors.CLError {
+  constructor(message) {
+    super(message);
+    this.code = 1031;
+    this.description = "The classical 'please contact technical support' error";
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CQPError = class Error extends nopaque.corpus_analysis.cqi.errors.CQiError {
+  constructor(message) {
+    super(message);
+    this.code = 5;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CQPErrorGeneral = class CQPErrorGeneral extends nopaque.corpus_analysis.cqi.errors.CQPError {
+  constructor(message) {
+    super(message);
+    this.code = 1281;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CQPErrorNoSuchCorpus = class CQPErrorNoSuchCorpus extends nopaque.corpus_analysis.cqi.errors.CQPError {
+  constructor(message) {
+    super(message);
+    this.code = 1282;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CQPErrorInvalidField = class CQPErrorInvalidField extends nopaque.corpus_analysis.cqi.errors.CQPError {
+  constructor(message) {
+    super(message);
+    this.code = 1283;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.CQPErrorOutOfRange = class CQPErrorOutOfRange extends nopaque.corpus_analysis.cqi.errors.CQPError {
+  constructor(message) {
+    super(message);
+    this.code = 1284;
+    this.description = 'A number is out of range';
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.errors.lookup = {
+  2: nopaque.corpus_analysis.cqi.errors.Error,
+  513: nopaque.corpus_analysis.cqi.errors.ErrorGeneralError,
+  514: nopaque.corpus_analysis.cqi.errors.ErrorConnectRefused,
+  515: nopaque.corpus_analysis.cqi.errors.ErrorUserAbort,
+  516: nopaque.corpus_analysis.cqi.errors.ErrorSyntaxError,
+  4: nopaque.corpus_analysis.cqi.errors.CLError,
+  1025: nopaque.corpus_analysis.cqi.errors.CLErrorNoSuchAttribute,
+  1026: nopaque.corpus_analysis.cqi.errors.CLErrorWrongAttributeType,
+  1027: nopaque.corpus_analysis.cqi.errors.CLErrorOutOfRange,
+  1028: nopaque.corpus_analysis.cqi.errors.CLErrorRegex,
+  1029: nopaque.corpus_analysis.cqi.errors.CLErrorCorpusAccess,
+  1030: nopaque.corpus_analysis.cqi.errors.CLErrorOutOfMemory,
+  1031: nopaque.corpus_analysis.cqi.errors.CLErrorInternal,
+  5: nopaque.corpus_analysis.cqi.errors.CQPError,
+  1281: nopaque.corpus_analysis.cqi.errors.CQPErrorGeneral,
+  1282: nopaque.corpus_analysis.cqi.errors.CQPErrorNoSuchCorpus,
+  1283: nopaque.corpus_analysis.cqi.errors.CQPErrorInvalidField,
+  1284: nopaque.corpus_analysis.cqi.errors.CQPErrorOutOfRange
+};
diff --git a/app/static/js/CorpusAnalysis/cqi/index.js b/app/static/js/CorpusAnalysis/cqi/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..379c58971ded7f50279234400e1004be22c618ca
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/cqi/index.js
@@ -0,0 +1 @@
+nopaque.corpus_analysis.cqi = {};
diff --git a/app/static/js/cqi/models/attributes.js b/app/static/js/CorpusAnalysis/cqi/models/attributes.js
similarity index 67%
rename from app/static/js/cqi/models/attributes.js
rename to app/static/js/CorpusAnalysis/cqi/models/attributes.js
index 3347146b0565660279d697c52f7742d48c80beef..a5764c3ed58db7710951f35e259aca38a3001af5 100644
--- a/app/static/js/cqi/models/attributes.js
+++ b/app/static/js/CorpusAnalysis/cqi/models/attributes.js
@@ -1,7 +1,7 @@
-cqi.models.attributes = {};
+nopaque.corpus_analysis.cqi.models.attributes = {};
 
 
-cqi.models.attributes.Attribute = class Attribute extends cqi.models.resource.Model {
+nopaque.corpus_analysis.cqi.models.attributes.Attribute = class Attribute extends nopaque.corpus_analysis.cqi.models.resource.Model {
   /**
    * @returns {string}
    */
@@ -24,7 +24,7 @@ cqi.models.attributes.Attribute = class Attribute extends cqi.models.resource.Mo
   }
 
   /**
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async drop() {
     return await this.client.api.cl_drop_attribute(this.apiName);
@@ -32,17 +32,17 @@ cqi.models.attributes.Attribute = class Attribute extends cqi.models.resource.Mo
 };
 
 
-cqi.models.attributes.AttributeCollection = class AttributeCollection extends cqi.models.resource.Collection {
-   /** @type{typeof cqi.models.attributes.Attribute} */
-  static model = cqi.models.attributes.Attribute;
+nopaque.corpus_analysis.cqi.models.attributes.AttributeCollection = class AttributeCollection extends nopaque.corpus_analysis.cqi.models.resource.Collection {
+   /** @type{typeof nopaque.corpus_analysis.cqi.models.attributes.Attribute} */
+  static model = nopaque.corpus_analysis.cqi.models.attributes.Attribute;
 
   /**
-   * @param {cqi.Client} client
-   * @param {cqi.models.corpora.Corpus} corpus
+   * @param {nopaque.corpus_analysis.cqi.Client} client
+   * @param {nopaque.corpus_analysis.cqi.models.corpora.Corpus} corpus
    */
   constructor(client, corpus) {
     super(client);
-     /** @type {cqi.models.corpora.Corpus} */
+     /** @type {nopaque.corpus_analysis.cqi.models.corpora.Corpus} */
     this.corpus = corpus;
   }
 
@@ -62,7 +62,7 @@ cqi.models.attributes.AttributeCollection = class AttributeCollection extends cq
 
   /**
    * @param {string} attributeName
-   * @returns {Promise<cqi.models.attributes.Attribute>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.attributes.Attribute>}
    */
   async get(attributeName) {
     return this.prepareModel(await this._get(attributeName));
@@ -70,7 +70,7 @@ cqi.models.attributes.AttributeCollection = class AttributeCollection extends cq
 };
 
 
-cqi.models.attributes.AlignmentAttribute = class AlignmentAttribute extends cqi.models.attributes.Attribute {
+nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttribute = class AlignmentAttribute extends nopaque.corpus_analysis.cqi.models.attributes.Attribute {
   /**
    * @param {number} id 
    * @returns {Promise<[number, number, number, number]>}
@@ -89,17 +89,17 @@ cqi.models.attributes.AlignmentAttribute = class AlignmentAttribute extends cqi.
 };
 
 
-cqi.models.attributes.AlignmentAttributeCollection = class AlignmentAttributeCollection extends cqi.models.attributes.AttributeCollection {
-   /** @type{typeof cqi.models.attributes.AlignmentAttribute} */
-  static model = cqi.models.attributes.AlignmentAttribute;
+nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttributeCollection = class AlignmentAttributeCollection extends nopaque.corpus_analysis.cqi.models.attributes.AttributeCollection {
+   /** @type{typeof nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttribute} */
+  static model = nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttribute;
 
   /**
-   * @returns {Promise<cqi.models.attributes.AlignmentAttribute[]>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttribute[]>}
    */
   async list() {
      /** @type {string[]} */
      let alignmentAttributeNames = await this.client.api.corpus_alignment_attributes(this.corpus.apiName);
-     /** @type {cqi.models.attributes.AlignmentAttribute[]} */
+     /** @type {nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttribute[]} */
     let alignmentAttributes = [];
     for (let alignmentAttributeName of alignmentAttributeNames) {
       alignmentAttributes.push(await this.get(alignmentAttributeName));
@@ -109,7 +109,7 @@ cqi.models.attributes.AlignmentAttributeCollection = class AlignmentAttributeCol
 };
 
 
-cqi.models.attributes.PositionalAttribute = class PositionalAttribute extends cqi.models.attributes.Attribute {
+nopaque.corpus_analysis.cqi.models.attributes.PositionalAttribute = class PositionalAttribute extends nopaque.corpus_analysis.cqi.models.attributes.Attribute {
   /**
    * @returns {number}
    */
@@ -183,9 +183,9 @@ cqi.models.attributes.PositionalAttribute = class PositionalAttribute extends cq
 };
 
 
-cqi.models.attributes.PositionalAttributeCollection = class PositionalAttributeCollection extends cqi.models.attributes.AttributeCollection {
-   /** @type{typeof cqi.models.attributes.PositionalAttribute} */
-  static model = cqi.models.attributes.PositionalAttribute;
+nopaque.corpus_analysis.cqi.models.attributes.PositionalAttributeCollection = class PositionalAttributeCollection extends nopaque.corpus_analysis.cqi.models.attributes.AttributeCollection {
+   /** @type{typeof nopaque.corpus_analysis.cqi.models.attributes.PositionalAttribute} */
+  static model = nopaque.corpus_analysis.cqi.models.attributes.PositionalAttribute;
 
   /**
    * @param {string} positionalAttributeName
@@ -198,7 +198,7 @@ cqi.models.attributes.PositionalAttributeCollection = class PositionalAttributeC
   }
 
   /**
-   * @returns {Promise<cqi.models.attributes.PositionalAttribute[]>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.attributes.PositionalAttribute[]>}
    */
   async list() {
     let positionalAttributeNames = await this.client.api.corpus_positional_attributes(this.corpus.apiName);
@@ -211,7 +211,7 @@ cqi.models.attributes.PositionalAttributeCollection = class PositionalAttributeC
 };
 
 
-cqi.models.attributes.StructuralAttribute = class StructuralAttribute extends cqi.models.attributes.Attribute {
+nopaque.corpus_analysis.cqi.models.attributes.StructuralAttribute = class StructuralAttribute extends nopaque.corpus_analysis.cqi.models.attributes.Attribute {
   /**
    * @returns {boolean}
    */
@@ -261,9 +261,9 @@ cqi.models.attributes.StructuralAttribute = class StructuralAttribute extends cq
 };
 
 
-cqi.models.attributes.StructuralAttributeCollection = class StructuralAttributeCollection extends cqi.models.attributes.AttributeCollection {
-   /** @type{typeof cqi.models.attributes.StructuralAttribute} */
-  static model = cqi.models.attributes.StructuralAttribute;
+nopaque.corpus_analysis.cqi.models.attributes.StructuralAttributeCollection = class StructuralAttributeCollection extends nopaque.corpus_analysis.cqi.models.attributes.AttributeCollection {
+   /** @type{typeof nopaque.corpus_analysis.cqi.models.attributes.StructuralAttribute} */
+  static model = nopaque.corpus_analysis.cqi.models.attributes.StructuralAttribute;
 
   /**
    * @param {string} structuralAttributeName
@@ -276,7 +276,7 @@ cqi.models.attributes.StructuralAttributeCollection = class StructuralAttributeC
   }
 
   /**
-   * @returns {Promise<cqi.models.attributes.StructuralAttribute[]>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.attributes.StructuralAttribute[]>}
    */
   async list() {
     let structuralAttributeNames = await this.client.api.corpus_structural_attributes(this.corpus.apiName);
diff --git a/app/static/js/cqi/models/corpora.js b/app/static/js/CorpusAnalysis/cqi/models/corpora.js
similarity index 66%
rename from app/static/js/cqi/models/corpora.js
rename to app/static/js/CorpusAnalysis/cqi/models/corpora.js
index 8128c47f024806cf59f60359ac78d34d922acc12..080f29a9da59d3270ea93864859bebca862dfa3d 100644
--- a/app/static/js/cqi/models/corpora.js
+++ b/app/static/js/CorpusAnalysis/cqi/models/corpora.js
@@ -1,7 +1,7 @@
-cqi.models.corpora = {};
+nopaque.corpus_analysis.cqi.models.corpora = {};
 
 
-cqi.models.corpora.Corpus = class Corpus extends cqi.models.resource.Model {
+nopaque.corpus_analysis.cqi.models.corpora.Corpus = class Corpus extends nopaque.corpus_analysis.cqi.models.resource.Model {
   /**
    * @returns {string}
    */
@@ -38,35 +38,35 @@ cqi.models.corpora.Corpus = class Corpus extends cqi.models.resource.Model {
   }
 
   /**
-   * @returns {cqi.models.attributes.AlignmentAttributeCollection}
+   * @returns {nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttributeCollection}
    */
   get alignmentAttributes() {
-    return new cqi.models.attributes.AlignmentAttributeCollection(this.client, this);
+    return new nopaque.corpus_analysis.cqi.models.attributes.AlignmentAttributeCollection(this.client, this);
   }
 
   /**
-   * @returns {cqi.models.attributes.PositionalAttributeCollection}
+   * @returns {nopaque.corpus_analysis.cqi.models.attributes.PositionalAttributeCollection}
    */
   get positionalAttributes() {
-    return new cqi.models.attributes.PositionalAttributeCollection(this.client, this);
+    return new nopaque.corpus_analysis.cqi.models.attributes.PositionalAttributeCollection(this.client, this);
   }
 
   /**
-   * @returns {cqi.models.attributes.StructuralAttributeCollection}
+   * @returns {nopaque.corpus_analysis.cqi.models.attributes.StructuralAttributeCollection}
    */
   get structuralAttributes() {
-    return new cqi.models.attributes.StructuralAttributeCollection(this.client, this);
+    return new nopaque.corpus_analysis.cqi.models.attributes.StructuralAttributeCollection(this.client, this);
   }
 
   /**
-   * @returns {cqi.models.subcorpora.SubcorpusCollection}
+   * @returns {nopaque.corpus_analysis.cqi.models.subcorpora.SubcorpusCollection}
    */
   get subcorpora() {
-    return new cqi.models.subcorpora.SubcorpusCollection(this.client, this);
+    return new nopaque.corpus_analysis.cqi.models.subcorpora.SubcorpusCollection(this.client, this);
   }
 
   /**
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async drop() {
     return await this.client.api.corpus_drop_corpus(this.apiName);
@@ -75,7 +75,7 @@ cqi.models.corpora.Corpus = class Corpus extends cqi.models.resource.Model {
   /**
    * @param {string} subcorpusName
    * @param {string} query
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async query(subcorpusName, query) {
     return await this.client.api.cqp_query(this.apiName, subcorpusName, query);
@@ -96,7 +96,7 @@ cqi.models.corpora.Corpus = class Corpus extends cqi.models.resource.Model {
   }
 
   /**
-   * @returns {cqi.status.StatusOk}
+   * @returns {nopaque.corpus_analysis.cqi.status.StatusOk}
    */
   async updateDb() {
     return await this.client.api.ext_corpus_update_db(this.apiName);
@@ -113,9 +113,9 @@ cqi.models.corpora.Corpus = class Corpus extends cqi.models.resource.Model {
 };
 
 
-cqi.models.corpora.CorpusCollection = class CorpusCollection extends cqi.models.resource.Collection {
-   /** @type {typeof cqi.models.corpora.Corpus} */
-  static model = cqi.models.corpora.Corpus;
+nopaque.corpus_analysis.cqi.models.corpora.CorpusCollection = class CorpusCollection extends nopaque.corpus_analysis.cqi.models.resource.Collection {
+   /** @type {typeof nopaque.corpus_analysis.cqi.models.corpora.Corpus} */
+  static model = nopaque.corpus_analysis.cqi.models.corpora.Corpus;
 
   /**
    * @param {string} corpusName
@@ -144,19 +144,19 @@ cqi.models.corpora.CorpusCollection = class CorpusCollection extends cqi.models.
 
   /**
    * @param {string} corpusName
-   * @returns {Promise<cqi.models.corpora.Corpus>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.corpora.Corpus>}
    */
   async get(corpusName) {
     return this.prepareModel(await this._get(corpusName));
   }
 
   /**
-   * @returns {Promise<cqi.models.corpora.Corpus[]>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.corpora.Corpus[]>}
    */
   async list() {
      /** @type {string[]} */
     let corpusNames = await this.client.api.corpus_list_corpora();
-     /** @type {cqi.models.corpora.Corpus[]} */
+     /** @type {nopaque.corpus_analysis.cqi.models.corpora.Corpus[]} */
     let corpora = [];
     for (let corpusName of corpusNames) {
       corpora.push(await this.get(corpusName));
diff --git a/app/static/js/CorpusAnalysis/cqi/models/index.js b/app/static/js/CorpusAnalysis/cqi/models/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..d258f12bbf9a8a95be5962fec054723e275a2381
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/cqi/models/index.js
@@ -0,0 +1 @@
+nopaque.corpus_analysis.cqi.models = {};
diff --git a/app/static/js/cqi/models/resource.js b/app/static/js/CorpusAnalysis/cqi/models/resource.js
similarity index 66%
rename from app/static/js/cqi/models/resource.js
rename to app/static/js/CorpusAnalysis/cqi/models/resource.js
index 9d3afde3ac86edef4f4fd08739d6a31725272ee3..3fb3a5b1936af8854ee19e861ce51a4d43de8c30 100644
--- a/app/static/js/cqi/models/resource.js
+++ b/app/static/js/CorpusAnalysis/cqi/models/resource.js
@@ -1,26 +1,26 @@
-cqi.models.resource = {};
+nopaque.corpus_analysis.cqi.models.resource = {};
 
 
 /**
  * A base class for representing a single object on the server.
  */
-cqi.models.resource.Model = class Model {
+nopaque.corpus_analysis.cqi.models.resource.Model = class Model {
   /**
    * @param {object} attrs
-   * @param {cqi.CQiClient} client
-   * @param {cqi.models.resource.Collection} collection
+   * @param {nopaque.corpus_analysis.cqi.CQiClient} client
+   * @param {nopaque.corpus_analysis.cqi.models.resource.Collection} collection
    */
   constructor(attrs, client, collection) {
      /**
       * A client pointing at the server that this object is on.
       *
-      * @type {cqi.CQiClient}
+      * @type {nopaque.corpus_analysis.cqi.CQiClient}
       */
     this.client = client;
      /**
       * The collection that this model is part of.
       *
-      * @type {cqi.models.resource.Collection}
+      * @type {nopaque.corpus_analysis.cqi.models.resource.Collection}
       */
     this.collection = collection;
      /**
@@ -50,22 +50,22 @@ cqi.models.resource.Model = class Model {
 /**
  * A base class for representing all objects of a particular type on the server.
  */
-cqi.models.resource.Collection = class Collection {
+nopaque.corpus_analysis.cqi.models.resource.Collection = class Collection {
    /** 
     * The type of object this collection represents, set by subclasses
     * 
-    * @type {typeof cqi.models.resource.Model}
+    * @type {typeof nopaque.corpus_analysis.cqi.models.resource.Model}
     */
   static model;
 
   /**
-   * @param {cqi.CQiClient} client
+   * @param {nopaque.corpus_analysis.cqi.CQiClient} client
    */
   constructor(client) {
      /**
       * A client pointing at the server that this object is on.
       *
-      * @type {cqi.CQiClient}
+      * @type {nopaque.corpus_analysis.cqi.CQiClient}
       */
      this.client = client;
   }
@@ -82,7 +82,7 @@ cqi.models.resource.Collection = class Collection {
    * Create a model from a set of attributes.
    * 
    * @param {object} attrs
-   * @returns {cqi.models.resource.Model}
+   * @returns {nopaque.corpus_analysis.cqi.models.resource.Model}
    */
   prepareModel(attrs) {
     return new this.constructor.model(attrs, this.client, this);
diff --git a/app/static/js/cqi/models/subcorpora.js b/app/static/js/CorpusAnalysis/cqi/models/subcorpora.js
similarity index 63%
rename from app/static/js/cqi/models/subcorpora.js
rename to app/static/js/CorpusAnalysis/cqi/models/subcorpora.js
index aeba94856fca515a828867e566da18494957db60..79af649b2efffb945097b28459c4d0e8b310c13f 100644
--- a/app/static/js/cqi/models/subcorpora.js
+++ b/app/static/js/CorpusAnalysis/cqi/models/subcorpora.js
@@ -1,7 +1,7 @@
-cqi.models.subcorpora = {};
+nopaque.corpus_analysis.cqi.models.subcorpora = {};
 
 
-cqi.models.subcorpora.Subcorpus = class Subcorpus extends cqi.models.resource.Model {
+nopaque.corpus_analysis.cqi.models.subcorpora.Subcorpus = class Subcorpus extends nopaque.corpus_analysis.cqi.models.resource.Model {
   /**
    * @returns {string}
    */
@@ -31,7 +31,7 @@ cqi.models.subcorpora.Subcorpus = class Subcorpus extends cqi.models.resource.Mo
   }
 
   /**
-   * @returns {Promise<cqi.status.StatusOk>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.status.StatusOk>}
    */
   async drop() {
     return await this.client.api.cqp_drop_subcorpus(this.apiName);
@@ -55,7 +55,7 @@ cqi.models.subcorpora.Subcorpus = class Subcorpus extends cqi.models.resource.Mo
   /**
    * @param {number} cutoff
    * @param {number} field
-   * @param {cqi.models.attributes.PositionalAttribute} attribute
+   * @param {nopaque.corpus_analysis.cqi.models.attributes.PositionalAttribute} attribute
    * @returns {Promise<number[]>}
    */
   async fdist1(cutoff, field, attribute) {
@@ -70,9 +70,9 @@ cqi.models.subcorpora.Subcorpus = class Subcorpus extends cqi.models.resource.Mo
   /**
    * @param {number} cutoff
    * @param {number} field1
-   * @param {cqi.models.attributes.PositionalAttribute} attribute1
+   * @param {nopaque.corpus_analysis.cqi.models.attributes.PositionalAttribute} attribute1
    * @param {number} field2
-   * @param {cqi.models.attributes.PositionalAttribute} attribute2
+   * @param {nopaque.corpus_analysis.cqi.models.attributes.PositionalAttribute} attribute2
    * @returns {Promise<number[]>}
    */ 
   async fdist2(cutoff, field1, attribute1, field2, attribute2) {
@@ -122,17 +122,17 @@ cqi.models.subcorpora.Subcorpus = class Subcorpus extends cqi.models.resource.Mo
 };
 
 
-cqi.models.subcorpora.SubcorpusCollection = class SubcorpusCollection extends cqi.models.resource.Collection {
-   /** @type {typeof cqi.models.subcorpora.Subcorpus} */
-  static model = cqi.models.subcorpora.Subcorpus;
+nopaque.corpus_analysis.cqi.models.subcorpora.SubcorpusCollection = class SubcorpusCollection extends nopaque.corpus_analysis.cqi.models.resource.Collection {
+   /** @type {typeof nopaque.corpus_analysis.cqi.models.subcorpora.Subcorpus} */
+  static model = nopaque.corpus_analysis.cqi.models.subcorpora.Subcorpus;
 
   /**
-   * @param {cqi.CQiClient} client
-   * @param {cqi.models.corpora.Corpus} corpus
+   * @param {nopaque.corpus_analysis.cqi.CQiClient} client
+   * @param {nopaque.corpus_analysis.cqi.models.corpora.Corpus} corpus
    */
   constructor(client, corpus) {
     super(client);
-     /** @type {cqi.models.corpora.Corpus} */
+     /** @type {nopaque.corpus_analysis.cqi.models.corpora.Corpus} */
     this.corpus = corpus;
   }
 
@@ -145,17 +145,17 @@ cqi.models.subcorpora.SubcorpusCollection = class SubcorpusCollection extends cq
     let apiName = `${this.corpus.apiName}:${subcorpusName}`;
      /** @type {object} */
     let fields = {};
-    if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.constants.FIELD_MATCH)) {
-      fields.match = cqi.constants.FIELD_MATCH;
+    if (await this.client.api.cqp_subcorpus_has_field(apiName, nopaque.corpus_analysis.cqi.constants.FIELD_MATCH)) {
+      fields.match = nopaque.corpus_analysis.cqi.constants.FIELD_MATCH;
     }
-    if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.constants.FIELD_MATCHEND)) {
-      fields.matchend = cqi.constants.FIELD_MATCHEND
+    if (await this.client.api.cqp_subcorpus_has_field(apiName, nopaque.corpus_analysis.cqi.constants.FIELD_MATCHEND)) {
+      fields.matchend = nopaque.corpus_analysis.cqi.constants.FIELD_MATCHEND
     }
-    if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.constants.FIELD_TARGET)) {
-      fields.target = cqi.constants.FIELD_TARGET
+    if (await this.client.api.cqp_subcorpus_has_field(apiName, nopaque.corpus_analysis.cqi.constants.FIELD_TARGET)) {
+      fields.target = nopaque.corpus_analysis.cqi.constants.FIELD_TARGET
     }
-    if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.constants.FIELD_KEYWORD)) {
-      fields.keyword = cqi.constants.FIELD_KEYWORD
+    if (await this.client.api.cqp_subcorpus_has_field(apiName, nopaque.corpus_analysis.cqi.constants.FIELD_KEYWORD)) {
+      fields.keyword = nopaque.corpus_analysis.cqi.constants.FIELD_KEYWORD
     }
     return {
       api_name: apiName,
@@ -167,19 +167,19 @@ cqi.models.subcorpora.SubcorpusCollection = class SubcorpusCollection extends cq
 
   /**
    * @param {string} subcorpusName
-   * @returns {Promise<cqi.models.subcorpora.Subcorpus>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.subcorpora.Subcorpus>}
    */
   async get(subcorpusName) {
     return this.prepareModel(await this._get(subcorpusName));
   }
 
   /**
-   * @returns {Promise<cqi.models.subcorpora.Subcorpus[]>}
+   * @returns {Promise<nopaque.corpus_analysis.cqi.models.subcorpora.Subcorpus[]>}
    */
   async list() {
      /** @type {string[]} */
     let subcorpusNames = await this.client.api.cqp_list_subcorpora(this.corpus.apiName);
-     /** @type {cqi.models.subcorpora.Subcorpus[]} */
+     /** @type {nopaque.corpus_analysis.cqi.models.subcorpora.Subcorpus[]} */
     let subcorpora = [];
     for (let subcorpusName of subcorpusNames) {
       subcorpora.push(await this.get(subcorpusName));
diff --git a/app/static/js/CorpusAnalysis/cqi/status.js b/app/static/js/CorpusAnalysis/cqi/status.js
new file mode 100644
index 0000000000000000000000000000000000000000..1d6a1fc71d9d8e757ae59c069ab3162cbccd3550
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/cqi/status.js
@@ -0,0 +1,51 @@
+nopaque.corpus_analysis.cqi.status = {};
+
+
+/**
+ * A base class from which all other status inherit.
+ */
+nopaque.corpus_analysis.cqi.status.CQiStatus = class CQiStatus {
+  constructor() {
+    this.code = undefined;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.status.StatusOk = class StatusOk extends nopaque.corpus_analysis.cqi.status.CQiStatus {
+  constructor() {
+    super();
+    this.code = 257;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.status.StatusConnectOk = class StatusConnectOk extends nopaque.corpus_analysis.cqi.status.CQiStatus {
+  constructor() {
+    super();
+    this.code = 258;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.status.StatusByeOk = class StatusByeOk extends nopaque.corpus_analysis.cqi.status.CQiStatus {
+  constructor() {
+    super();
+    this.code = 259;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.status.StatusPingOk = class StatusPingOk extends nopaque.corpus_analysis.cqi.status.CQiStatus {
+  constructor() {
+    super();
+    this.code = 260;
+  }
+};
+
+
+nopaque.corpus_analysis.cqi.status.lookup = {
+  257: nopaque.corpus_analysis.cqi.status.StatusOk,
+  258: nopaque.corpus_analysis.cqi.status.StatusConnectOk,
+  259: nopaque.corpus_analysis.cqi.status.StatusByeOk,
+  260: nopaque.corpus_analysis.cqi.status.StatusPingOk
+};
diff --git a/app/static/js/CorpusAnalysis/index.js b/app/static/js/CorpusAnalysis/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2ec10ca6f069f368862ff6773b363792a5e6b93
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/index.js
@@ -0,0 +1 @@
+nopaque.corpus_analysis = {};
diff --git a/app/static/js/CorpusAnalysis/query-builder/general-query-builder-functions.js b/app/static/js/CorpusAnalysis/query-builder/general-query-builder-functions.js
index 003bb01a255f9ee1b69adfe99e7c57340299d444..97380ca717e7a6e70491ef588f944ff1f1c632bf 100644
--- a/app/static/js/CorpusAnalysis/query-builder/general-query-builder-functions.js
+++ b/app/static/js/CorpusAnalysis/query-builder/general-query-builder-functions.js
@@ -51,7 +51,7 @@ class GeneralQueryBuilderFunctions {
   }
 
   addPlaceholder() {
-    let placeholder = Utils.HTMLToElement('<span id="corpus-analysis-concordance-query-builder-input-field-placeholder">Click on a button to add a query component</span>');
+    let placeholder = nopaque.Utils.HTMLToElement('<span id="corpus-analysis-concordance-query-builder-input-field-placeholder">Click on a button to add a query component</span>');
     this.elements.queryInputField.appendChild(placeholder);
   }
   
@@ -81,9 +81,9 @@ class GeneralQueryBuilderFunctions {
 
   queryChipFactory(dataType, prettyQueryText, queryText, index = null, isClosingTag = false, isEditable = false) {
     // Creates a new query chip element, adds Eventlisteners for selection, deletion and drag and drop and appends it to the query input field.
-    queryText = Utils.escape(queryText);
-    prettyQueryText = Utils.escape(prettyQueryText);
-    let queryChipElement = Utils.HTMLToElement(
+    queryText = nopaque.Utils.escape(queryText);
+    prettyQueryText = nopaque.Utils.escape(prettyQueryText);
+    let queryChipElement = nopaque.Utils.HTMLToElement(
       `
         <span class="chip query-component" data-type="${dataType}" data-query="${queryText}" draggable="true" data-closing-tag="${isClosingTag}">
           ${prettyQueryText}${isEditable ? '<i class="material-icons chip-action-button" data-chip-action="edit" style="padding-left:5px; font-size:18px; cursor:pointer;">edit</i>': ''}
@@ -213,7 +213,7 @@ class GeneralQueryBuilderFunctions {
       queryChips = this.elements.queryInputField.querySelectorAll('.query-component[data-type="token"]');
     }
     setTimeout(() => {
-      let targetChipElement = Utils.HTMLToElement('<span class="chip drop-target">Drop here</span>');
+      let targetChipElement = nopaque.Utils.HTMLToElement('<span class="chip drop-target">Drop here</span>');
       for (let element of queryChips) {
         if (element === this.elements.queryInputField.querySelectorAll('.query-component')[0]) {
           let secondTargetChipClone = targetChipElement.cloneNode(true);
@@ -261,7 +261,7 @@ class GeneralQueryBuilderFunctions {
     this.elements.queryChipElements.forEach(element => {
       let queryElement = element.dataset.query;
       if (queryElement !== undefined) {
-        queryElement = Utils.escape(queryElement);
+        queryElement = nopaque.Utils.escape(queryElement);
       }
       queryInputFieldContent.push(queryElement);
     });
diff --git a/app/static/js/nopaque/app.js b/app/static/js/app.js
similarity index 97%
rename from app/static/js/nopaque/app.js
rename to app/static/js/app.js
index c4e837c4a8b7680fef535b796d67dd7fe2761e90..27b675f4df48a2ad03728dcf3bfec627ef30b7d4 100644
--- a/app/static/js/nopaque/app.js
+++ b/app/static/js/app.js
@@ -179,7 +179,7 @@ nopaque.App = class App {
       {
         dismissible: false,
         onCloseEnd: (modalElement) => {
-          Requests.users.entity.acceptTermsOfUse();
+          nopaque.requests.users.entity.acceptTermsOfUse();
         }
       }
     );
@@ -188,9 +188,9 @@ nopaque.App = class App {
 
     /* Initialize nopaque Components */
     // #region 
-    ResourceDisplays.AutoInit();
-    ResourceLists.AutoInit();
-    Forms.AutoInit();
+    nopaque.resource_displays.AutoInit();
+    nopaque.resource_lists.AutoInit();
+    nopaque.forms.AutoInit();
     // #endregion
   }
 };
diff --git a/app/static/js/cqi/api/index.js b/app/static/js/cqi/api/index.js
deleted file mode 100644
index fb42389b4cc454d5966447381990c2bc4fe4718d..0000000000000000000000000000000000000000
--- a/app/static/js/cqi/api/index.js
+++ /dev/null
@@ -1 +0,0 @@
-cqi.api = {};
diff --git a/app/static/js/cqi/constants.js b/app/static/js/cqi/constants.js
deleted file mode 100644
index b12fef88327810ec83432bd2822391c5106f33bf..0000000000000000000000000000000000000000
--- a/app/static/js/cqi/constants.js
+++ /dev/null
@@ -1,43 +0,0 @@
-cqi.constants = {};
-
-/** @type {number} */
-cqi.constants.FIELD_KEYWORD = 9;
-
-/** @type {number} */
-cqi.constants.FIELD_MATCH = 16;
-
-/** @type {number} */
-cqi.constants.FIELD_MATCHEND = 17;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET = 0;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_0 = 0;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_1 = 1;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_2 = 2;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_3 = 3;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_4 = 4;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_5 = 5;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_6 = 6;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_7 = 7;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_8 = 8;
-
-/** @type {number} */
-cqi.constants.FIELD_TARGET_9 = 9;
diff --git a/app/static/js/cqi/errors.js b/app/static/js/cqi/errors.js
deleted file mode 100644
index c7011eb7c7250ae64d1cddd81470d877fbacf0c3..0000000000000000000000000000000000000000
--- a/app/static/js/cqi/errors.js
+++ /dev/null
@@ -1,185 +0,0 @@
-cqi.errors = {};
-
-
-/**
- * A base class from which all other errors inherit.
- * If you want to catch all errors that the CQi package might throw,
- * catch this base error.
- */
-cqi.errors.CQiError = class CQiError extends Error {
-  constructor(message) {
-    super(message);
-    this.code = undefined;
-    this.description = undefined;
-  }
-};
-
-
-cqi.errors.Error = class Error extends cqi.errors.CQiError {
-  constructor(message) {
-    super(message);
-    this.code = 2;
-  }
-};
-
-
-cqi.errors.ErrorGeneralError = class ErrorGeneralError extends cqi.errors.Error {
-  constructor(message) {
-    super(message);
-    this.code = 513;
-  }
-};
-
-
-cqi.errors.ErrorConnectRefused = class ErrorConnectRefused extends cqi.errors.Error {
-  constructor(message) {
-    super(message);
-    this.code = 514;
-  }
-};
-
-
-cqi.errors.ErrorUserAbort = class ErrorUserAbort extends cqi.errors.Error {
-  constructor(message) {
-    super(message);
-    this.code = 515;
-  }
-};
-
-
-cqi.errors.ErrorSyntaxError = class ErrorSyntaxError extends cqi.errors.Error {
-  constructor(message) {
-    super(message);
-    this.code = 516;
-  }
-};
-
-
-cqi.errors.CLError = class Error extends cqi.errors.CQiError {
-  constructor(message) {
-    super(message);
-    this.code = 4;
-  }
-};
-
-
-cqi.errors.CLErrorNoSuchAttribute = class CLErrorNoSuchAttribute extends cqi.errors.CLError {
-  constructor(message) {
-    super(message);
-    this.code = 1025;
-    this.description = "CQi server couldn't open attribute";
-  }
-};
-
-
-cqi.errors.CLErrorWrongAttributeType = class CLErrorWrongAttributeType extends cqi.errors.CLError {
-  constructor(message) {
-    super(message);
-    this.code = 1026;
-  }
-};
-
-
-cqi.errors.CLErrorOutOfRange = class CLErrorOutOfRange extends cqi.errors.CLError {
-  constructor(message) {
-    super(message);
-    this.code = 1027;
-  }
-};
-
-
-cqi.errors.CLErrorRegex = class CLErrorRegex extends cqi.errors.CLError {
-  constructor(message) {
-    super(message);
-    this.code = 1028;
-  }
-};
-
-
-cqi.errors.CLErrorCorpusAccess = class CLErrorCorpusAccess extends cqi.errors.CLError {
-  constructor(message) {
-    super(message);
-    this.code = 1029;
-  }
-};
-
-
-cqi.errors.CLErrorOutOfMemory = class CLErrorOutOfMemory extends cqi.errors.CLError {
-  constructor(message) {
-    super(message);
-    this.code = 1030;
-    this.description = 'CQi server has run out of memory; try discarding some other corpora and/or subcorpora';
-  }
-};
-
-
-cqi.errors.CLErrorInternal = class CLErrorInternal extends cqi.errors.CLError {
-  constructor(message) {
-    super(message);
-    this.code = 1031;
-    this.description = "The classical 'please contact technical support' error";
-  }
-};
-
-
-cqi.errors.CQPError = class Error extends cqi.errors.CQiError {
-  constructor(message) {
-    super(message);
-    this.code = 5;
-  }
-};
-
-
-cqi.errors.CQPErrorGeneral = class CQPErrorGeneral extends cqi.errors.CQPError {
-  constructor(message) {
-    super(message);
-    this.code = 1281;
-  }
-};
-
-
-cqi.errors.CQPErrorNoSuchCorpus = class CQPErrorNoSuchCorpus extends cqi.errors.CQPError {
-  constructor(message) {
-    super(message);
-    this.code = 1282;
-  }
-};
-
-
-cqi.errors.CQPErrorInvalidField = class CQPErrorInvalidField extends cqi.errors.CQPError {
-  constructor(message) {
-    super(message);
-    this.code = 1283;
-  }
-};
-
-
-cqi.errors.CQPErrorOutOfRange = class CQPErrorOutOfRange extends cqi.errors.CQPError {
-  constructor(message) {
-    super(message);
-    this.code = 1284;
-    this.description = 'A number is out of range';
-  }
-};
-
-
-cqi.errors.lookup = {
-  2: cqi.errors.Error,
-  513: cqi.errors.ErrorGeneralError,
-  514: cqi.errors.ErrorConnectRefused,
-  515: cqi.errors.ErrorUserAbort,
-  516: cqi.errors.ErrorSyntaxError,
-  4: cqi.errors.CLError,
-  1025: cqi.errors.CLErrorNoSuchAttribute,
-  1026: cqi.errors.CLErrorWrongAttributeType,
-  1027: cqi.errors.CLErrorOutOfRange,
-  1028: cqi.errors.CLErrorRegex,
-  1029: cqi.errors.CLErrorCorpusAccess,
-  1030: cqi.errors.CLErrorOutOfMemory,
-  1031: cqi.errors.CLErrorInternal,
-  5: cqi.errors.CQPError,
-  1281: cqi.errors.CQPErrorGeneral,
-  1282: cqi.errors.CQPErrorNoSuchCorpus,
-  1283: cqi.errors.CQPErrorInvalidField,
-  1284: cqi.errors.CQPErrorOutOfRange
-};
diff --git a/app/static/js/cqi/index.js b/app/static/js/cqi/index.js
deleted file mode 100644
index d941a870e8e163f0579648d31764af2147e124e7..0000000000000000000000000000000000000000
--- a/app/static/js/cqi/index.js
+++ /dev/null
@@ -1 +0,0 @@
-var cqi = {};
diff --git a/app/static/js/cqi/models/index.js b/app/static/js/cqi/models/index.js
deleted file mode 100644
index 4973862f6400ffb628007d69705f02e52e628af6..0000000000000000000000000000000000000000
--- a/app/static/js/cqi/models/index.js
+++ /dev/null
@@ -1 +0,0 @@
-cqi.models = {};
diff --git a/app/static/js/cqi/status.js b/app/static/js/cqi/status.js
deleted file mode 100644
index 0782ee26e29b190f02921575a8f84c927589fd57..0000000000000000000000000000000000000000
--- a/app/static/js/cqi/status.js
+++ /dev/null
@@ -1,51 +0,0 @@
-cqi.status = {};
-
-
-/**
- * A base class from which all other status inherit.
- */
-cqi.status.CQiStatus = class CQiStatus {
-  constructor() {
-    this.code = undefined;
-  }
-};
-
-
-cqi.status.StatusOk = class StatusOk extends cqi.status.CQiStatus {
-  constructor() {
-    super();
-    this.code = 257;
-  }
-};
-
-
-cqi.status.StatusConnectOk = class StatusConnectOk extends cqi.status.CQiStatus {
-  constructor() {
-    super();
-    this.code = 258;
-  }
-};
-
-
-cqi.status.StatusByeOk = class StatusByeOk extends cqi.status.CQiStatus {
-  constructor() {
-    super();
-    this.code = 259;
-  }
-};
-
-
-cqi.status.StatusPingOk = class StatusPingOk extends cqi.status.CQiStatus {
-  constructor() {
-    super();
-    this.code = 260;
-  }
-};
-
-
-cqi.status.lookup = {
-  257: cqi.status.StatusOk,
-  258: cqi.status.StatusConnectOk,
-  259: cqi.status.StatusByeOk,
-  260: cqi.status.StatusPingOk
-};
diff --git a/app/static/js/forms/base-form.js b/app/static/js/forms/base-form.js
index b856048500eebc803af849aebeed136099a43082..5b4b9e4186420fe81d8b4786307776403496d9a3 100644
--- a/app/static/js/forms/base-form.js
+++ b/app/static/js/forms/base-form.js
@@ -1,4 +1,4 @@
-Forms.BaseForm = class BaseForm {
+nopaque.forms.BaseForm = class BaseForm {
   static htmlClass;
 
   constructor(formElement) {
@@ -28,7 +28,7 @@ Forms.BaseForm = class BaseForm {
 
   submit(event) {
     let request = new XMLHttpRequest();
-    let modalElement = Utils.HTMLToElement(
+    let modalElement = nopaque.Utils.HTMLToElement(
       `
         <div class="modal">
           <div class="modal-content">
@@ -67,7 +67,7 @@ Forms.BaseForm = class BaseForm {
     for (let selectElement of this.formElement.querySelectorAll('select')) {
       if (selectElement.value === '') {
         let inputFieldElement = selectElement.closest('.input-field');
-        let errorHelperTextElement = Utils.HTMLToElement(
+        let errorHelperTextElement = nopaque.Utils.HTMLToElement(
           '<span class="helper-text error-color-text" data-helper-text-type="error">Please select an option.</span>'
         );
         inputFieldElement.appendChild(errorHelperTextElement);
@@ -93,7 +93,7 @@ Forms.BaseForm = class BaseForm {
             .querySelector(`input[name$="${inputName}"], select[name$="${inputName}"]`)
             .closest('.input-field');
           for (let inputError of inputErrors) {
-            let errorHelperTextElement = Utils.HTMLToElement(
+            let errorHelperTextElement = nopaque.Utils.HTMLToElement(
               `<span class="helper-text error-color-text" data-helper-type="error">${inputError}</span>`
             );
             inputFieldElement.appendChild(errorHelperTextElement);
diff --git a/app/static/js/forms/create-contribution-form.js b/app/static/js/forms/create-contribution-form.js
index 4474ff893bd1d02a5c94343c53219f3389734c38..7c9326e9e2d0fcf93821a87ff650605d73e96d60 100644
--- a/app/static/js/forms/create-contribution-form.js
+++ b/app/static/js/forms/create-contribution-form.js
@@ -1,4 +1,4 @@
-Forms.CreateContributionForm = class CreateContributionForm extends Forms.BaseForm {
+nopaque.forms.CreateContributionForm = class CreateContributionForm extends nopaque.forms.BaseForm {
   static htmlClass = 'create-contribution-form';
 
   constructor(formElement) {
diff --git a/app/static/js/forms/create-corpus-file-form.js b/app/static/js/forms/create-corpus-file-form.js
index beec4ee2276960da81b98628db1ecdb544c98ac5..439ad8c5efbda5fd8feb5b5a3c4d58e7641add8f 100644
--- a/app/static/js/forms/create-corpus-file-form.js
+++ b/app/static/js/forms/create-corpus-file-form.js
@@ -1,4 +1,4 @@
-Forms.CreateCorpusFileForm = class CreateCorpusFileForm extends Forms.BaseForm {
+nopaque.forms.CreateCorpusFileForm = class CreateCorpusFileForm extends nopaque.forms.BaseForm {
   static htmlClass = 'create-corpus-file-form';
 
   constructor(formElement) {
diff --git a/app/static/js/forms/create-job-form.js b/app/static/js/forms/create-job-form.js
index 6e6c7c0116f5844979b08668e4344dda6a5b5503..9322286e8ea39b186086a921f56f8cef6b1ce5d0 100644
--- a/app/static/js/forms/create-job-form.js
+++ b/app/static/js/forms/create-job-form.js
@@ -1,4 +1,4 @@
-Forms.CreateJobForm = class CreateJobForm extends Forms.BaseForm {
+nopaque.forms.CreateJobForm = class CreateJobForm extends nopaque.forms.BaseForm {
   static htmlClass = 'create-job-form';
 
   constructor(formElement) {
diff --git a/app/static/js/forms/index.js b/app/static/js/forms/index.js
index a6d098ddf28d01701cc2e9e0f643dfc2066f39a6..5a382b44d98106d5a01d4906f4fa09313a053607 100644
--- a/app/static/js/forms/index.js
+++ b/app/static/js/forms/index.js
@@ -1,11 +1,11 @@
-var Forms = {};
+nopaque.forms = {};
 
-Forms.AutoInit = () => {
-  for (let propertyName in Forms) {
-    let property = Forms[propertyName];
-    // Call autoInit of all properties that are subclasses of Forms.BaseForm.
-    // This does not include Forms.BaseForm itself.
-    if (property.prototype instanceof Forms.BaseForm) {
+nopaque.forms.AutoInit = () => {
+  for (let propertyName in nopaque.forms) {
+    let property = nopaque.forms[propertyName];
+    // Initialize properties that are subclasses of nopaque.forms.BaseForm.
+    // This does not include nopaque.forms.BaseForm itself.
+    if (property.prototype instanceof nopaque.forms.BaseForm) {
       // Check if the static htmlClass property is defined.
       if (property.htmlClass === undefined) {return;}
       // Gather all HTML elements that have the `this.htmlClass` class
diff --git a/app/static/js/index.js b/app/static/js/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..c2537ef6f4cbad157675d43411060d167ad595b3
--- /dev/null
+++ b/app/static/js/index.js
@@ -0,0 +1,5 @@
+/*
+ * This object functions as a global namespace for nopaque.
+ * All components of nopaque should be attached to this object.
+ */
+var nopaque = {};
diff --git a/app/static/js/nopaque/index.js b/app/static/js/nopaque/index.js
deleted file mode 100644
index 0d7bc55f16a87de3d7ef8d3a219e49fccba765d8..0000000000000000000000000000000000000000
--- a/app/static/js/nopaque/index.js
+++ /dev/null
@@ -1 +0,0 @@
-var nopaque = {};
diff --git a/app/static/js/requests/admin.js b/app/static/js/requests/admin.js
index fdfe5dcd02af29b1920fc4dd19e885d7715c6d24..bbaf64471b51e73bac118f7b0ad57999ff61a69b 100644
--- a/app/static/js/requests/admin.js
+++ b/app/static/js/requests/admin.js
@@ -1,19 +1,19 @@
 /*****************************************************************************
  * Requests for /admin routes                                                *
 *****************************************************************************/
-Requests.admin = {};
+nopaque.requests.admin = {};
 
-Requests.admin.users = {};
+nopaque.requests.admin.users = {};
 
-Requests.admin.users.entity = {};
+nopaque.requests.admin.users.entity = {};
 
-Requests.admin.users.entity.confirmed = {};
+nopaque.requests.admin.users.entity.confirmed = {};
 
-Requests.admin.users.entity.confirmed.update = (userId, value) => {
+nopaque.requests.admin.users.entity.confirmed.update = (userId, value) => {
   let input = `/admin/users/${userId}/confirmed`;
   let init = {
     method: 'PUT',
     body: JSON.stringify(value)
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
diff --git a/app/static/js/requests/contributions.js b/app/static/js/requests/contributions.js
index cd6329b6c5d07c3fe3c0f5375cde36b869e4f8f8..20d26212af44e6cb813a0c08868a20998b8c84bf 100644
--- a/app/static/js/requests/contributions.js
+++ b/app/static/js/requests/contributions.js
@@ -1,58 +1,58 @@
 /*****************************************************************************
 * Requests for /contributions routes                                         *
 *****************************************************************************/
-Requests.contributions = {};
+nopaque.requests.contributions = {};
 
 
 /*****************************************************************************
 * Requests for /contributions/spacy-nlp-pipeline-models routes               *
 *****************************************************************************/
-Requests.contributions.spacy_nlp_pipeline_models = {};
+nopaque.requests.contributions.spacy_nlp_pipeline_models = {};
 
-Requests.contributions.spacy_nlp_pipeline_models.entity = {};
+nopaque.requests.contributions.spacy_nlp_pipeline_models.entity = {};
 
-Requests.contributions.spacy_nlp_pipeline_models.entity.delete = (spacyNlpPipelineModelId) => {
+nopaque.requests.contributions.spacy_nlp_pipeline_models.entity.delete = (spacyNlpPipelineModelId) => {
   let input = `/contributions/spacy-nlp-pipeline-models/${spacyNlpPipelineModelId}`;
   let init = {
     method: 'DELETE'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.contributions.spacy_nlp_pipeline_models.entity.isPublic = {};
+nopaque.requests.contributions.spacy_nlp_pipeline_models.entity.isPublic = {};
 
-Requests.contributions.spacy_nlp_pipeline_models.entity.isPublic.update = (spacyNlpPipelineModelId, value) => {
+nopaque.requests.contributions.spacy_nlp_pipeline_models.entity.isPublic.update = (spacyNlpPipelineModelId, value) => {
   let input = `/contributions/spacy-nlp-pipeline-models/${spacyNlpPipelineModelId}/is_public`;
   let init = {
     method: 'PUT',
     body: JSON.stringify(value)
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
 
 /*****************************************************************************
 * Requests for /contributions/tesseract-ocr-pipeline-models routes           *
 *****************************************************************************/
-Requests.contributions.tesseract_ocr_pipeline_models = {};
+nopaque.requests.contributions.tesseract_ocr_pipeline_models = {};
 
-Requests.contributions.tesseract_ocr_pipeline_models.entity = {};
+nopaque.requests.contributions.tesseract_ocr_pipeline_models.entity = {};
 
-Requests.contributions.tesseract_ocr_pipeline_models.entity.delete = (tesseractOcrPipelineModelId) => {
+nopaque.requests.contributions.tesseract_ocr_pipeline_models.entity.delete = (tesseractOcrPipelineModelId) => {
   let input = `/contributions/tesseract-ocr-pipeline-models/${tesseractOcrPipelineModelId}`;
   let init = {
     method: 'DELETE'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic = {};
+nopaque.requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic = {};
 
-Requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic.update = (tesseractOcrPipelineModelId, value) => {
+nopaque.requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic.update = (tesseractOcrPipelineModelId, value) => {
   let input = `/contributions/tesseract-ocr-pipeline-models/${tesseractOcrPipelineModelId}/is_public`;
   let init = {
     method: 'PUT',
     body: JSON.stringify(value)
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
diff --git a/app/static/js/requests/corpora.js b/app/static/js/requests/corpora.js
index 4c65a7eeb2903cfab124df28bd95d9a1cff43cbe..beb87f84e487181726077882e31122cb83db9311 100644
--- a/app/static/js/requests/corpora.js
+++ b/app/static/js/requests/corpora.js
@@ -1,102 +1,102 @@
 /*****************************************************************************
 * Requests for /corpora routes                                               *
 *****************************************************************************/
-Requests.corpora = {};
+nopaque.requests.corpora = {};
 
-Requests.corpora.entity = {};
+nopaque.requests.corpora.entity = {};
 
-Requests.corpora.entity.delete = (corpusId) => {
+nopaque.requests.corpora.entity.delete = (corpusId) => {
   let input = `/corpora/${corpusId}`;
   let init = {
     method: 'DELETE'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.corpora.entity.build = (corpusId) => {
+nopaque.requests.corpora.entity.build = (corpusId) => {
   let input = `/corpora/${corpusId}/build`;
   let init = {
     method: 'POST',
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.corpora.entity.generateShareLink = (corpusId, role, expiration) => {
+nopaque.requests.corpora.entity.generateShareLink = (corpusId, role, expiration) => {
   let input = `/corpora/${corpusId}/generate-share-link`;
   let init = {
     method: 'POST',
     body: JSON.stringify({role: role, expiration: expiration})
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.corpora.entity.getStopwords = () => {
+nopaque.requests.corpora.entity.getStopwords = () => {
   let input = `/corpora/stopwords`;
   let init = {
     method: 'GET'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.corpora.entity.isPublic = {};
+nopaque.requests.corpora.entity.isPublic = {};
 
-Requests.corpora.entity.isPublic.update = (corpusId, isPublic) => {
+nopaque.requests.corpora.entity.isPublic.update = (corpusId, isPublic) => {
   let input = `/corpora/${corpusId}/is_public`;
   let init = {
     method: 'PUT',
     body: JSON.stringify(isPublic)
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
 
 /*****************************************************************************
 * Requests for /corpora/<entity>/files routes                                *
 *****************************************************************************/
-Requests.corpora.entity.files = {};
+nopaque.requests.corpora.entity.files = {};
 
-Requests.corpora.entity.files.ent = {};
+nopaque.requests.corpora.entity.files.ent = {};
 
-Requests.corpora.entity.files.ent.delete = (corpusId, corpusFileId) => {
+nopaque.requests.corpora.entity.files.ent.delete = (corpusId, corpusFileId) => {
   let input = `/corpora/${corpusId}/files/${corpusFileId}`;
   let init = {
     method: 'DELETE',
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
 
 /*****************************************************************************
 * Requests for /corpora/<entity>/followers routes                            *
 *****************************************************************************/
-Requests.corpora.entity.followers = {};
+nopaque.requests.corpora.entity.followers = {};
 
-Requests.corpora.entity.followers.add = (corpusId, usernames) => {
+nopaque.requests.corpora.entity.followers.add = (corpusId, usernames) => {
   let input = `/corpora/${corpusId}/followers`;
   let init = {
     method: 'POST',
     body: JSON.stringify(usernames)
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.corpora.entity.followers.entity = {};
+nopaque.requests.corpora.entity.followers.entity = {};
 
-Requests.corpora.entity.followers.entity.delete = (corpusId, followerId) => {
+nopaque.requests.corpora.entity.followers.entity.delete = (corpusId, followerId) => {
   let input = `/corpora/${corpusId}/followers/${followerId}`;
   let init = {
     method: 'DELETE',
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.corpora.entity.followers.entity.role = {};
+nopaque.requests.corpora.entity.followers.entity.role = {};
 
-Requests.corpora.entity.followers.entity.role.update = (corpusId, followerId, value) => {
+nopaque.requests.corpora.entity.followers.entity.role.update = (corpusId, followerId, value) => {
   let input = `/corpora/${corpusId}/followers/${followerId}/role`;
   let init = {
     method: 'PUT',
     body: JSON.stringify(value)
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
diff --git a/app/static/js/requests/index.js b/app/static/js/requests/index.js
index c5bb8a1f51c3b99f6fd506603a3ac95674da0ab0..177eca880386100c04422c7028cbc7ccd3ab2ded 100644
--- a/app/static/js/requests/index.js
+++ b/app/static/js/requests/index.js
@@ -1,6 +1,6 @@
-var Requests = {};
+nopaque.requests = {};
 
-Requests.JSONfetch = (input, init={}) => {
+nopaque.requests.JSONfetch = (input, init={}) => {
   return new Promise((resolve, reject) => {
     let fixedInit = {};
     fixedInit.headers = {};
@@ -8,7 +8,7 @@ Requests.JSONfetch = (input, init={}) => {
     if (init.hasOwnProperty('body')) {
       fixedInit.headers['Content-Type'] = 'application/json';
     }
-    fetch(input, Utils.mergeObjectsDeep(init, fixedInit))
+    fetch(input, nopaque.Utils.mergeObjectsDeep(init, fixedInit))
       .then(
         (response) => {
           if (response.ok) {
diff --git a/app/static/js/requests/jobs.js b/app/static/js/requests/jobs.js
index 6a50463d0d669228002061cae80ef7c14d4f5c60..35abce329f74e1ca19456957db448cfb2d38a835 100644
--- a/app/static/js/requests/jobs.js
+++ b/app/static/js/requests/jobs.js
@@ -1,30 +1,30 @@
 /*****************************************************************************
 * Requests for /jobs routes                                                  *
 *****************************************************************************/
-Requests.jobs = {};
+nopaque.requests.jobs = {};
 
-Requests.jobs.entity = {};
+nopaque.requests.jobs.entity = {};
 
-Requests.jobs.entity.delete = (jobId) => {
+nopaque.requests.jobs.entity.delete = (jobId) => {
   let input = `/jobs/${jobId}`;
   let init = {
     method: 'DELETE'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.jobs.entity.log = (jobId) => {
+nopaque.requests.jobs.entity.log = (jobId) => {
   let input = `/jobs/${jobId}/log`;
   let init = {
     method: 'GET'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.jobs.entity.restart = (jobId) => {
+nopaque.requests.jobs.entity.restart = (jobId) => {
   let input = `/jobs/${jobId}/restart`;
   let init = {
     method: 'POST'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
diff --git a/app/static/js/requests/users.js b/app/static/js/requests/users.js
index fb76cb074ae74b7c1914b6b02747f6907e5308c4..25ec135311137689fc81a110c5056eee7c15c123 100644
--- a/app/static/js/requests/users.js
+++ b/app/static/js/requests/users.js
@@ -2,50 +2,50 @@
 * Users                                                                      *
 * Fetch requests for /users routes                                           *
 *****************************************************************************/
-Requests.users = {};
+nopaque.requests.users = {};
 
-Requests.users.entity = {};
+nopaque.requests.users.entity = {};
 
-Requests.users.entity.delete = (userId) => {
+nopaque.requests.users.entity.delete = (userId) => {
   let input = `/users/${userId}`;
   let init = {
     method: 'DELETE'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.users.entity.acceptTermsOfUse = () => {
+nopaque.requests.users.entity.acceptTermsOfUse = () => {
   let input = `/users/accept-terms-of-use`;
   let init = {
     method: 'POST'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
-Requests.users.entity.avatar = {};
+nopaque.requests.users.entity.avatar = {};
 
-Requests.users.entity.avatar.delete = (userId) => {
+nopaque.requests.users.entity.avatar.delete = (userId) => {
   let input = `/users/${userId}/avatar`;
   let init = {
     method: 'DELETE'
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 }
 
 
 /*****************************************************************************
 * Requests for /users/<entity>/settings routes                               *
 *****************************************************************************/
-Requests.users.entity.settings = {};
+nopaque.requests.users.entity.settings = {};
 
-Requests.users.entity.settings.profilePrivacy = {};
+nopaque.requests.users.entity.settings.profilePrivacy = {};
 
-Requests.users.entity.settings.profilePrivacy.update = (userId, profilePrivacySetting, enabled) => {
+nopaque.requests.users.entity.settings.profilePrivacy.update = (userId, profilePrivacySetting, enabled) => {
   let input = `/users/${userId}/settings/profile-privacy/${profilePrivacySetting}`;
   let init = {
     method: 'PUT',
     body: JSON.stringify(enabled)
   };
-  return Requests.JSONfetch(input, init);
+  return nopaque.requests.JSONfetch(input, init);
 };
 
diff --git a/app/static/js/resource-displays/corpus-display.js b/app/static/js/resource-displays/corpus-display.js
index bf6d258948ae407cf6f32033dc510c8ea92f3898..992328383e587e3929bacc9382908d4a5ce85ce2 100644
--- a/app/static/js/resource-displays/corpus-display.js
+++ b/app/static/js/resource-displays/corpus-display.js
@@ -1,4 +1,4 @@
-ResourceDisplays.CorpusDisplay = class CorpusDisplay extends ResourceDisplays.ResourceDisplay {
+nopaque.resource_displays.CorpusDisplay = class CorpusDisplay extends nopaque.resource_displays.ResourceDisplay {
   static htmlClass = 'corpus-display';
 
   constructor(displayElement) {
@@ -7,7 +7,7 @@ ResourceDisplays.CorpusDisplay = class CorpusDisplay extends ResourceDisplays.Re
     this.displayElement
       .querySelector('.action-button[data-action="build-request"]')
       .addEventListener('click', (event) => {
-        Requests.corpora.entity.build(this.corpusId);
+        nopaque.requests.corpora.entity.build(this.corpusId);
       });
   }
 
diff --git a/app/static/js/resource-displays/index.js b/app/static/js/resource-displays/index.js
index a559189d21bc9950b546ca4f7556d37c9b882233..926f11d630c23471c7e7c54e05745e53536dad71 100644
--- a/app/static/js/resource-displays/index.js
+++ b/app/static/js/resource-displays/index.js
@@ -1,11 +1,11 @@
-var ResourceDisplays = {};
+nopaque.resource_displays = {};
 
-ResourceDisplays.AutoInit = () => {
-  for (let propertyName in ResourceDisplays) {
-    let property = ResourceDisplays[propertyName];
-    // Call autoInit of all properties that are subclasses of `ResourceDisplays.ResourceDisplay`.
-    // This does not include `ResourceDisplays.ResourceDisplay` itself.
-    if (property.prototype instanceof ResourceDisplays.ResourceDisplay) {
+nopaque.resource_displays.AutoInit = () => {
+  for (let propertyName in nopaque.resource_displays) {
+    let property = nopaque.resource_displays[propertyName];
+    // Initialize properties that are subclasses of `nopaque.resource_displays.ResourceDisplay`.
+    // This does not include `nopaque.resource_displays.ResourceDisplay` itself.
+    if (property.prototype instanceof nopaque.resource_displays.ResourceDisplay) {
       // Check if the static `htmlClass` property is defined.
       if (property.htmlClass === undefined) {return;}
       // Gather all HTML elements that have the `this.htmlClass` class
diff --git a/app/static/js/resource-displays/job-display.js b/app/static/js/resource-displays/job-display.js
index 78ebc22c0ccbb6a8ae0acac3a85d62ad86a5eefe..0be3e232126e3ffd4c388098584ee6334992c55d 100644
--- a/app/static/js/resource-displays/job-display.js
+++ b/app/static/js/resource-displays/job-display.js
@@ -1,4 +1,4 @@
-ResourceDisplays.JobDisplay = class JobDisplay extends ResourceDisplays.ResourceDisplay {
+nopaque.resource_displays.JobDisplay = class JobDisplay extends nopaque.resource_displays.ResourceDisplay {
   static htmlClass = 'job-display';
 
   constructor(displayElement) {
diff --git a/app/static/js/resource-displays/resource-display.js b/app/static/js/resource-displays/resource-display.js
index 39401d2bdd26961c16e188b9b7d0ed8039b3826a..23763ca9797b10b67a1d871bb6019f7b7c50d80d 100644
--- a/app/static/js/resource-displays/resource-display.js
+++ b/app/static/js/resource-displays/resource-display.js
@@ -1,4 +1,4 @@
-ResourceDisplays.ResourceDisplay = class ResourceDisplay {
+nopaque.resource_displays.ResourceDisplay = class ResourceDisplay {
   static htmlClass;
 
   constructor(displayElement) {
diff --git a/app/static/js/resource-lists/admin-user-list.js b/app/static/js/resource-lists/admin-user-list.js
index 40feab2790703b7564df19780c4aee716ce65777..3b7f0ac46e7a26a89ac1145a4a52645331573110 100644
--- a/app/static/js/resource-lists/admin-user-list.js
+++ b/app/static/js/resource-lists/admin-user-list.js
@@ -1,4 +1,4 @@
-ResourceLists.AdminUserList = class AdminUserList extends ResourceLists.ResourceList {
+nopaque.resource_lists.AdminUserList = class AdminUserList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'admin-user-list';
 
   constructor(listContainerElement, options = {}) {
@@ -37,9 +37,9 @@ ResourceLists.AdminUserList = class AdminUserList extends ResourceLists.Resource
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('user-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('user-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
@@ -87,7 +87,7 @@ ResourceLists.AdminUserList = class AdminUserList extends ResourceLists.Resource
     let listAction = listActionElement === null ? 'view' : listActionElement.dataset.listAction;
     switch (listAction) {
       case 'delete': {
-        Requests.users.entity.delete(itemId);
+        nopaque.requests.users.entity.delete(itemId);
         if (itemId === currentUserId) {window.location.href = '/';}
         break;
       }
diff --git a/app/static/js/resource-lists/corpus-file-list.js b/app/static/js/resource-lists/corpus-file-list.js
index 7e6a5da9c570debee16b4dad1ab38567d98ff7a0..e1aed5181453f3d399a835b332fe21910fbdf4ed 100644
--- a/app/static/js/resource-lists/corpus-file-list.js
+++ b/app/static/js/resource-lists/corpus-file-list.js
@@ -1,4 +1,4 @@
-ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.ResourceList {
+nopaque.resource_lists.CorpusFileList = class CorpusFileList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'corpus-file-list';
 
   constructor(listContainerElement, options = {}) {
@@ -62,9 +62,9 @@ ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.Resour
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('corpus-file-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('corpus-file-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
@@ -121,7 +121,7 @@ ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.Resour
     switch (listAction) {
       case 'delete': {
         let values = this.listjs.get('id', itemId)[0].values();
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -149,12 +149,12 @@ ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.Resour
         let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
         confirmElement.addEventListener('click', (event) => {
           if (currentUserId != this.userId) {
-            Requests.corpora.entity.files.ent.delete(this.corpusId, itemId)
+            nopaque.requests.corpora.entity.files.ent.delete(this.corpusId, itemId)
             .then(() => {
               window.location.reload();
             });
           } else {
-            Requests.corpora.entity.files.ent.delete(this.corpusId, itemId)
+            nopaque.requests.corpora.entity.files.ent.delete(this.corpusId, itemId)
           }
         });
         modal.open();
@@ -208,7 +208,7 @@ ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.Resour
         break;
       }
       case 'delete': {
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -229,7 +229,7 @@ ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.Resour
         this.selectedItemIds.forEach(selectedItemId => {
           let listItem = this.listjs.get('id', selectedItemId)[0].elm;
           let values = this.listjs.get('id', listItem.dataset.id)[0].values();
-          let itemElement = Utils.HTMLToElement(`<li> - ${values.title}</li>`);
+          let itemElement = nopaque.Utils.HTMLToElement(`<li> - ${values.title}</li>`);
           itemList.appendChild(itemElement);
         });
         let modal = M.Modal.init(
@@ -246,12 +246,12 @@ ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.Resour
         confirmElement.addEventListener('click', (event) => {
           this.selectedItemIds.forEach(selectedItemId => {
             if (currentUserId != this.userId) {
-              Requests.corpora.entity.files.ent.delete(this.corpusId, selectedItemId)
+              nopaque.requests.corpora.entity.files.ent.delete(this.corpusId, selectedItemId)
               .then(() => {
                 window.location.reload();
               });
             } else {
-              Requests.corpora.entity.files.ent.delete(this.corpusId, selectedItemId);
+              nopaque.requests.corpora.entity.files.ent.delete(this.corpusId, selectedItemId);
             }
           });
           this.selectedItemIds.clear();
diff --git a/app/static/js/resource-lists/corpus-follower-list.js b/app/static/js/resource-lists/corpus-follower-list.js
index d56364675012236f30105aeb5c2a209b6b550981..ad7154dc3310087c30d732331835dd616131bf34 100644
--- a/app/static/js/resource-lists/corpus-follower-list.js
+++ b/app/static/js/resource-lists/corpus-follower-list.js
@@ -1,4 +1,4 @@
-ResourceLists.CorpusFollowerList = class CorpusFollowerList extends ResourceLists.ResourceList {
+nopaque.resource_lists.CorpusFollowerList = class CorpusFollowerList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'corpus-follower-list';
 
   constructor(listContainerElement, options = {}) {
@@ -68,9 +68,9 @@ ResourceLists.CorpusFollowerList = class CorpusFollowerList extends ResourceList
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('corpus-follower-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('corpus-follower-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
@@ -120,7 +120,7 @@ ResourceLists.CorpusFollowerList = class CorpusFollowerList extends ResourceList
       case 'update-role': {
         let followerId = listItemElement.dataset.followerId;
         let roleName = event.target.value;
-        Requests.corpora.entity.followers.entity.role.update(this.corpusId, followerId, roleName);
+        nopaque.requests.corpora.entity.followers.entity.role.update(this.corpusId, followerId, roleName);
         break;
       }
       default: {
@@ -140,12 +140,12 @@ ResourceLists.CorpusFollowerList = class CorpusFollowerList extends ResourceList
       case 'unfollow-request': {
         let followerId = listItemElement.dataset.followerId;
         if (currentUserId != this.userId) {
-          Requests.corpora.entity.followers.entity.delete(this.corpusId, followerId)
+          nopaque.requests.corpora.entity.followers.entity.delete(this.corpusId, followerId)
             .then(() => {
               window.location.reload();
             });
         } else {
-          Requests.corpora.entity.followers.entity.delete(this.corpusId, followerId);
+          nopaque.requests.corpora.entity.followers.entity.delete(this.corpusId, followerId);
         }
         break;
       }
diff --git a/app/static/js/resource-lists/corpus-list.js b/app/static/js/resource-lists/corpus-list.js
index f4289d8b9e8d0fa619ff2bd0b22ec469207c17f7..989cd17f1a344ffe67fb6a6dc6ecbd3406ea8935 100644
--- a/app/static/js/resource-lists/corpus-list.js
+++ b/app/static/js/resource-lists/corpus-list.js
@@ -1,4 +1,4 @@
-ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
+nopaque.resource_lists.CorpusList = class CorpusList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'corpus-list';
 
   constructor(listContainerElement, options = {}) {
@@ -93,9 +93,9 @@ ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('corpus-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('corpus-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
@@ -139,7 +139,7 @@ ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
     switch (listAction) {
       case 'delete-request': {
         let values = this.listjs.get('id', itemId)[0].values();
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -167,12 +167,12 @@ ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
         let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
         confirmElement.addEventListener('click', (event) => {
           if (!values['is-owner']) {
-            Requests.corpora.entity.followers.entity.delete(itemId, currentUserId)
+            nopaque.requests.corpora.entity.followers.entity.delete(itemId, currentUserId)
               .then((response) => {
                 window.location.reload();
               });
           } else {
-            Requests.corpora.entity.delete(itemId);
+            nopaque.requests.corpora.entity.delete(itemId);
           }
         });
         modal.open();
@@ -224,7 +224,7 @@ ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
         // Saved for future use:
         // <p class="hide">Do you really want to unfollow this Corpora?</p>
         // <ul id="selected-unfollow-items-list"></ul>
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -245,7 +245,7 @@ ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
         this.selectedItemIds.forEach(selectedItemId => {
           let listItem = this.listjs.get('id', selectedItemId)[0].elm;
           let values = this.listjs.get('id', listItem.dataset.id)[0].values();
-          let itemElement = Utils.HTMLToElement(`<li> - ${values.title}</li>`);
+          let itemElement = nopaque.Utils.HTMLToElement(`<li> - ${values.title}</li>`);
           // if (!values['is-owner']) { 
           //   itemUnfollowList.appendChild(itemElement);
           // } else {
@@ -268,9 +268,9 @@ ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
             let listItem = this.listjs.get('id', selectedItemId)[0].elm;
             let values = this.listjs.get('id', listItem.dataset.id)[0].values();
             if (values['is-owner']) {
-              Requests.corpora.entity.delete(selectedItemId);
+              nopaque.requests.corpora.entity.delete(selectedItemId);
             } else {
-              Requests.corpora.entity.followers.entity.delete(selectedItemId, currentUserId);
+              nopaque.requests.corpora.entity.followers.entity.delete(selectedItemId, currentUserId);
               setTimeout(() => {
                 window.location.reload();
               }, 1000);
diff --git a/app/static/js/resource-lists/corpus-text-info-list.js b/app/static/js/resource-lists/corpus-text-info-list.js
index e24502a0f5188f1938cda7ca582a4f29e42c23c4..9b6c4805cf60f5c2b497b964be7a9d41acf706d1 100644
--- a/app/static/js/resource-lists/corpus-text-info-list.js
+++ b/app/static/js/resource-lists/corpus-text-info-list.js
@@ -1,4 +1,4 @@
-ResourceLists.CorpusTextInfoList = class CorpusTextInfoList extends ResourceLists.ResourceList {
+nopaque.resource_lists.CorpusTextInfoList = class CorpusTextInfoList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'corpus-text-info-list';
 
   static defaultOptions = {
@@ -6,8 +6,8 @@ ResourceLists.CorpusTextInfoList = class CorpusTextInfoList extends ResourceList
   };
 
   constructor(listContainerElement, options = {}) {
-    let _options = Utils.mergeObjectsDeep(
-      ResourceLists.CorpusTextInfoList.defaultOptions,
+    let _options = nopaque.Utils.mergeObjectsDeep(
+      nopaque.resource_lists.CorpusTextInfoList.defaultOptions,
       options
     );
     super(listContainerElement, _options);
@@ -49,9 +49,9 @@ ResourceLists.CorpusTextInfoList = class CorpusTextInfoList extends ResourceList
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('corpus-file-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('corpus-file-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
diff --git a/app/static/js/resource-lists/corpus-token-list.js b/app/static/js/resource-lists/corpus-token-list.js
index eddd82ea35f0c1c44745fc84d4ddf3fe73202ac6..3819fd742556335e10f978854108b4b4811f5cd5 100644
--- a/app/static/js/resource-lists/corpus-token-list.js
+++ b/app/static/js/resource-lists/corpus-token-list.js
@@ -1,4 +1,4 @@
-ResourceLists.CorpusTokenList = class CorpusTokenList extends ResourceLists.ResourceList {
+nopaque.resource_lists.CorpusTokenList = class CorpusTokenList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'corpus-token-list';
 
   static defaultOptions = {
@@ -6,8 +6,8 @@ ResourceLists.CorpusTokenList = class CorpusTokenList extends ResourceLists.Reso
   };
 
   constructor(listContainerElement, options = {}) {
-    let _options = Utils.mergeObjectsDeep(
-      ResourceLists.CorpusTokenList.defaultOptions,
+    let _options = nopaque.Utils.mergeObjectsDeep(
+      nopaque.resource_lists.CorpusTokenList.defaultOptions,
       options
     );
     super(listContainerElement, _options);
@@ -72,9 +72,9 @@ ResourceLists.CorpusTokenList = class CorpusTokenList extends ResourceLists.Reso
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('corpus-token-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('corpus-token-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
diff --git a/app/static/js/resource-lists/detailed-public-corpus-list.js b/app/static/js/resource-lists/detailed-public-corpus-list.js
index e855e07b6c926811aeb5122668ea8a4dc127f958..c4376ae68f9edc7076d86e72b0f55f9bd6a88243 100644
--- a/app/static/js/resource-lists/detailed-public-corpus-list.js
+++ b/app/static/js/resource-lists/detailed-public-corpus-list.js
@@ -1,4 +1,4 @@
-ResourceLists.DetailedPublicCorpusList = class DetailedPublicCorpusList extends ResourceLists.ResourceList {
+nopaque.resource_lists.DetailedPublicCorpusList = class DetailedPublicCorpusList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'detailed-public-corpus-list';
 
   get item() {
@@ -32,9 +32,9 @@ ResourceLists.DetailedPublicCorpusList = class DetailedPublicCorpusList extends
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('corpus-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('corpus-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
diff --git a/app/static/js/resource-lists/index.js b/app/static/js/resource-lists/index.js
index 1683a6a5a92e811490b2cab2bb04744084f4e269..c40fc5143f77747ab276a58bdd7a6b18a1c45a4c 100644
--- a/app/static/js/resource-lists/index.js
+++ b/app/static/js/resource-lists/index.js
@@ -1,11 +1,11 @@
-var ResourceLists = {};
+nopaque.resource_lists = {};
 
-ResourceLists.AutoInit = () => {
-  for (let propertyName in ResourceLists) {
-    let property = ResourceLists[propertyName];
-    // Call autoInit of all properties that are subclasses of `ResourceLists.ResourceList`.
-    // This does not include `ResourceLists.ResourceList` itself.
-    if (property.prototype instanceof ResourceLists.ResourceList) {
+nopaque.resource_lists.AutoInit = () => {
+  for (let propertyName in nopaque.resource_lists) {
+    let property = nopaque.resource_lists[propertyName];
+    // Initialize properties that are subclasses of `nopaque.resource_lists.ResourceList`.
+    // This does not include `nopaque.resource_lists.ResourceList` itself.
+    if (property.prototype instanceof nopaque.resource_lists.ResourceList) {
       // Check if the static `htmlClass` property is defined.
       if (property.htmlClass === undefined) {return;}
       // Gather all HTML elements that have the `this.htmlClass` class
diff --git a/app/static/js/resource-lists/job-input-list.js b/app/static/js/resource-lists/job-input-list.js
index 609702b504799ba014ca39d5f3c988481d000af1..270c6d2d67e9c83628467ac263abbf7fc9ffcedc 100644
--- a/app/static/js/resource-lists/job-input-list.js
+++ b/app/static/js/resource-lists/job-input-list.js
@@ -1,4 +1,4 @@
-ResourceLists.JobInputList = class JobInputList extends ResourceLists.ResourceList {
+nopaque.resource_lists.JobInputList = class JobInputList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'job-input-list';
 
   constructor(listContainerElement, options = {}) {
@@ -36,9 +36,9 @@ ResourceLists.JobInputList = class JobInputList extends ResourceLists.ResourceLi
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('job-input-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('job-input-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
diff --git a/app/static/js/resource-lists/job-list.js b/app/static/js/resource-lists/job-list.js
index c751e7052a7e23a0a925a36a75cf2981e4ce5aec..95140ef2adae0c442bbe663f827a72370c9b86ea 100644
--- a/app/static/js/resource-lists/job-list.js
+++ b/app/static/js/resource-lists/job-list.js
@@ -1,4 +1,4 @@
-ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
+nopaque.resource_lists.JobList = class JobList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'job-list';
 
   constructor(listContainerElement, options = {}) {
@@ -56,9 +56,9 @@ ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('job-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('job-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
@@ -112,7 +112,7 @@ ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
     switch (listAction) {
       case 'delete-request': {
         let values = this.listjs.get('id', itemId)[0].values();
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -139,7 +139,7 @@ ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
         );
         let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
         confirmElement.addEventListener('click', (event) => {
-          Requests.jobs.entity.delete(itemId);
+          nopaque.requests.jobs.entity.delete(itemId);
         });
         modal.open();
         break;
@@ -187,7 +187,7 @@ ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
         break;
       }
       case 'delete': {
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -208,7 +208,7 @@ ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
         this.selectedItemIds.forEach(selectedItemId => {
           let listItem = this.listjs.get('id', selectedItemId)[0].elm;
           let values = this.listjs.get('id', listItem.dataset.id)[0].values();
-          let itemElement = Utils.HTMLToElement(`<li> - ${values.title}</li>`);
+          let itemElement = nopaque.Utils.HTMLToElement(`<li> - ${values.title}</li>`);
           itemList.appendChild(itemElement);
         });
         let modal = M.Modal.init(
@@ -224,7 +224,7 @@ ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
         let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
         confirmElement.addEventListener('click', (event) => {
           this.selectedItemIds.forEach(selectedItemId => {
-            Requests.jobs.entity.delete(selectedItemId);
+            nopaque.requests.jobs.entity.delete(selectedItemId);
           });
           this.selectedItemIds.clear();
           this.renderingItemSelection();
diff --git a/app/static/js/resource-lists/job-result-list.js b/app/static/js/resource-lists/job-result-list.js
index e71759a57a4ef35e099d4fc24d71b99de16c66bd..5736901575f54e6ace6befd3fd7f59ceddc40ebd 100644
--- a/app/static/js/resource-lists/job-result-list.js
+++ b/app/static/js/resource-lists/job-result-list.js
@@ -1,4 +1,4 @@
-ResourceLists.JobResultList = class JobResultList extends ResourceLists.ResourceList {
+nopaque.resource_lists.JobResultList = class JobResultList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'job-result-list';
 
   constructor(listContainerElement, options = {}) {
@@ -42,9 +42,9 @@ ResourceLists.JobResultList = class JobResultList extends ResourceLists.Resource
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('job-result-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('job-result-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
diff --git a/app/static/js/resource-lists/public-corpus-list.js b/app/static/js/resource-lists/public-corpus-list.js
index 71eb4fbd8ddd986d1505da132ee6a2c6d661616f..a7ee6b3829927e4bd82f6fdd709ed84b12eb228f 100644
--- a/app/static/js/resource-lists/public-corpus-list.js
+++ b/app/static/js/resource-lists/public-corpus-list.js
@@ -1,4 +1,4 @@
-ResourceLists.PublicCorpusList = class PublicCorpusList extends ResourceLists.ResourceList {
+nopaque.resource_lists.PublicCorpusList = class PublicCorpusList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'public-corpus-list';
 
   constructor(listContainerElement, options = {}) {
@@ -49,9 +49,9 @@ ResourceLists.PublicCorpusList = class PublicCorpusList extends ResourceLists.Re
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('corpus-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('corpus-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
diff --git a/app/static/js/resource-lists/public-user-list.js b/app/static/js/resource-lists/public-user-list.js
index cc56604a4486d05d6d4c0600877461ea5e28fe2b..707e07bd11469739d6125fd1dab867da64b7cfc6 100644
--- a/app/static/js/resource-lists/public-user-list.js
+++ b/app/static/js/resource-lists/public-user-list.js
@@ -1,4 +1,4 @@
-ResourceLists.PublicUserList = class PublicUserList extends ResourceLists.ResourceList {
+nopaque.resource_lists.PublicUserList = class PublicUserList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'public-user-list';
 
   constructor(listContainerElement, options = {}) {
@@ -37,9 +37,9 @@ ResourceLists.PublicUserList = class PublicUserList extends ResourceLists.Resour
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('user-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('user-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
diff --git a/app/static/js/resource-lists/resource-list.js b/app/static/js/resource-lists/resource-list.js
index ba71f03f0685b0ed750a16c7d2ace85bbaf3e035..233628c3bb2ba7b9cf33720997093ccf195e8809 100644
--- a/app/static/js/resource-lists/resource-list.js
+++ b/app/static/js/resource-lists/resource-list.js
@@ -1,4 +1,4 @@
-ResourceLists.ResourceList = class ResourceList {
+nopaque.resource_lists.ResourceList = class ResourceList {
   /* A wrapper class for the list.js list.
    * This class is not meant to be used directly, instead it should be used as
    * a base class for concrete resource list implementations.
@@ -21,9 +21,9 @@ ResourceLists.ResourceList = class ResourceList {
     if ('valueNames' in options) {
       throw '"valueNames" is not supported as an option, define it as a getter in the list class';
     }
-    let _options = Utils.mergeObjectsDeep(
+    let _options = nopaque.Utils.mergeObjectsDeep(
       {item: this.item, valueNames: this.valueNames},
-      ResourceLists.ResourceList.defaultOptions,
+      nopaque.resource_lists.ResourceList.defaultOptions,
       options
     );
     this.listContainerElement = listContainerElement;
diff --git a/app/static/js/resource-lists/spacy-nlp-pipeline-model-list.js b/app/static/js/resource-lists/spacy-nlp-pipeline-model-list.js
index 195fa60c3a57e498418b4a541406b27359c35e85..b41795c1bd88c44824d32da7c05263715048144c 100644
--- a/app/static/js/resource-lists/spacy-nlp-pipeline-model-list.js
+++ b/app/static/js/resource-lists/spacy-nlp-pipeline-model-list.js
@@ -1,4 +1,4 @@
-ResourceLists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelList extends ResourceLists.ResourceList {
+nopaque.resource_lists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'spacy-nlp-pipeline-model-list';
 
   constructor(listContainerElement, options = {}) {
@@ -60,9 +60,9 @@ ResourceLists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelList extend
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('spacy-nlp-pipeline-model-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('spacy-nlp-pipeline-model-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
@@ -116,7 +116,7 @@ ResourceLists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelList extend
     switch (listAction) {
       case 'toggle-is-public': {
         let newIsPublicValue = listActionElement.checked;
-        Requests.contributions.spacy_nlp_pipeline_models.entity.isPublic.update(itemId, newIsPublicValue)
+        nopaque.requests.contributions.spacy_nlp_pipeline_models.entity.isPublic.update(itemId, newIsPublicValue)
           .catch((response) => {
             listActionElement.checked = !newIsPublicValue;
           });
@@ -138,7 +138,7 @@ ResourceLists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelList extend
     switch (listAction) {
       case 'delete-request': {
         let values = this.listjs.get('id', itemId)[0].values();
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -165,7 +165,7 @@ ResourceLists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelList extend
         );
         let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
         confirmElement.addEventListener('click', (event) => {
-          Requests.contributions.spacy_nlp_pipeline_models.entity.delete(itemId);
+          nopaque.requests.contributions.spacy_nlp_pipeline_models.entity.delete(itemId);
         });
         modal.open();
         break;
diff --git a/app/static/js/resource-lists/tesseract-ocr-pipeline-model-list.js b/app/static/js/resource-lists/tesseract-ocr-pipeline-model-list.js
index 975bfe5cc598a769d6fd2f0fba190e63f1fbd55d..5019d3da8828353bcf7538c961e0dabe48c92ae7 100644
--- a/app/static/js/resource-lists/tesseract-ocr-pipeline-model-list.js
+++ b/app/static/js/resource-lists/tesseract-ocr-pipeline-model-list.js
@@ -1,4 +1,4 @@
-ResourceLists.TesseractOCRPipelineModelList = class TesseractOCRPipelineModelList extends ResourceLists.ResourceList {
+nopaque.resource_lists.TesseractOCRPipelineModelList = class TesseractOCRPipelineModelList extends nopaque.resource_lists.ResourceList {
   static htmlClass = 'tesseract-ocr-pipeline-model-list';
 
   constructor(listContainerElement, options = {}) {
@@ -69,9 +69,9 @@ ResourceLists.TesseractOCRPipelineModelList = class TesseractOCRPipelineModelLis
 
   initListContainerElement() {
     if (!this.listContainerElement.hasAttribute('id')) {
-      this.listContainerElement.id = Utils.generateElementId('tesseract-ocr-pipeline-model-list-');
+      this.listContainerElement.id = nopaque.Utils.generateElementId('tesseract-ocr-pipeline-model-list-');
     }
-    let listSearchElementId = Utils.generateElementId(`${this.listContainerElement.id}-search-`);
+    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
     this.listContainerElement.innerHTML = `
       <div class="input-field">
         <i class="material-icons prefix">search</i>
@@ -125,7 +125,7 @@ ResourceLists.TesseractOCRPipelineModelList = class TesseractOCRPipelineModelLis
     switch (listAction) {
       case 'toggle-is-public': {
         let newIsPublicValue = listActionElement.checked;
-        Requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic.update(itemId, newIsPublicValue)
+        nopaque.requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic.update(itemId, newIsPublicValue)
           .catch((response) => {
             listActionElement.checked = !newIsPublicValue;
           });
@@ -147,7 +147,7 @@ ResourceLists.TesseractOCRPipelineModelList = class TesseractOCRPipelineModelLis
     switch (listAction) {
       case 'delete-request': {
         let values = this.listjs.get('id', itemId)[0].values();
-        let modalElement = Utils.HTMLToElement(
+        let modalElement = nopaque.Utils.HTMLToElement(
           `
             <div class="modal">
               <div class="modal-content">
@@ -174,7 +174,7 @@ ResourceLists.TesseractOCRPipelineModelList = class TesseractOCRPipelineModelLis
         );
         let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
         confirmElement.addEventListener('click', (event) => {
-          Requests.contributions.tesseract_ocr_pipeline_models.entity.delete(itemId);
+          nopaque.requests.contributions.tesseract_ocr_pipeline_models.entity.delete(itemId);
         });
         modal.open();
         break;
diff --git a/app/static/js/utils.js b/app/static/js/utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..b73345992d3756ccff1299fbebd24b21256d21d4
--- /dev/null
+++ b/app/static/js/utils.js
@@ -0,0 +1,91 @@
+nopaque.Utils = class Utils {
+  static escape(text) {
+    // https://codereview.stackexchange.com/a/126722
+    let lookup = {
+      '<': 'lt',
+      '>': 'gt',
+      '"': 'quot',
+      '\'': 'apos',
+      '&': 'amp',
+      '\r': '#10',
+      '\n': '#13'
+    };
+
+    return text.toString().replace(/[<>"'\r\n&]/g, (chr) => {
+      return '&' + lookup[chr] + ';';
+    });
+  }
+
+  static unescape(escapedText) {
+    let lookup = {
+      'lt': '<',
+      'gt': '>',
+      'quot': '"',
+      'apos': "'",
+      'amp': '&',
+      '#10': '\r',
+      '#13': '\n'
+    };
+    
+    return escapedText.replace(/&(#?\w+);/g, (match, entity) => {
+      if (lookup.hasOwnProperty(entity)) {
+        return lookup[entity];
+      }
+      
+      return match;
+    });
+  }
+
+  static HTMLToElement(HTMLString) {
+    let templateElement = document.createElement('template');
+    templateElement.innerHTML = HTMLString.trim();
+    return templateElement.content.firstChild;
+  }
+
+  static generateElementId(prefix='', suffix='') {
+    for (let i = 0; true; i++) {
+      if (document.querySelector(`#${prefix}${i}${suffix}`) !== null) {continue;}
+      return `${prefix}${i}${suffix}`;
+    }
+  }
+
+  static isObject(object) {
+    return object !== null && typeof object === 'object' && !Array.isArray(object);
+  }
+
+  static mergeObjectsDeep(...objects) {
+    let mergedObject = {};
+    if (objects.length === 0) {
+      return mergedObject;
+    }
+    if (!this.isObject(objects[0])) {throw 'Cannot merge non-object';}
+    if (objects.length === 1) {
+      return this.mergeObjectsDeep(mergedObject, objects[0]);
+    }
+    if (!this.isObject(objects[1])) {throw 'Cannot merge non-object';}
+    for (let key in objects[0]) {
+      if (objects[0].hasOwnProperty(key)) {
+        if (objects[1].hasOwnProperty(key)) {
+          if (this.isObject(objects[0][key]) && this.isObject(objects[1][key])) {
+            mergedObject[key] = this.mergeObjectsDeep(objects[0][key], objects[1][key]);
+          } else {
+            mergedObject[key] = objects[1][key];
+          }
+        } else {
+          mergedObject[key] = objects[0][key];
+        }
+      }
+    }
+    for (let key in objects[1]) {
+      if (objects[1].hasOwnProperty(key)) {
+        if (!objects[0].hasOwnProperty(key)) {
+          mergedObject[key] = objects[1][key];
+        }
+      }
+    }
+    if (objects.length === 2) {
+      return mergedObject;
+    }
+    return this.mergeObjectsDeep(mergedObject, ...objects.slice(2));
+  }
+}
diff --git a/app/static/js/utils/index.js b/app/static/js/utils/index.js
deleted file mode 100644
index 39d693f5495c21de9d1d2bae22d9a7669b9c39bd..0000000000000000000000000000000000000000
--- a/app/static/js/utils/index.js
+++ /dev/null
@@ -1 +0,0 @@
-Utils = {};
diff --git a/app/static/js/utils/utils.js b/app/static/js/utils/utils.js
deleted file mode 100644
index 17dcde056fd9204e4d66ac0460492bda560e2f4f..0000000000000000000000000000000000000000
--- a/app/static/js/utils/utils.js
+++ /dev/null
@@ -1,89 +0,0 @@
-Utils.escape = (text) => {
-  // https://codereview.stackexchange.com/a/126722
-  var table = {
-    '<': 'lt',
-    '>': 'gt',
-    '"': 'quot',
-    '\'': 'apos',
-    '&': 'amp',
-    '\r': '#10',
-    '\n': '#13'
-  };
-  
-  return text.toString().replace(/[<>"'\r\n&]/g, (chr) => {
-    return '&' + table[chr] + ';';
-  });
-};
-
-Utils.unescape = (escapedText) => {
-  var table = {
-    'lt': '<',
-    'gt': '>',
-    'quot': '"',
-    'apos': "'",
-    'amp': '&',
-    '#10': '\r',
-    '#13': '\n'
-  };
-  
-  return escapedText.replace(/&(#?\w+);/g, (match, entity) => {
-    if (table.hasOwnProperty(entity)) {
-      return table[entity];
-    }
-    
-    return match;
-  });
-};
-
-Utils.HTMLToElement = (HTMLString) => {
-  let templateElement = document.createElement('template');
-  templateElement.innerHTML = HTMLString.trim();
-  return templateElement.content.firstChild;
-};
-
-Utils.generateElementId = (prefix='', suffix='') => {
-  for (let i = 0; true; i++) {
-    if (document.querySelector(`#${prefix}${i}${suffix}`) !== null) {continue;}
-    return `${prefix}${i}${suffix}`;
-  }
-};
-
-Utils.isObject = (object) => {
-  return object !== null && typeof object === 'object' && !Array.isArray(object);
-};
-
-Utils.mergeObjectsDeep = (...objects) => {
-  let mergedObject = {};
-  if (objects.length === 0) {
-    return mergedObject;
-  }
-  if (!Utils.isObject(objects[0])) {throw 'Cannot merge non-object';}
-  if (objects.length === 1) {
-    return Utils.mergeObjectsDeep(mergedObject, objects[0]);
-  }
-  if (!Utils.isObject(objects[1])) {throw 'Cannot merge non-object';}
-  for (let key in objects[0]) {
-    if (objects[0].hasOwnProperty(key)) {
-      if (objects[1].hasOwnProperty(key)) {
-        if (Utils.isObject(objects[0][key]) && Utils.isObject(objects[1][key])) {
-          mergedObject[key] = Utils.mergeObjectsDeep(objects[0][key], objects[1][key]);
-        } else {
-          mergedObject[key] = objects[1][key];
-        }
-      } else {
-        mergedObject[key] = objects[0][key];
-      }
-    }
-  }
-  for (let key in objects[1]) {
-    if (objects[1].hasOwnProperty(key)) {
-      if (!objects[0].hasOwnProperty(key)) {
-        mergedObject[key] = objects[1][key];
-      }
-    }
-  }
-  if (objects.length === 2) {
-    return mergedObject;
-  }
-  return Utils.mergeObjectsDeep(mergedObject, ...objects.slice(2));
-};
diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2
index 63da9c5d90906144921d7532fc4ae5f23a71213d..f361f1dd4425afd4d8c8d16356523d73b7996c22 100644
--- a/app/templates/_scripts.html.j2
+++ b/app/templates/_scripts.html.j2
@@ -7,36 +7,9 @@
 {%- assets
   filters='rjsmin',
   output='gen/app.%(version)s.js',
-  'js/nopaque/index.js',
-  'js/nopaque/app.js'
-%}
-<script src="{{ ASSET_URL }}"></script>
-{%- endassets %}
-
-{%- assets
-  filters='rjsmin',
-  output='gen/utils.%(version)s.js',
-  'js/utils/index.js',
-  'js/utils/utils.js'
-%}
-<script src="{{ ASSET_URL }}"></script>
-{%- endassets %}
-
-{%- assets
-  filters='rjsmin',
-  output='gen/cqi.%(version)s.js',
-  'js/cqi/index.js',
-  'js/cqi/constants.js',
-  'js/cqi/errors.js',
-  'js/cqi/status.js',
-  'js/cqi/api/index.js',
-  'js/cqi/api/client.js',
-  'js/cqi/models/index.js',
-  'js/cqi/models/resource.js',
-  'js/cqi/models/attributes.js',
-  'js/cqi/models/subcorpora.js',
-  'js/cqi/models/corpora.js',
-  'js/cqi/client.js'
+  'js/index.js',
+  'js/app.js',
+  'js/utils.js'
 %}
 <script src="{{ ASSET_URL }}"></script>
 {%- endassets %}
@@ -102,7 +75,20 @@
 
 {%- assets
   filters='rjsmin',
-  output='gen/CorpusAnalysis.%(version)s.js',
+  output='gen/corpus-analysis.%(version)s.js',
+  'js/CorpusAnalysis/index.js',
+  'js/CorpusAnalysis/cqi/index.js',
+  'js/CorpusAnalysis/cqi/constants.js',
+  'js/CorpusAnalysis/cqi/errors.js',
+  'js/CorpusAnalysis/cqi/status.js',
+  'js/CorpusAnalysis/cqi/api/index.js',
+  'js/CorpusAnalysis/cqi/api/client.js',
+  'js/CorpusAnalysis/cqi/models/index.js',
+  'js/CorpusAnalysis/cqi/models/resource.js',
+  'js/CorpusAnalysis/cqi/models/attributes.js',
+  'js/CorpusAnalysis/cqi/models/subcorpora.js',
+  'js/CorpusAnalysis/cqi/models/corpora.js',
+  'js/CorpusAnalysis/cqi/client.js',
   'js/CorpusAnalysis/query-builder/index.js',
   'js/CorpusAnalysis/query-builder/element-references.js',
   'js/CorpusAnalysis/query-builder/general-query-builder-functions.js',
diff --git a/app/templates/admin/corpora.html.j2 b/app/templates/admin/corpora.html.j2
index 3eeb7981491570dae30095105c2fd0dbb66e687d..295013f2dae74029c00fa3c1bd7b6eb4b011be39 100644
--- a/app/templates/admin/corpora.html.j2
+++ b/app/templates/admin/corpora.html.j2
@@ -17,7 +17,7 @@
 {{ super() }}
 <script>
   let corpusListElement = document.querySelector('#corpus-list');
-  let corpusList = new ResourceLists.CorpusList(corpusListElement);
+  let corpusList = new nopaque.resource_lists.CorpusList(corpusListElement);
   corpusList.add(
     [
       {% for corpus in corpora %}
diff --git a/app/templates/admin/user_settings.html.j2 b/app/templates/admin/user_settings.html.j2
index fb022564b9cfc357c1ffea3f8d050a7f03e98ef6..17fdc151f1fff920cb5d6bed7b37ba7acf510b0b 100644
--- a/app/templates/admin/user_settings.html.j2
+++ b/app/templates/admin/user_settings.html.j2
@@ -57,7 +57,7 @@
 let userConfirmedSwitchElement = document.querySelector('#user-confirmed-switch');
 userConfirmedSwitchElement.addEventListener('change', (event) => {
   let newConfirmed = userConfirmedSwitchElement.checked;
-  Requests.admin.users.entity.confirmed.update({{ user.hashid|tojson }}, newConfirmed)
+  nopaque.requests.admin.users.entity.confirmed.update({{ user.hashid|tojson }}, newConfirmed)
     .catch((response) => {
       userConfirmedSwitchElement.checked = !userConfirmedSwitchElement;
     });
diff --git a/app/templates/admin/users.html.j2 b/app/templates/admin/users.html.j2
index 94833b61d1c97cde11e80ac0c6e0d051218b44e1..eccdd4f47c4e774df7b8c1ba8829c8ccd3481f67 100644
--- a/app/templates/admin/users.html.j2
+++ b/app/templates/admin/users.html.j2
@@ -22,7 +22,7 @@
 {{ super() }}
 <script>
   let adminUserListElement = document.querySelector('#admin-user-list');
-  let adminUserList = new ResourceLists.AdminUserList(adminUserListElement);
+  let adminUserList = new nopaque.resource_lists.AdminUserList(adminUserListElement);
   adminUserList.add(
     [
       {% for user in users %}
diff --git a/app/templates/corpora/corpus.html.j2 b/app/templates/corpora/corpus.html.j2
index 978b87bb7678722ebe47177640895859de9fe5a7..b01331699636d27ef6ff1b89e5890b9f24e7fd93 100644
--- a/app/templates/corpora/corpus.html.j2
+++ b/app/templates/corpora/corpus.html.j2
@@ -240,7 +240,7 @@
 {% if current_user.is_following_corpus(corpus) %}
   let unfollowRequestElement = document.querySelector('.action-button[data-action="unfollow-request"]');
   unfollowRequestElement.addEventListener('click', () => {
-    Requests.corpora.entity.followers.entity.delete({{ corpus.hashid|tojson }}, {{ current_user.hashid|tojson }})
+    nopaque.requests.corpora.entity.followers.entity.delete({{ corpus.hashid|tojson }}, {{ current_user.hashid|tojson }})
       .then((response) => {
         window.location.reload();
       });
@@ -252,7 +252,7 @@
 let publishingModalIsPublicSwitchElement = document.querySelector('#publishing-modal-is-public-switch');
 publishingModalIsPublicSwitchElement.addEventListener('change', (event) => {
   let newIsPublic = publishingModalIsPublicSwitchElement.checked;
-  Requests.corpora.entity.isPublic.update({{ corpus.hashid|tojson }}, newIsPublic)
+  nopaque.requests.corpora.entity.isPublic.update({{ corpus.hashid|tojson }}, newIsPublic)
     .catch((response) => {
       publishingModalIsPublicSwitchElement.checked = !newIsPublic;
     });
@@ -262,7 +262,7 @@ publishingModalIsPublicSwitchElement.addEventListener('change', (event) => {
 // #region Delete
 let deleteModalDeleteButtonElement = document.querySelector('#delete-modal-delete-button');
 deleteModalDeleteButtonElement.addEventListener('click', (event) => {
-  Requests.corpora.entity.delete({{ corpus.hashid|tojson }})
+  nopaque.requests.corpora.entity.delete({{ corpus.hashid|tojson }})
     .then((response) => {
       window.location.href = {{ url_for('main.dashboard')|tojson }};
     });
@@ -312,7 +312,7 @@ M.Modal.init(
 
 inviteUserModalInviteButtonElement.addEventListener('click', (event) => {
   let usernames = inviteUserModalSearch.chipsData.map((chipData) => chipData.tag);
-  Requests.corpora.entity.followers.add({{ corpus.hashid|tojson }}, usernames);
+  nopaque.requests.corpora.entity.followers.add({{ corpus.hashid|tojson }}, usernames);
 });
 // #endregion Invite user
 
@@ -357,7 +357,7 @@ M.Modal.init(
 shareLinkModalCreateButtonElement.addEventListener('click', (event) => {
   let role = shareLinkModalCorpusFollowerRoleSelectElement.value;
   let expiration = shareLinkModalExpirationDateDatepickerElement.value
-  Requests.corpora.entity.generateShareLink({{ corpus.hashid|tojson }}, role, expiration)
+  nopaque.requests.corpora.entity.generateShareLink({{ corpus.hashid|tojson }}, role, expiration)
     .then((response) => {
       response.json()
         .then((json) => {
diff --git a/app/templates/corpora/public_corpus.html.j2 b/app/templates/corpora/public_corpus.html.j2
index c28fe926233fbd04661f8f40634b1966ed1e1ea9..5c6556c8ac4fe07d3c047af425bcb15392c7cc41 100644
--- a/app/templates/corpora/public_corpus.html.j2
+++ b/app/templates/corpora/public_corpus.html.j2
@@ -242,7 +242,7 @@
 {{ super() }}
 <script>
 
-let publicCorpusFileList = new ResourceLists.CorpusFileList(document.querySelector('#corpus-file-list'));
+let publicCorpusFileList = new nopaque.resource_lists.CorpusFileList(document.querySelector('#corpus-file-list'));
 publicCorpusFileList.add(
   [
     {% for corpus_file in corpus.files %}
@@ -259,7 +259,7 @@ refreshButton.addEventListener('click', () => {
 {% endif %}
 
 {% if cfr.has_permission('MANAGE_FOLLOWERS') %}
-let publicCorpusFollowerList = new ResourceLists.CorpusFollowerList(document.querySelector('.corpus-follower-list'));
+let publicCorpusFollowerList = new nopaque.resource_lists.CorpusFollowerList(document.querySelector('.corpus-follower-list'));
 publicCorpusFollowerList.add(
   [
     {% for cfa in cfas %}
diff --git a/app/templates/main/social_area.html.j2 b/app/templates/main/social_area.html.j2
index 872365cc1b8eefe8fd2fba2c7b4e79137195fb60..35262f5334f5532cb23f9cc91b1c167042e27915 100644
--- a/app/templates/main/social_area.html.j2
+++ b/app/templates/main/social_area.html.j2
@@ -50,7 +50,6 @@
       <p>Find public corpora.</p>
       <div class="card">
         <div class="card-content">
-          <span class="card-title">Public Corpora</span>
           <div id="public-corpus-list"></div>
         </div>
       </div>
@@ -63,7 +62,7 @@
 {{ super() }}
 <script>
   let publicUserListElement = document.querySelector('#public-user-list');
-  let publicUserList = new ResourceLists.PublicUserList(publicUserListElement);
+  let publicUserList = new nopaque.resource_lists.PublicUserList(publicUserListElement);
   publicUserList.add(
     [
       {% for user in users %}
@@ -73,7 +72,7 @@
   );
 
   let publicCorpusListElement = document.querySelector('#public-corpus-list');
-  let publicCorpusList = new ResourceLists.PublicCorpusList(publicCorpusListElement);
+  let publicCorpusList = new nopaque.resource_lists.PublicCorpusList(publicCorpusListElement);
   publicCorpusList.add(
     [
       {% for corpus in corpora %}
diff --git a/app/templates/users/settings/settings.html.j2 b/app/templates/users/settings/settings.html.j2
index 4e52344a396c6bb483f3870c3f254f390b149df8..34fa4f791f1eae8f4638da597868b14bf21e27f4 100644
--- a/app/templates/users/settings/settings.html.j2
+++ b/app/templates/users/settings/settings.html.j2
@@ -221,7 +221,7 @@ avatarUploadElement.addEventListener('change', () => {
 });
 
 document.querySelector('#delete-avatar').addEventListener('click', () => {
-  Requests.users.entity.avatar.delete({{ user.hashid|tojson }})
+  nopaque.requests.users.entity.avatar.delete({{ user.hashid|tojson }})
     .then(
       (response) => {
         avatarPreviewElement.src = {{ url_for('static', filename='images/user_avatar.png')|tojson }};
@@ -230,7 +230,7 @@ document.querySelector('#delete-avatar').addEventListener('click', () => {
 });
 
 document.querySelector('#delete-user').addEventListener('click', (event) => {
-  Requests.users.entity.delete({{ user.hashid|tojson }})
+  nopaque.requests.users.entity.delete({{ user.hashid|tojson }})
     .then((response) => {window.location.href = '/';});
 });
 
@@ -255,7 +255,7 @@ let profileIsPublicSwitchElement = document.querySelector('#profile-is-public-sw
 let profilePrivacySettingCheckboxElements = document.querySelectorAll('.profile-privacy-setting-checkbox');
 profileIsPublicSwitchElement.addEventListener('change', (event) => {
   let newEnabled = profileIsPublicSwitchElement.checked;
-  Requests.users.entity.settings.profilePrivacy.update({{ user.hashid|tojson }}, 'is-public', newEnabled)
+  nopaque.requests.users.entity.settings.profilePrivacy.update({{ user.hashid|tojson }}, 'is-public', newEnabled)
     .then(
       (response) => {
         for (let profilePrivacySettingCheckboxElement of document.querySelectorAll('.profile-privacy-setting-checkbox')) {
@@ -271,7 +271,7 @@ for (let profilePrivacySettingCheckboxElement of profilePrivacySettingCheckboxEl
   profilePrivacySettingCheckboxElement.addEventListener('change', (event) => {
     let newEnabled = profilePrivacySettingCheckboxElement.checked;
     let valueName = profilePrivacySettingCheckboxElement.dataset.profilePrivacySettingName;
-    Requests.users.entity.settings.profilePrivacy.update({{ user.hashid|tojson }}, valueName, newEnabled)
+    nopaque.requests.users.entity.settings.profilePrivacy.update({{ user.hashid|tojson }}, valueName, newEnabled)
       .catch((response) => {
         profilePrivacySettingCheckboxElement.checked = !newEnabled;
       });
diff --git a/app/templates/users/user.html.j2 b/app/templates/users/user.html.j2
index 0ab23035e169c4a759b843ecf95a2b5d795722a5..41054eb642475407d9db4512a4ec9c787acdee80 100644
--- a/app/templates/users/user.html.j2
+++ b/app/templates/users/user.html.j2
@@ -122,7 +122,7 @@
 {% block scripts %}
 {{ super() }}
 <script>
-let followedCorpusList = new ResourceLists.PublicCorpusList(document.querySelector('.followed-corpus-list'));
+let followedCorpusList = new nopaque.resource_lists.PublicCorpusList(document.querySelector('.followed-corpus-list'));
 followedCorpusList.add(
   [
     {% for corpus in user.followed_corpora %}
@@ -132,7 +132,7 @@ followedCorpusList.add(
     {% endfor %}
   ]
 );
-let publicCorpusList = new ResourceLists.PublicCorpusList(document.querySelector('.public-corpus-list'));
+let publicCorpusList = new nopaque.resource_lists.PublicCorpusList(document.querySelector('.public-corpus-list'));
 publicCorpusList.add(
   [
     {% for corpus in user.corpora %}