| 
      
            Line 0
          
      
      
        Link Here
      
     | 
  
            
               | 
               | 
              1 | 
                  [% INCLUDE 'doc-head-open.inc' %]  | 
            
            
              | 2 | 
                  <title>Koha › Tools › Quote uploader</title>  | 
            
            
              | 3 | 
                  [% INCLUDE 'doc-head-close.inc' %]  | 
            
            
              | 4 | 
                  <link rel="stylesheet" type="text/css" href="/intranet-tmpl/prog/en/css/uploader.css" />  | 
            
            
              | 5 | 
                  <link rel="stylesheet" type="text/css" href="/intranet-tmpl/prog/en/css/datatables.css" />  | 
            
            
              | 6 | 
                  <script type="text/javascript" src="/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.dataTables.min.js"></script>  | 
            
            
              | 7 | 
                  [% INCLUDE 'datatables-strings.inc' %]  | 
            
            
              | 8 | 
                  </script>  | 
            
            
              | 9 | 
                  <script type="text/javascript" src="/intranet-tmpl/prog/en/js/datatables.js"></script>  | 
            
            
              | 10 | 
                  <script type="text/javascript" src="/intranet-tmpl/prog/en/js/jquery.jeditable.mini.js"></script>  | 
            
            
              | 11 | 
                  <script type="text/javascript">  | 
            
            
              | 12 | 
                  //<![CDATA[  | 
            
            
              | 13 | 
                  var oTable; //DataTable object  | 
            
            
              | 14 | 
                  $(document).ready(function() { | 
            
            
              | 15 | 
               | 
            
            
              | 16 | 
                  // Credits:  | 
            
            
              | 17 | 
                  // FileReader() code copied and hacked from:  | 
            
            
              | 18 | 
                  // http://www.html5rocks.com/en/tutorials/file/dndfiles/  | 
            
            
              | 19 | 
                  // fnCSVToArray() gratefully borrowed from:  | 
            
            
              | 20 | 
                  // http://www.bennadel.com/blog/1504-Ask-Ben-Parsing-CSV-Strings-With-Javascript-Exec-Regular-Expression-Command.htm  | 
            
            
              | 21 | 
               | 
            
            
              | 22 | 
                  var reader;  | 
            
            
              | 23 | 
                  var progress = document.querySelector('.percent'); | 
            
            
              | 24 | 
                  $("#server_response").hide(); | 
            
            
              | 25 | 
               | 
            
            
              | 26 | 
                  function fnAbortRead() { | 
            
            
              | 27 | 
                      reader.abort();  | 
            
            
              | 28 | 
                  }  | 
            
            
              | 29 | 
               | 
            
            
              | 30 | 
                  function fnErrorHandler(evt) { | 
            
            
              | 31 | 
                      switch(evt.target.error.code) { | 
            
            
              | 32 | 
                          case evt.target.error.NOT_FOUND_ERR:  | 
            
            
              | 33 | 
                              alert('File Not Found!'); | 
            
            
              | 34 | 
                              break;  | 
            
            
              | 35 | 
                          case evt.target.error.NOT_READABLE_ERR:  | 
            
            
              | 36 | 
                              alert('File is not readable'); | 
            
            
              | 37 | 
                              break;  | 
            
            
              | 38 | 
                          case evt.target.error.ABORT_ERR:  | 
            
            
              | 39 | 
                              break; // noop  | 
            
            
              | 40 | 
                          default:  | 
            
            
              | 41 | 
                              alert('An error occurred reading this file.'); | 
            
            
              | 42 | 
                      };  | 
            
            
              | 43 | 
                  }  | 
            
            
              | 44 | 
               | 
            
            
              | 45 | 
                  function fnUpdateProgress(evt) { | 
            
            
              | 46 | 
                      // evt is an ProgressEvent.  | 
            
            
              | 47 | 
                      if (evt.lengthComputable) { | 
            
            
              | 48 | 
                          var percentLoaded = Math.round((evt.loaded / evt.total) * 100);  | 
            
            
              | 49 | 
                          // Increase the progress bar length.  | 
            
            
              | 50 | 
                          if (percentLoaded < 100) { | 
            
            
              | 51 | 
                              progress.style.width = percentLoaded + '%';  | 
            
            
              | 52 | 
                              progress.textContent = percentLoaded + '%';  | 
            
            
              | 53 | 
                          }  | 
            
            
              | 54 | 
                      }  | 
            
            
              | 55 | 
                  }  | 
            
            
              | 56 | 
               | 
            
            
              | 57 | 
                  function fnCSVToArray( strData, strDelimiter ){ | 
            
            
              | 58 | 
                      // This will parse a delimited string into an array of  | 
            
            
              | 59 | 
                      // arrays. The default delimiter is the comma, but this  | 
            
            
              | 60 | 
                      // can be overriden in the second argument.  | 
            
            
              | 61 | 
               | 
            
            
              | 62 | 
                      // Check to see if the delimiter is defined. If not,  | 
            
            
              | 63 | 
                      // then default to comma.  | 
            
            
              | 64 | 
                      strDelimiter = (strDelimiter || ",");  | 
            
            
              | 65 | 
               | 
            
            
              | 66 | 
                      // Create a regular expression to parse the CSV values.  | 
            
            
              | 67 | 
                      var objPattern = new RegExp(  | 
            
            
              | 68 | 
                      (  | 
            
            
              | 69 | 
                          // Delimiters.  | 
            
            
              | 70 | 
                          "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +  | 
            
            
              | 71 | 
                          // Quoted fields.  | 
            
            
              | 72 | 
                          "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +  | 
            
            
              | 73 | 
                          // Standard fields.  | 
            
            
              | 74 | 
                          "([^\"\\" + strDelimiter + "\\r\\n]*))"  | 
            
            
              | 75 | 
                      ),  | 
            
            
              | 76 | 
                          "gi"  | 
            
            
              | 77 | 
                      );  | 
            
            
              | 78 | 
               | 
            
            
              | 79 | 
                      // Create an array to hold our data. Give the array  | 
            
            
              | 80 | 
                      // a default empty first row.  | 
            
            
              | 81 | 
                      var arrData = [[]];  | 
            
            
              | 82 | 
               | 
            
            
              | 83 | 
                      // Create an array to hold our individual pattern  | 
            
            
              | 84 | 
                      // matching groups.  | 
            
            
              | 85 | 
                      var arrMatches = null;  | 
            
            
              | 86 | 
               | 
            
            
              | 87 | 
                      // Keep looping over the regular expression matches  | 
            
            
              | 88 | 
                      // until we can no longer find a match.  | 
            
            
              | 89 | 
                      while (arrMatches = objPattern.exec( strData )){ | 
            
            
              | 90 | 
               | 
            
            
              | 91 | 
                          // Get the delimiter that was found.  | 
            
            
              | 92 | 
                          var strMatchedDelimiter = arrMatches[ 1 ];  | 
            
            
              | 93 | 
               | 
            
            
              | 94 | 
                          // Check to see if the given delimiter has a length  | 
            
            
              | 95 | 
                          // (is not the start of string) and if it matches  | 
            
            
              | 96 | 
                          // field delimiter. If it does not, then we know  | 
            
            
              | 97 | 
                          // that this delimiter is a row delimiter.  | 
            
            
              | 98 | 
                          if ( strMatchedDelimiter.length && (strMatchedDelimiter != strDelimiter) ){ | 
            
            
              | 99 | 
                              // Since we have reached a new row of data,  | 
            
            
              | 100 | 
                              // add an empty row to our data array.  | 
            
            
              | 101 | 
                              // Note: if there is not more data, we will have to remove this row later  | 
            
            
              | 102 | 
                              arrData.push( [] );  | 
            
            
              | 103 | 
                          }  | 
            
            
              | 104 | 
               | 
            
            
              | 105 | 
                          // Now that we have our delimiter out of the way,  | 
            
            
              | 106 | 
                          // let's check to see which kind of value we  | 
            
            
              | 107 | 
                          // captured (quoted or unquoted).  | 
            
            
              | 108 | 
                          if (arrMatches[ 2 ]){ | 
            
            
              | 109 | 
                              // We found a quoted value. When we capture  | 
            
            
              | 110 | 
                              // this value, unescape any double quotes.  | 
            
            
              | 111 | 
                              var strMatchedValue = arrMatches[ 2 ].replace(  | 
            
            
              | 112 | 
                              new RegExp( "\"\"", "g" ),  | 
            
            
              | 113 | 
                                  "\""  | 
            
            
              | 114 | 
                              );  | 
            
            
              | 115 | 
                          } else if (arrMatches[3]){ | 
            
            
              | 116 | 
                              // We found a non-quoted value.  | 
            
            
              | 117 | 
                              var strMatchedValue = arrMatches[ 3 ];  | 
            
            
              | 118 | 
                          } else { | 
            
            
              | 119 | 
                              // There is no more valid data so remove the row we added earlier  | 
            
            
              | 120 | 
                              // Is there a better way? Perhaps a look-ahead regexp?  | 
            
            
              | 121 | 
                              arrData.splice(arrData.length-1, 1);  | 
            
            
              | 122 | 
                          }  | 
            
            
              | 123 | 
               | 
            
            
              | 124 | 
                          // Now that we have our value string, let's add  | 
            
            
              | 125 | 
                          // it to the data array.  | 
            
            
              | 126 | 
                          arrData[ arrData.length - 1 ].push( strMatchedValue );  | 
            
            
              | 127 | 
                      }  | 
            
            
              | 128 | 
               | 
            
            
              | 129 | 
                      // Return the parsed data.  | 
            
            
              | 130 | 
                      return( arrData );  | 
            
            
              | 131 | 
                  }  | 
            
            
              | 132 | 
               | 
            
            
              | 133 | 
                  function fnDataTable(aaData) { | 
            
            
              | 134 | 
                      for(var i=0; i<aaData.length; i++) { | 
            
            
              | 135 | 
                          aaData[i].unshift(i+1); // Add a column w/quote number  | 
            
            
              | 136 | 
                      }  | 
            
            
              | 137 | 
                      $('#save_quotes').css("visibility","visible"); | 
            
            
              | 138 | 
                      $('#file_uploader').css("visibility","hidden"); | 
            
            
              | 139 | 
                      $('#file_uploader').css("position","absolute"); | 
            
            
              | 140 | 
                      $('#file_uploader').css("top","-150px"); | 
            
            
              | 141 | 
                      $('#quotes_editor').css("visibility","visible"); | 
            
            
              | 142 | 
                      oSaveButton.on("click", yuiGetData); | 
            
            
              | 143 | 
                      oDeleteButton.on("click", fnClickDeleteRow); | 
            
            
              | 144 | 
                      oTable = $('#quotes_editor').dataTable( { | 
            
            
              | 145 | 
                          "bAutoWidth"        : false,  | 
            
            
              | 146 | 
                          "bPaginate"         : true,  | 
            
            
              | 147 | 
                          "bSort"             : false,  | 
            
            
              | 148 | 
                          "sPaginationType"   : "full_numbers",  | 
            
            
              | 149 | 
                          "aaData"            : aaData,  | 
            
            
              | 150 | 
                          "aoColumns"         : [  | 
            
            
              | 151 | 
                              { | 
            
            
              | 152 | 
                                  "sTitle"  : "Number",  | 
            
            
              | 153 | 
                                  "sWidth"  : "2%",  | 
            
            
              | 154 | 
                              },  | 
            
            
              | 155 | 
                              { | 
            
            
              | 156 | 
                                  "sTitle"  : "Source",  | 
            
            
              | 157 | 
                                  "sWidth"  : "15%",  | 
            
            
              | 158 | 
                              },  | 
            
            
              | 159 | 
                              { | 
            
            
              | 160 | 
                                  "sTitle"  : "Quote",  | 
            
            
              | 161 | 
                                  "sWidth"  : "83%",  | 
            
            
              | 162 | 
                              },  | 
            
            
              | 163 | 
                          ],  | 
            
            
              | 164 | 
                         "fnPreDrawCallback": function(oSettings) { | 
            
            
              | 165 | 
                              return true;  | 
            
            
              | 166 | 
                          },  | 
            
            
              | 167 | 
                          "fnRowCallback": function( nRow, aData, iDisplayIndex ) { | 
            
            
              | 168 | 
                              /* do foo on various cells in the current row */  | 
            
            
              | 169 | 
                              var quoteNum = $('td', nRow)[0].innerHTML; | 
            
            
              | 170 | 
                              $(nRow).attr("id", quoteNum); /* set row ids to quote number */ | 
            
            
              | 171 | 
                              $('td:eq(0)', nRow).click(function() {$(this.parentNode).toggleClass('selected',this.clicked);}); /* add row selectors */ | 
            
            
              | 172 | 
                              $('td:eq(0)', nRow).attr("title", "Click ID to select/deselect quote"); | 
            
            
              | 173 | 
                              /* apply no_edit id to noEditFields */  | 
            
            
              | 174 | 
                              noEditFields = [0]; /* number */  | 
            
            
              | 175 | 
                              for (i=0; i<noEditFields.length; i++) { | 
            
            
              | 176 | 
                                  $('td', nRow)[noEditFields[i]].setAttribute("id","no_edit"); | 
            
            
              | 177 | 
                              }  | 
            
            
              | 178 | 
                              return nRow;  | 
            
            
              | 179 | 
                          },  | 
            
            
              | 180 | 
                         "fnDrawCallback": function(oSettings) { | 
            
            
              | 181 | 
                              /* Apply the jEditable handlers to the table on all fields w/o the no_edit id */  | 
            
            
              | 182 | 
                              $('#quotes_editor tbody td[id!="no_edit"]').editable( function(value, settings) { | 
            
            
              | 183 | 
                                      var cellPosition = oTable.fnGetPosition( this );  | 
            
            
              | 184 | 
                                      oTable.fnUpdate(value, cellPosition[0], cellPosition[1], false, false);  | 
            
            
              | 185 | 
                                      return(value);  | 
            
            
              | 186 | 
                                  },  | 
            
            
              | 187 | 
                                  { | 
            
            
              | 188 | 
                                  "callback"      : function( sValue, y ) { | 
            
            
              | 189 | 
                                                        oTable.fnDraw(false); /* no filter/sort or we lose our pagination */  | 
            
            
              | 190 | 
                                                    },  | 
            
            
              | 191 | 
                                  "height"        : "14px",  | 
            
            
              | 192 | 
                              });  | 
            
            
              | 193 | 
                         },  | 
            
            
              | 194 | 
                      });  | 
            
            
              | 195 | 
                      $('#footer').css("visibility","visible"); | 
            
            
              | 196 | 
                  }  | 
            
            
              | 197 | 
               | 
            
            
              | 198 | 
                  function fnHandleFileSelect(evt) { | 
            
            
              | 199 | 
                      // Reset progress indicator on new file selection.  | 
            
            
              | 200 | 
                      progress.style.width = '0%';  | 
            
            
              | 201 | 
                      progress.textContent = '0%';  | 
            
            
              | 202 | 
               | 
            
            
              | 203 | 
                      reader = new FileReader();  | 
            
            
              | 204 | 
                      reader.onerror = fnErrorHandler;  | 
            
            
              | 205 | 
                      reader.onprogress = fnUpdateProgress;  | 
            
            
              | 206 | 
                      reader.onabort = function(e) { | 
            
            
              | 207 | 
                          alert('File read cancelled'); | 
            
            
              | 208 | 
                          parent.location='quotes-upload.pl';  | 
            
            
              | 209 | 
                      };  | 
            
            
              | 210 | 
                      reader.onloadstart = function(e) { | 
            
            
              | 211 | 
                          $('#cancel_upload').css("visibility","visible"); | 
            
            
              | 212 | 
                          $('#progress_bar').addClass("loading"); | 
            
            
              | 213 | 
                      };  | 
            
            
              | 214 | 
                      reader.onload = function(e) { | 
            
            
              | 215 | 
                          // Ensure that the progress bar displays 100% at the end.  | 
            
            
              | 216 | 
                          progress.style.width = '100%';  | 
            
            
              | 217 | 
                          progress.textContent = '100%';  | 
            
            
              | 218 | 
                          $('#cancel_upload').css("visibility","hidden"); | 
            
            
              | 219 | 
                          quotes = fnCSVToArray(e.target.result, ',');  | 
            
            
              | 220 | 
                          fnDataTable(quotes);  | 
            
            
              | 221 | 
                      }  | 
            
            
              | 222 | 
               | 
            
            
              | 223 | 
                      // perform various sanity checks on the target file prior to uploading...  | 
            
            
              | 224 | 
                      var fileType = evt.target.files[0].type || 'unknown';  | 
            
            
              | 225 | 
                      var fileSizeInK = Math.round(evt.target.files[0].size/1024);  | 
            
            
              | 226 | 
               | 
            
            
              | 227 | 
                      if (!fileType.match(/comma-separated-values|csv|excel/i)) { | 
            
            
              | 228 | 
                          alert('Incorrect filetype: '+fileType+'. Uploads limited to csv.'); | 
            
            
              | 229 | 
                          parent.location='quotes-upload.pl';  | 
            
            
              | 230 | 
                          return;  | 
            
            
              | 231 | 
                      }  | 
            
            
              | 232 | 
                      if (fileSizeInK > 512) { | 
            
            
              | 233 | 
                          if (!confirm(evt.target.files[0].name+' is '+fileSizeInK+' K in size. Do you really want to upload this file?')) { | 
            
            
              | 234 | 
                              parent.location='quotes-upload.pl';  | 
            
            
              | 235 | 
                              return;  | 
            
            
              | 236 | 
                          }  | 
            
            
              | 237 | 
                      }  | 
            
            
              | 238 | 
                      // Read in the image file as a text string.  | 
            
            
              | 239 | 
                      reader.readAsText(evt.target.files[0]);  | 
            
            
              | 240 | 
                  }  | 
            
            
              | 241 | 
               | 
            
            
              | 242 | 
                  $('#file_upload').one('change', fnHandleFileSelect); | 
            
            
              | 243 | 
               | 
            
            
              | 244 | 
                  });  | 
            
            
              | 245 | 
               | 
            
            
              | 246 | 
                  function fnGetData(element) { | 
            
            
              | 247 | 
                      var jqXHR = $.ajax({ | 
            
            
              | 248 | 
                          url         : "/cgi-bin/koha/tools/quotes/quotes-upload_ajax.pl",  | 
            
            
              | 249 | 
                          type        : "POST",  | 
            
            
              | 250 | 
                          contentType : "application/x-www-form-urlencoded", // we must claim this mimetype or CGI will not decode the URL encoding  | 
            
            
              | 251 | 
                          dataType    : "json",  | 
            
            
              | 252 | 
                          data        : { | 
            
            
              | 253 | 
                                          "quote"     : JSON.stringify(oTable.fnGetData()),  | 
            
            
              | 254 | 
                                          "action"    : "add",  | 
            
            
              | 255 | 
                                        },  | 
            
            
              | 256 | 
                          success     : function(){ | 
            
            
              | 257 | 
                                          var response = JSON.parse(jqXHR.responseText);  | 
            
            
              | 258 | 
                                          if (response.success) { | 
            
            
              | 259 | 
                                              $("#server_response").text(response.records+' quotes saved.'); | 
            
            
              | 260 | 
                                          }  | 
            
            
              | 261 | 
                                          else { | 
            
            
              | 262 | 
                                              $("#server_response").text('An error has occurred. '+response.records+' quotes saved. Please ask your administrator to check the server log for more details.'); | 
            
            
              | 263 | 
                                          }  | 
            
            
              | 264 | 
                                          $("#server_response").fadeIn(200); | 
            
            
              | 265 | 
                                        },  | 
            
            
              | 266 | 
                      });  | 
            
            
              | 267 | 
                  }  | 
            
            
              | 268 | 
               | 
            
            
              | 269 | 
                  function fnClickDeleteRow() { | 
            
            
              | 270 | 
                      var idsToDelete = oTable.$('.selected').map(function() { | 
            
            
              | 271 | 
                            return this.id;  | 
            
            
              | 272 | 
                      }).get().join(', '); | 
            
            
              | 273 | 
                      if (!idsToDelete) { | 
            
            
              | 274 | 
                          alert('Please select a quote(s) by clicking the quote id(s) you desire to delete.'); | 
            
            
              | 275 | 
                      }  | 
            
            
              | 276 | 
                      else if (confirm('Are you sure you wish to delete quote(s) '+idsToDelete+'?')) { | 
            
            
              | 277 | 
                          oTable.$('.selected').each(function(){ | 
            
            
              | 278 | 
                              oTable.fnDeleteRow(this);  | 
            
            
              | 279 | 
                          });  | 
            
            
              | 280 | 
                      }  | 
            
            
              | 281 | 
                  }  | 
            
            
              | 282 | 
               | 
            
            
              | 283 | 
                  function fnResetUpload() { | 
            
            
              | 284 | 
                      $('#server_response').fadeOut(200); | 
            
            
              | 285 | 
                      window.location.reload(true);   // is this the best route?  | 
            
            
              | 286 | 
                  }  | 
            
            
              | 287 | 
               | 
            
            
              | 288 | 
                  //]]>  | 
            
            
              | 289 | 
                  </script>  | 
            
            
              | 290 | 
              </head>  | 
            
            
              | 291 | 
              <body id="tools_quotes" class="tools">  | 
            
            
              | 292 | 
              [% INCLUDE 'header.inc' %]  | 
            
            
              | 293 | 
              [% INCLUDE 'cat-search.inc' %]  | 
            
            
              | 294 | 
               | 
            
            
              | 295 | 
              <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › <a href="/cgi-bin/koha/tools/quotes.pl">Quote editor</a> › Quote uploader</div>  | 
            
            
              | 296 | 
               | 
            
            
              | 297 | 
              <div id="doc3" class="yui-t2">  | 
            
            
              | 298 | 
                  <div id="bd">  | 
            
            
              | 299 | 
                      <div id="yui-main">  | 
            
            
              | 300 | 
                          <div class="yui-b">  | 
            
            
              | 301 | 
                              [% INCLUDE 'quotes-upload-toolbar.inc' %]  | 
            
            
              | 302 | 
                              <h2>Quote uploader</h2>  | 
            
            
              | 303 | 
                              <fieldset id="file_uploader" class="rows" style="visibility:visible;">  | 
            
            
              | 304 | 
                                  <legend>Upload quotes</legend>  | 
            
            
              | 305 | 
                                  <div id="file_upload" style="margin-left: 10px;">  | 
            
            
              | 306 | 
                                      <input type="file" name="file" />  | 
            
            
              | 307 | 
                                      <button id="cancel_upload" style="visibility:hidden;" onclick="fnAbortRead();">Cancel Upload</button>  | 
            
            
              | 308 | 
                                      <div id="progress_bar"><div class="percent">0%</div></div>  | 
            
            
              | 309 | 
                                  </div>  | 
            
            
              | 310 | 
                              </fieldset>  | 
            
            
              | 311 | 
                              <div id="server_response" onclick='fnResetUpload()'>Server Response</div>  | 
            
            
              | 312 | 
                              <table id="quotes_editor" style="float: left; width: 100%; visibility:hidden;">  | 
            
            
              | 313 | 
                              <thead>  | 
            
            
              | 314 | 
                                  <tr>  | 
            
            
              | 315 | 
                                      <th>Source</th>  | 
            
            
              | 316 | 
                                      <th>Text</th>  | 
            
            
              | 317 | 
                                      <th>Actions</th>  | 
            
            
              | 318 | 
                                  </tr>  | 
            
            
              | 319 | 
                              </thead>  | 
            
            
              | 320 | 
                              <tbody>  | 
            
            
              | 321 | 
                                  <!-- tbody content is generated by DataTables -->  | 
            
            
              | 322 | 
                                  <tr>  | 
            
            
              | 323 | 
                                      <td></td>  | 
            
            
              | 324 | 
                                      <td>Loading data...</td>  | 
            
            
              | 325 | 
                                      <td></td>  | 
            
            
              | 326 | 
                                  </tr>  | 
            
            
              | 327 | 
                              </tbody>  | 
            
            
              | 328 | 
                              </table>  | 
            
            
              | 329 | 
                              <fieldset id="footer" class="action" style="visibility:hidden; height:25px">  | 
            
            
              | 330 | 
                              </fieldset>  | 
            
            
              | 331 | 
                          </div>  | 
            
            
              | 332 | 
                      </div>  | 
            
            
              | 333 | 
                  <div class="yui-b noprint">  | 
            
            
              | 334 | 
                      [% INCLUDE 'tools-menu.inc' %]  | 
            
            
              | 335 | 
                  </div>  | 
            
            
              | 336 | 
              </div>  | 
            
            
              | 337 | 
              [% INCLUDE 'intranet-bottom.inc' %]  |