derekovecs: start outsourcing js from html-template to .js scripts
diff --git a/js/derekovcs.js b/js/derekovcs.js
index d2ed5b5..31f238b 100644
--- a/js/derekovcs.js
+++ b/js/derekovcs.js
@@ -14,3 +14,157 @@
         return false;
     }
 }
+
+
+function makeVocabDistanceTable(id, baseURL) {
+  var urlprefix =  new URLSearchParams(window.location.search);
+  return $(id).DataTable({
+    ajax: {
+      method: "GET",
+      url: baseURL + '/getBiggestVocabDistances',
+      dataType: 'json',
+      dataSrc: function (result) {
+        return result;
+      },
+      timeout: 30000,
+    },
+    "initComplete":function(settings, json){
+      vocabDistanceTable.columns.adjust().draw();
+    },
+    "createdRow": function (row, data, rowIndex) {
+      $.each($('td.collocator', row), function (colIndex) {
+        $(this).attr('title', "f("+data.word+")="+data.f2.toLocaleString("en-GB") + " f1: "+ccResult.f1+ " total: "+ccResult.N);
+      });
+    },
+    "sScrollY": "780px",
+    "bScrollCollapse": true,
+    "bPaginate": false,
+    "bJQueryUI": true,
+    "dom": '<"top">rt<"bottom"flp><"clear">',
+    "columns": [
+      { "data": "rank", type: "allnumeric" },
+      { "data": "dist",  render: function ( data, type, row ) {return data.toFixed(3) }},
+      { "data": "word",  class: "paradigmator", render: function ( data, type, row ) {
+        urlprefix.set("word", data); return  '<a class="' + getMergedClass(row.rank) + '" href="?' + urlprefix + '">' + data + '</a>' 
+      }}
+    ],
+    "columnDefs": [
+      { className: "dt-right", "targets": [0,1] },
+      { "searchable": false,
+        "orderable": false,
+        "targets": 0
+      },
+      { "orderSequence": [ "desc" ], "targets": [ 1 ] },
+      { "orderSequence": [ "asc", "desc" ], "targets": [ 2 ] },
+    ],
+    "oLanguage": {
+      "sSearch": "Filter: "
+    },
+    "order": [[ 1, 'desc' ]]
+  });
+}
+
+function toFixed(n, d) {
+  if(typeof n != "number") {
+    return n;
+  } else {
+    return n.toFixed(d);
+  }
+}
+
+function toExponential(n, d) {
+  if(typeof n != "number") {
+    return n;
+  } else {
+    return n.toExponential(d);
+  }
+}
+
+function bitmask2window(autofocus, win) {
+  var af_str = autofocus.toString(2).padStart(10, "0")
+    .replace(/^([0-9]{5})/, '$1 ')
+    .replace(/0/g, '·')
+    .replace(/1/g, '◼');
+  var w_str = win.toString(2).padStart(10, "0")
+    .replace(/^([0-9]{5})/, '$1 ')
+    .replace(/0/g, '·')
+    .replace(/1/g, 'o');
+  for (var i=0, l=af_str.length; i<l; i++) {
+    if(af_str.charAt(i) == '·' && w_str.charAt(i) == 'o' ) {
+      af_str = af_str.substring(0, i) + "◽" + af_str.substring(i+1);
+    }
+  }
+  return af_str;
+}
+
+function makeClassicCollocatorTable(id, baseURL, wordIndex) {
+  var classicCollocatorTable = $('#classicoloctable').DataTable({
+    ajax: {
+      method: "GET",
+      url: baseURL + '/getClassicCollocators',
+      dataType: 'json',
+      dataSrc: function (result) {
+        ccResult = result;
+        $("#rawfreq_tt").attr("title", "Raw frequencies of the co-occurence.\n"
+                              + "f(" + ccResult.w1+")=" + ccResult.f1.toLocaleString("en-GB") + ";\n"
+                              + "N=" + ccResult.N.toLocaleString("en-GB"));
+        return result.collocates;
+      },
+      timeout: 30000,
+      data: { w: wordIndex }
+    },
+    "initComplete":function(settings, json){
+      $("td.collocator").click(function(){
+        queryKorAPCII(this.textContent + " /w5 " + CIIsearchWords);
+      });
+      classicCollocatorTable.columns(".detail").visible(false);
+      $("#ccd").css('width', '680px');
+      classicCollocatorTable.columns.adjust().draw();
+    },
+    "createdRow": function (row, data, rowIndex) {
+      $.each($('td.collocator', row), function (colIndex) {
+        $(this).attr('title', "f("+data.word+")="+data.f2.toLocaleString("en-GB") + " f1: "+ccResult.f1+ " total: "+ccResult.N);
+      });
+    },
+    "sScrollY": "780px",
+    "bScrollCollapse": true,
+    "bPaginate": false,
+    "bJQueryUI": true,
+    "dom": '<"top">rt<"bottom"flp><"clear">',
+    "columns": [
+      //                      { "data": "pos", width: "7%", sClass: "dt-center mono compact", render: function ( data, type, row ) {return bitvec2window(data, row.heat, row.word) }},
+      { "data": "llr",  render: function ( data, type, row ) {return toFixed(data, 0) }},
+      { "data": "pmi", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      { "data": "md", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      { "data": "lfmd", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      //             { "data": "fpmi", type: "scientific", render: function ( data, type, row ) {return data.toExponential(2) }  },
+      { "data": "npmi", render: function ( data, type, row ) {return toFixed(data, 3) }},
+      { "data": "dice", render: function ( data, type, row ) {return toExponential(data, 2) }},
+      { "data": "ld", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      { "data": "af", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      { "data": "delta", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      { "data": "afwin", width: "auto", sClass: "dt-center mono compact", render: function ( data, type, row ) {return bitmask2window(data, row.win) }},
+      { "data": "llfmd", render: function ( data, type, row ) {return toFixed(data, 1) }},
+      { "data": "rlfmd", render: function ( data, type, row ) {return toFixed(data, 1) }},
+      { "data": "lnpmi", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      { "data": "rnpmi", render: function ( data, type, row ) {return toFixed(data, 2) }},
+      { "data": "f" },
+      { "data": "word",  sClass: "collocator" }
+    ],
+    "columnDefs": [
+      { className: "dt-right", "targets": [0,1,2,3,4,5,6,7,8,10,11,12,13,14] },
+      { className: "dt-right detail", "targets": [5,10,11,12,13] },
+      { "searchable": false,
+        "orderable": false,
+        "targets": []
+      },
+      { "orderSequence": [ "desc" ], "targets": [0,1,2,3,4,5,6,7,10,11,12,13,14] },
+      { "orderSequence": [ "asc", "desc" ], "targets": [8,9,15] },
+    ],
+    "oLanguage": {
+      "sSearch": "Filter: "
+    },
+    "order": [[ 7, 'desc' ]],
+  });
+  return classicCollocatorTable;
+}
diff --git a/templates/index.html.ep b/templates/index.html.ep
index 418fdc7..5c38c77 100644
--- a/templates/index.html.ep
+++ b/templates/index.html.ep
@@ -44,7 +44,7 @@
          function () {
            MathJax.Hub.Queue(
              ["Typeset",MathJax.Hub,"ccd"],
-             function () {                
+             function () {
                $("#mi_tt").attr("title",$("#pmi_ttt").html());
                $("#lfmd_tt").attr("title",$("#lfmd_ttt").html());
                $("#md_tt").attr("title",$("#md_ttt").html());
@@ -111,23 +111,6 @@
          return ["hsl(",hue,",90%,70%)"].join("");
        }
 
-       function bitmask2window(autofocus, win) {
-         var af_str = autofocus.toString(2).padStart(10, "0")
-                               .replace(/^([0-9]{5})/, '$1 ')
-                               .replace(/0/g, '·')
-                               .replace(/1/g, '◼');
-         var w_str = win.toString(2).padStart(10, "0")
-                        .replace(/^([0-9]{5})/, '$1 ')
-                        .replace(/0/g, '·')
-                        .replace(/1/g, 'o');
-         for (var i=0, l=af_str.length; i<l; i++) {
-           if(af_str.charAt(i) == '·' && w_str.charAt(i) == 'o' ) {
-             af_str = af_str.substring(0, i) + "◽" + af_str.substring(i+1);
-           }
-         }
-         return af_str;
-       }
-
        function bitvec2window(n, heat, word) {
          var str = n.toString(2).padStart(10, "0")
                     .replace(/^([0-9]{5})/, '$1x')
@@ -136,22 +119,6 @@
          return changeCharColor(str, heat, word);
        }
 
-       function toFixed(n, d) {
-         if(typeof n != "number") {
-           return n;
-         } else {
-           return n.toFixed(d);
-         }
-       }
-
-       function toExponential(n, d) {
-         if(typeof n != "number") {
-           return n;
-         } else {
-           return n.toExponential(d);
-         }
-       }
-
        % use Mojo::ByteStream 'b';
        var paraResults = <%= b(Mojo::JSON::to_json($lists)) %>;
        var urlprefix =  new URLSearchParams(window.location.search);
@@ -215,50 +182,7 @@
        var collocatorData = <%= b(Mojo::JSON::to_json($collocators)) %>;
        var maxHeat; // = Math.max.apply(Math,collocatorData.map(function(o){return o.cprob;}))
 
-         vocabDistanceTable = $('#vocabdistt').DataTable({
-           ajax: {
-             method: "GET",
-             url: baseURL + '/getBiggestVocabDistances',
-             dataType: 'json',
-             dataSrc: function (result) {
-               return result;
-             },
-             timeout: 30000,
-           },
-           "initComplete":function(settings, json){
-             vocabDistanceTable.columns.adjust().draw();
-           },
-           "createdRow": function (row, data, rowIndex) {
-             $.each($('td.collocator', row), function (colIndex) {
-               $(this).attr('title', "f("+data.word+")="+data.f2.toLocaleString("en-GB") + " f1: "+ccResult.f1+ " total: "+ccResult.N);
-             });
-           },
-           "sScrollY": "780px",
-           "bScrollCollapse": true,
-           "bPaginate": false,
-           "bJQueryUI": true,
-           "dom": '<"top">rt<"bottom"flp><"clear">',
-           "columns": [
-             { "data": "rank", type: "allnumeric" },
-             { "data": "dist",  render: function ( data, type, row ) {return data.toFixed(3) }},
-             { "data": "word",  class: "paradigmator", render: function ( data, type, row ) {
-               urlprefix.set("word", data); return  '<a class="' + getMergedClass(row.rank) + '" href="?' + urlprefix + '">' + data + '</a>' 
-             }}
-           ],
-           "columnDefs": [
-             { className: "dt-right", "targets": [0,1] },
-             { "searchable": false,
-               "orderable": false,
-               "targets": 0
-             },
-             { "orderSequence": [ "desc" ], "targets": [ 1 ] },
-             { "orderSequence": [ "asc", "desc" ], "targets": [ 2 ] },
-           ],
-           "oLanguage": {
-             "sSearch": "Filter: "
-           },
-           "order": [[ 1, 'desc' ]]
-         });
+       vocabDistanceTable = makeVocabDistanceTable("#vocabdistt", baseURL);
 
        if (collocatorData != null) {
          maxHeat = Math.max.apply(Math,collocatorData.map(function(o){return Math.max.apply(Math,o.heat);}))
@@ -349,74 +273,7 @@
          var filterQuot = /^quot/;
          var ccResult;
          var baseURL =  window.location.pathname.replace(/[/]$/, '')
-         classicCollocatorTable = $('#classicoloctable').DataTable({
-           ajax: {
-             method: "GET",
-             url: baseURL + '/getClassicCollocators',
-             dataType: 'json',
-             dataSrc: function (result) {
-               ccResult = result;
-               $("#rawfreq_tt").attr("title", "Raw frequencies of the co-occurence.\n"
-                                            + "f(" + ccResult.w1+")=" + ccResult.f1.toLocaleString("en-GB") + ";\n"
-                                            + "N=" + ccResult.N.toLocaleString("en-GB"));
-               return result.collocates;
-             },
-             timeout: 30000,
-             data: { w: paraResults[0][0].rank }
-           },
-           "initComplete":function(settings, json){
-             $("td.collocator").click(function(){
-               queryKorAPCII(this.textContent + " /w5 " + CIIsearchWords);
-             });
-             classicCollocatorTable.columns(".detail").visible(false);
-             $("#ccd").css('width', '680px');
-             classicCollocatorTable.columns.adjust().draw();
-           },
-           "createdRow": function (row, data, rowIndex) {
-             $.each($('td.collocator', row), function (colIndex) {
-               $(this).attr('title', "f("+data.word+")="+data.f2.toLocaleString("en-GB") + " f1: "+ccResult.f1+ " total: "+ccResult.N);
-             });
-           },
-           "sScrollY": "780px",
-           "bScrollCollapse": true,
-           "bPaginate": false,
-           "bJQueryUI": true,
-           "dom": '<"top">rt<"bottom"flp><"clear">',
-           "columns": [
-             //                      { "data": "pos", width: "7%", sClass: "dt-center mono compact", render: function ( data, type, row ) {return bitvec2window(data, row.heat, row.word) }},
-             { "data": "llr",  render: function ( data, type, row ) {return toFixed(data, 0) }},
-             { "data": "pmi", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             { "data": "md", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             { "data": "lfmd", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             //             { "data": "fpmi", type: "scientific", render: function ( data, type, row ) {return data.toExponential(2) }  },
-             { "data": "npmi", render: function ( data, type, row ) {return toFixed(data, 3) }},
-             { "data": "dice", render: function ( data, type, row ) {return toExponential(data, 2) }},
-             { "data": "ld", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             { "data": "af", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             { "data": "delta", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             { "data": "afwin", width: "auto", sClass: "dt-center mono compact", render: function ( data, type, row ) {return bitmask2window(data, row.win) }},
-             { "data": "llfmd", render: function ( data, type, row ) {return toFixed(data, 1) }},
-             { "data": "rlfmd", render: function ( data, type, row ) {return toFixed(data, 1) }},
-             { "data": "lnpmi", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             { "data": "rnpmi", render: function ( data, type, row ) {return toFixed(data, 2) }},
-             { "data": "f" },
-             { "data": "word",  sClass: "collocator" }
-           ],
-           "columnDefs": [
-             { className: "dt-right", "targets": [0,1,2,3,4,5,6,7,8,10,11,12,13,14] },
-             { className: "dt-right detail", "targets": [5,10,11,12,13] },
-             { "searchable": false,
-               "orderable": false,
-               "targets": []
-             },
-             { "orderSequence": [ "desc" ], "targets": [0,1,2,3,4,5,6,7,10,11,12,13,14] },
-             { "orderSequence": [ "asc", "desc" ], "targets": [8,9,15] },
-           ],
-           "oLanguage": {
-             "sSearch": "Filter: "
-           },
-           "order": [[ 7, 'desc' ]],
-         });
+         classicCollocatorTable = makeClassicCollocatorTable('#classicoloctable', baseURL, paraResults[0][0].rank)
 
          $('#show-details').change(function (e) {
            var columns = classicCollocatorTable.columns(".detail");
@@ -886,13 +743,13 @@
             <table class="display compact nowrap" id="vocabdistt">
               <thead>
                 <tr>
-                  <th align="right">#</th><th align="right">cos</th><th align="left">word</th>
+                  <th align="right">#</th><th id="cosD" align="right">D<sub>cos</sub></th><th align="left">word</th>
                 </tr>
               </thead>
               <tbody>
                 <tr>
                   <td align="right">
-                      </td>
+                  </td>
                   <td align="right">
                   </td>
                   <td></td>
@@ -908,7 +765,7 @@
                 <table class="display compact nowrap" id="firsttable">
                   <thead>
                     <tr>
-                      <th align="right">#</th><th align="right">cos</th><th align="left">similars by w2v</th>
+                      <th align="right">#</th><th align="right">S<sub>cos</sub></th><th align="left">similars by w2v</th>
                     </tr>
                   </thead>
                   <tbody>