<commit_before>(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "CellExternalCopyManager": CellExternalCopyManager
    }
  });

  function CellExternalCopyManager(options) {
    /*
      This manager enables users to copy/paste data from/to an external Spreadsheet application
      such as MS-Excel® or OpenOffice-Spreadsheet.

      Since it is not possible to access directly the clipboard in javascript, the plugin uses
      a trick to do it's job. After detecting the keystroke, we dynamically create a textarea
      where the browser copies/pastes the serialized data.

      options:
        copiedCellStyle : sets the css className used for copied cells. default : "copied"
        copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : "copy-manager"
        dataItemColumnValueExtractor : option to specify a custom column value extractor function
        dataItemColumnValueSetter : option to specify a custom column value setter function
        clipboardCommandHandler : option to specify a custom handler for paste actions
    */
    var _grid;
    var _self = this;
    var _copiedRanges;
    var _options = options || {};
    var _copiedCellStyleLayerKey = _options.copiedCellStyleLayerKey || "copy-manager";
    var _copiedCellStyle = _options.copiedCellStyle || "copied";
    var _clearCopyTI = 0;

    var keyCodes = {
      'C':67,
      'V':86
    }

    function init(grid) {
      _grid = grid;
      _grid.onKeyDown.subscribe(handleKeyDown);

      // we need a cell selection model
      var cellSelectionModel = grid.getSelectionModel();
      if (!cellSelectionModel){
        throw new Error("Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())");
      }
    }

    function destroy() {
      _grid.onKeyDown.unsubscribe(handleKeyDown);
    }

    function getDataItemValueForColumn(item, columnDef) {
      if (_options.dataItemColumnValueExtractor) {
        return _options.dataItemColumnValueExtractor(item, columnDef);
      }

      var retVal = '';

      // if a custom getter is not defined, we call serializeValue of the editor to serialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$(document),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        retVal = editor.serializeValue();
        editor.destroy();
      }

      return retVal;
    }

    function setDataItemValueForColumn(item, columnDef, value) {
      if (_options.dataItemColumnValueSetter) {
        return _options.dataItemColumnValueSetter(item, columnDef, value);
      }

      // if a custom setter is not defined, we call applyValue of the editor to unserialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$(document),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        editor.applyValue(item, value);
        editor.destroy();
      }
    }

    function _createTextBox(innerText){
      var ta = document.createElement('textarea');
      ta.style.position = 'absolute';
      ta.style.left = '-1000px';
      ta.style.top = document.body.scrollTop + 'px';
      ta.value = innerText;
      document.body.appendChild(ta);
      ta.select();

      return ta;
    }

    function _decodeTabularData(_grid, ta){
      var columns = _grid.getColumns();
      var clipText = ta.value;
      var clipRows = clipText.split(/[\n\f\r]/);
      var clippedRange = [];

      document.body.removeChild(ta);

      for (var i=0; i<clipRows.length; i++) {
          clippedRange[i] = clipRows[i].split("\t");
      }

      var selectedCell = _grid.getActiveCell();
      var ranges = _grid.getSelectionModel().getSelectedRanges();
      var selectedRange = ranges && ranges.length ? ranges[0] : null;   // pick only one selection
      var activeRow = null;
      var activeCell = null;

      if (selectedRange){
        activeRow = selectedRange.fromRow;
        activeCell = Math.max(selectedRange.fromCell, 1);
      } else if (selectedCell){
        activeRow = selectedCell.row;
        activeCell = Math.max(selectedCell.cell, 1);
      } else {
        // we don't know where to paste
        return;
      }

      var oneCellToMultiple = false;
      var destH = clippedRange.length;
      var destW = clippedRange.length ? clippedRange[0].length : 0;
      if (clippedRange.length == 1 && clippedRange[0].length == 1 && selectedRange){
        oneCellToMultiple = true;
        destH = selectedRange.toRow - activeRow + 1;
        destW = selectedRange.toCell - activeCell + 1;
      }
      var availableCols = columns.length - activeCell;
      if(availableCols < destW) {
          alert("Error: Trying to paste out of the range of columns");
          return;
      }

      var readOnlyCols = new Array();
      for(var i = activeCell; i < activeCell + destW; ++i) {
          if(!columns[i].hasOwnProperty('editor')) {
              readOnlyCols.push(columns[i].name);
          }
      }
      if(readOnlyCols.length > 0) {
          var confirmText = "Information pasted on the readonly column";
          confirmText += (readOnlyCols.length == 1)?" ":"s ";
          confirmText += readOnlyCols.join(",");
          confirmText += " will be lost.\n\nDo you want to continue?";
          if(!confirm(confirmText)) {
              return;
          }
      }

      var availableRows = _grid.getData().length - activeRow;
      var addRows = 0;
      if(availableRows < destH)
      {
        var d = _grid.getData();
        for(addRows = 1; addRows <= destH - availableRows; addRows++) {
            d.push({});
        }
        _grid.setData(d);
        _grid.render();
      }
      var clipCommand = {

        isClipboardCommand: true,
        clippedRange: clippedRange,
        oldValues: [],
        cellExternalCopyManager: _self,
        _options: _options,
        setDataItemValueForColumn: setDataItemValueForColumn,
        markCopySelection: markCopySelection,
        oneCellToMultiple: oneCellToMultiple,
        activeRow: activeRow,
        activeCell: activeCell,
        destH: destH,
        destW: destW,
        desty: activeRow,
        destx: activeCell,
        maxDestY: _grid.getDataLength(),
        maxDestX: _grid.getColumns().length,
        h: 0,
        w: 0,

        execute: function() {
          this.h=0;
          for (var y = 0; y < destH; y++){
            this.oldValues[y] = [];
            this.w=0;
            this.h++;
            for (var x = 0; x < destW; x++){
              this.w++;
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                this.oldValues[y][x] = dt[columns[destx]['id']];
                if (oneCellToMultiple) {
                    this.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);
                } else {
                    this.setDataItemValueForColumn(dt, columns[destx], clippedRange[y][x]);
                }
                _grid.updateCell(desty, destx);
              }
            }
          }

          var bRange = new Slick.Range(activeRow, activeCell, activeRow+this.h-1, activeCell+this.w-1);
          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});
        },

        undo: function() {
          for (var y = 0; y < destH; y++){
            for (var x = 0; x < destW; x++){
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                if (oneCellToMultiple)
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[0][0]);
                else
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[y][x]);
                _grid.updateCell(desty, destx);
              }
            }
          }

          var bRange = new Slick.Range(activeRow, activeCell, activeRow+this.h-1, activeCell+this.w-1);

          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});

          if(addRows > 1){
            var d = _grid.getData();
            for(; addRows > 1; addRows--)
              d.splice(d.length - 1, 1);
            _grid.setData(d);
            _grid.render();
          }
        }
      };

      if(_options.clipboardCommandHandler) {
        _options.clipboardCommandHandler(clipCommand);
      }
      else {
        clipCommand.execute();
      }
    }

    function handleKeyDown(e, args) {
      var ranges;
      if (!_grid.getEditorLock().isActive()) {
        if (e.which == $.ui.keyCode.ESCAPE) {
          if (_copiedRanges) {
            e.preventDefault();
            clearCopySelection();
            _self.onCopyCancelled.notify({ranges: _copiedRanges});
            _copiedRanges = null;
          }
        }

        if (e.which == keyCodes.C && (e.ctrlKey || e.metaKey)) {    // CTRL + C
          ranges = _grid.getSelectionModel().getSelectedRanges();
          if (ranges.length != 0) {
            _copiedRanges = ranges;
            markCopySelection(ranges);
            _self.onCopyCells.notify({ranges: ranges});

            var columns = _grid.getColumns();
            var clipTextArr = [];
            var gridData = _grid.getData();

            for (var rg = 0; rg < ranges.length; rg++){
                var range = ranges[rg];
                var fromCellSafe = Math.max(range.fromCell, 1);
                var clipTextRows = [];
                for (var i=range.fromRow; i < range.toRow+1 ; i++){
                    var clipTextCells = [];
                    for (var j=fromCellSafe; j< range.toCell+1 ; j++){
                        var cellValue = gridData[i][columns[j].field];
                        clipTextCells.push(escapeNewLines(cellValue));
                    }
                    clipTextRows.push(clipTextCells.join("\t"));
                }
                clipTextArr.push(clipTextRows.join("\r\n"));
                if (clipTextRows.length === 1 && ranges.length > 1 && rg < ranges.length - 1) {
                    clipTextArr.push("\r\n");
                }
            }
            var clipText = clipTextArr.join('');
            var $focus = $(_grid.getActiveCellNode());

            var ta = _createTextBox(clipText);

            ta.focus();

            setTimeout(function(){
                document.body.removeChild(ta);
                // restore focus
                if ($focus && $focus.length > 0) {
                    $focus.attr('tabIndex', '-1');
                    $focus.focus();
                    $focus.removeAttr('tabIndex');
                }
            }, 100);

            return false;
          }
        }

        if (e.which == keyCodes.V && (e.ctrlKey || e.metaKey)) {    // CTRL + V
            var ta = _createTextBox('');

            setTimeout(function(){
                _decodeTabularData(_grid, ta);
            }, 100);

            return false;
        }
      }
    }

    function markCopySelection(ranges) {
      clearCopySelection();

      var columns = _grid.getColumns();
      var hash = {};
      for (var i = 0; i < ranges.length; i++) {
        for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
          hash[j] = {};
          for (var k = ranges[i].fromCell; k <= ranges[i].toCell && k<columns.length; k++) {
            hash[j][columns[k].id] = _copiedCellStyle;
          }
        }
      }
      _grid.setCellCssStyles(_copiedCellStyleLayerKey, hash);
      clearTimeout(_clearCopyTI);
      _clearCopyTI = setTimeout(function(){
        _self.clearCopySelection();
      }, 2000);
    }

    function clearCopySelection() {
      _grid.removeCellCssStyles(_copiedCellStyleLayerKey);
    }

    $.extend(this, {
      "init": init,
      "destroy": destroy,
      "clearCopySelection": clearCopySelection,
      "handleKeyDown":handleKeyDown,

      "onCopyCells": new Slick.Event(),
      "onCopyCancelled": new Slick.Event(),
      "onPasteCells": new Slick.Event()
    });
  }
})(jQuery);
<commit_msg>Fix for paste on empty tables, added check  when the cell header is selected to start with row 0.<commit_after>(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "CellExternalCopyManager": CellExternalCopyManager
    }
  });

  function CellExternalCopyManager(options) {
    /*
      This manager enables users to copy/paste data from/to an external Spreadsheet application
      such as MS-Excel® or OpenOffice-Spreadsheet.

      Since it is not possible to access directly the clipboard in javascript, the plugin uses
      a trick to do it's job. After detecting the keystroke, we dynamically create a textarea
      where the browser copies/pastes the serialized data.

      options:
        copiedCellStyle : sets the css className used for copied cells. default : "copied"
        copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : "copy-manager"
        dataItemColumnValueExtractor : option to specify a custom column value extractor function
        dataItemColumnValueSetter : option to specify a custom column value setter function
        clipboardCommandHandler : option to specify a custom handler for paste actions
    */
    var _grid;
    var _self = this;
    var _copiedRanges;
    var _options = options || {};
    var _copiedCellStyleLayerKey = _options.copiedCellStyleLayerKey || "copy-manager";
    var _copiedCellStyle = _options.copiedCellStyle || "copied";
    var _clearCopyTI = 0;

    var keyCodes = {
      'C':67,
      'V':86
    }

    function init(grid) {
      _grid = grid;
      _grid.onKeyDown.subscribe(handleKeyDown);

      // we need a cell selection model
      var cellSelectionModel = grid.getSelectionModel();
      if (!cellSelectionModel){
        throw new Error("Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())");
      }
    }

    function destroy() {
      _grid.onKeyDown.unsubscribe(handleKeyDown);
    }

    function getDataItemValueForColumn(item, columnDef) {
      if (_options.dataItemColumnValueExtractor) {
        return _options.dataItemColumnValueExtractor(item, columnDef);
      }

      var retVal = '';

      // if a custom getter is not defined, we call serializeValue of the editor to serialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$(document),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        retVal = editor.serializeValue();
        editor.destroy();
      }

      return retVal;
    }

    function setDataItemValueForColumn(item, columnDef, value) {
      if (_options.dataItemColumnValueSetter) {
        return _options.dataItemColumnValueSetter(item, columnDef, value);
      }

      // if a custom setter is not defined, we call applyValue of the editor to unserialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$(document),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        editor.applyValue(item, value);
        editor.destroy();
      }
    }

    function _createTextBox(innerText){
      var ta = document.createElement('textarea');
      ta.style.position = 'absolute';
      ta.style.left = '-1000px';
      ta.style.top = document.body.scrollTop + 'px';
      ta.value = innerText;
      document.body.appendChild(ta);
      ta.select();

      return ta;
    }

    function _decodeTabularData(_grid, ta){
      var columns = _grid.getColumns();
      var clipText = ta.value;
      var clipRows = clipText.split(/[\n\f\r]/);
      var clippedRange = [];

      document.body.removeChild(ta);

      for (var i=0; i<clipRows.length; i++) {
          clippedRange[i] = clipRows[i].split("\t");
      }

      var selectedCell = _grid.getActiveCell();
      var ranges = _grid.getSelectionModel().getSelectedRanges();
      var selectedRange = ranges && ranges.length ? ranges[0] : null;   // pick only one selection
      var activeRow = null;
      var activeCell = null;

      if (selectedRange){
        activeRow = Math.max(selectedRange.fromRow, 0);
        activeCell = Math.max(selectedRange.fromCell, 1);
      } else if (selectedCell){
        activeRow = selectedCell.row;
        activeCell = Math.max(selectedCell.cell, 1);
      } else {
        // we don't know where to paste
        return;
      }

      var oneCellToMultiple = false;
      var destH = clippedRange.length;
      var destW = clippedRange.length ? clippedRange[0].length : 0;
      if (clippedRange.length == 1 && clippedRange[0].length == 1 && selectedRange){
        oneCellToMultiple = true;
        destH = selectedRange.toRow - activeRow + 1;
        destW = selectedRange.toCell - activeCell + 1;
      }
      var availableCols = columns.length - activeCell;
      if(availableCols < destW) {
          alert("Error: Trying to paste out of the range of columns");
          return;
      }

      var readOnlyCols = new Array();
      for(var i = activeCell; i < activeCell + destW; ++i) {
          if(!columns[i].hasOwnProperty('editor')) {
              readOnlyCols.push(columns[i].name);
          }
      }
      if(readOnlyCols.length > 0) {
          var confirmText = "Information pasted on the readonly column";
          confirmText += (readOnlyCols.length == 1)?" ":"s ";
          confirmText += readOnlyCols.join(",");
          confirmText += " will be lost.\n\nDo you want to continue?";
          if(!confirm(confirmText)) {
              return;
          }
      }

      var availableRows = _grid.getData().length - activeRow;
      var addRows = 0;
      if(availableRows < destH)
      {
        var d = _grid.getData();
        for(addRows = 1; addRows <= destH - availableRows; addRows++) {
            d.push({});
        }
        _grid.setData(d);
        _grid.render();
      }
      var clipCommand = {

        isClipboardCommand: true,
        clippedRange: clippedRange,
        oldValues: [],
        cellExternalCopyManager: _self,
        _options: _options,
        setDataItemValueForColumn: setDataItemValueForColumn,
        markCopySelection: markCopySelection,
        oneCellToMultiple: oneCellToMultiple,
        activeRow: activeRow,
        activeCell: activeCell,
        destH: destH,
        destW: destW,
        desty: activeRow,
        destx: activeCell,
        maxDestY: _grid.getDataLength(),
        maxDestX: _grid.getColumns().length,
        h: 0,
        w: 0,

        execute: function() {
          this.h=0;
          for (var y = 0; y < destH; y++){
            this.oldValues[y] = [];
            this.w=0;
            this.h++;
            for (var x = 0; x < destW; x++){
              this.w++;
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                this.oldValues[y][x] = dt[columns[destx]['id']];
                if (oneCellToMultiple) {
                    this.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);
                } else {
                    this.setDataItemValueForColumn(dt, columns[destx], clippedRange[y][x]);
                }
                _grid.updateCell(desty, destx);
              }
            }
          }

          var bRange = new Slick.Range(activeRow, activeCell, activeRow+this.h-1, activeCell+this.w-1);
          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});
        },

        undo: function() {
          for (var y = 0; y < destH; y++){
            for (var x = 0; x < destW; x++){
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                if (oneCellToMultiple)
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[0][0]);
                else
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[y][x]);
                _grid.updateCell(desty, destx);
              }
            }
          }

          var bRange = new Slick.Range(activeRow, activeCell, activeRow+this.h-1, activeCell+this.w-1);

          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});

          if(addRows > 1){
            var d = _grid.getData();
            for(; addRows > 1; addRows--)
              d.splice(d.length - 1, 1);
            _grid.setData(d);
            _grid.render();
          }
        }
      };

      if(_options.clipboardCommandHandler) {
        _options.clipboardCommandHandler(clipCommand);
      }
      else {
        clipCommand.execute();
      }
    }

    function handleKeyDown(e, args) {
      var ranges;
      if (!_grid.getEditorLock().isActive()) {
        if (e.which == $.ui.keyCode.ESCAPE) {
          if (_copiedRanges) {
            e.preventDefault();
            clearCopySelection();
            _self.onCopyCancelled.notify({ranges: _copiedRanges});
            _copiedRanges = null;
          }
        }

        if (e.which == keyCodes.C && (e.ctrlKey || e.metaKey)) {    // CTRL + C
          ranges = _grid.getSelectionModel().getSelectedRanges();
          if (ranges.length != 0) {
            _copiedRanges = ranges;
            markCopySelection(ranges);
            _self.onCopyCells.notify({ranges: ranges});

            var columns = _grid.getColumns();
            var clipTextArr = [];
            var gridData = _grid.getData();

            for (var rg = 0; rg < ranges.length; rg++){
                var range = ranges[rg];
                var fromCellSafe = Math.max(range.fromCell, 1);
                var clipTextRows = [];
                for (var i=range.fromRow; i < range.toRow+1 ; i++){
                    var clipTextCells = [];
                    for (var j=fromCellSafe; j< range.toCell+1 ; j++){
                        var cellValue = gridData[i][columns[j].field];
                        clipTextCells.push(escapeNewLines(cellValue));
                    }
                    clipTextRows.push(clipTextCells.join("\t"));
                }
                clipTextArr.push(clipTextRows.join("\r\n"));
                if (clipTextRows.length === 1 && ranges.length > 1 && rg < ranges.length - 1) {
                    clipTextArr.push("\r\n");
                }
            }
            var clipText = clipTextArr.join('');
            var $focus = $(_grid.getActiveCellNode());

            var ta = _createTextBox(clipText);

            ta.focus();

            setTimeout(function(){
                document.body.removeChild(ta);
                // restore focus
                if ($focus && $focus.length > 0) {
                    $focus.attr('tabIndex', '-1');
                    $focus.focus();
                    $focus.removeAttr('tabIndex');
                }
            }, 100);

            return false;
          }
        }

        if (e.which == keyCodes.V && (e.ctrlKey || e.metaKey)) {    // CTRL + V
            var ta = _createTextBox('');

            setTimeout(function(){
                _decodeTabularData(_grid, ta);
            }, 100);

            return false;
        }
      }
    }

    function markCopySelection(ranges) {
      clearCopySelection();

      var columns = _grid.getColumns();
      var hash = {};
      for (var i = 0; i < ranges.length; i++) {
        for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
          hash[j] = {};
          for (var k = ranges[i].fromCell; k <= ranges[i].toCell && k<columns.length; k++) {
            hash[j][columns[k].id] = _copiedCellStyle;
          }
        }
      }
      _grid.setCellCssStyles(_copiedCellStyleLayerKey, hash);
      clearTimeout(_clearCopyTI);
      _clearCopyTI = setTimeout(function(){
        _self.clearCopySelection();
      }, 2000);
    }

    function clearCopySelection() {
      _grid.removeCellCssStyles(_copiedCellStyleLayerKey);
    }

    $.extend(this, {
      "init": init,
      "destroy": destroy,
      "clearCopySelection": clearCopySelection,
      "handleKeyDown":handleKeyDown,

      "onCopyCells": new Slick.Event(),
      "onCopyCancelled": new Slick.Event(),
      "onPasteCells": new Slick.Event()
    });
  }
})(jQuery);
<|endoftext|>


<commit_before>/*
 *
 *   Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *   WSO2 Inc. licenses this file to you under the Apache License,
 *   Version 2.0 (the "License"); you may not use this file except
 *   in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on anselectedRevision
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

var selectedRevisionLogMap = {};
var selectedRevisionReplicaList = [];
var selectedReplica;
var editor;
$(document).ready(function () {
    editor = CodeMirror.fromTextArea(document.getElementById("build-logs"), {
        styleActiveLine: true,
        lineNumbers: true,
        readOnly: true,
        searchonly: true,
        lineWrapping: true,
        theme:'icecoder'
    });
    initData(selectedRevision, true);
});

function regerateReplicasList(selectedRevisionReplicaList) {
    $('#replicas').empty();
    for (var i = 0; i < selectedRevisionReplicaList.length; i++) {
        var $option = $('<option value="' + selectedRevisionReplicaList[i] + '">' + selectedRevisionReplicaList[i] + '</option>');
        if (i == 0) {
            selectedReplica = selectedRevisionReplicaList[i];
            $option.attr('selected', 'selected');
        }
        $('#replicas').append($option);
    }
}

function setLogArea(logVal, isFirstRequest){
    if(!isFirstRequest) {
        var currentLog = $('#build-logs').val();
        logVal = currentLog + logVal;
    }
    $('#build-logs').val(logVal);
    editor.setValue(logVal);
    var scroller = editor.getScrollInfo();
    editor.scrollTo(0, scroller.height);
    $('.log-search').focus();
}

function initData(selectedRevision, isFirstRequest){
    $('#replicas').empty();
    if(isFirstRequest) {
        setLogArea("Loading...", true);
    }
    jagg.post("../blocks/runtimeLogs/ajax/runtimeLogs.jag", {
        action:"getSnapshotLogs",
        applicationKey:applicationKey,
        selectedRevision:selectedRevision,
        isFirstRequest:isFirstRequest
    },function (result) {
        initelements();
        result = result.replace(/\t+/g, "    ");
        selectedRevisionLogMap = jQuery.parseJSON(result);
        if(!jQuery.isEmptyObject(selectedRevisionLogMap)){
            $("#log-reload").removeClass("btn-action btn disabled").addClass("btn-action");
            selectedRevisionReplicaList = Object.keys(selectedRevisionLogMap);
            regerateReplicasList(selectedRevisionReplicaList);
            setLogArea(selectedRevisionLogMap[selectedRevisionReplicaList[0]], isFirstRequest);
            setInterval(function(){ initData(selectedRevision, false); }, 3000);
        } else {
            //Check for application revision status and display correct message
            jagg.post("../blocks/runtimeLogs/ajax/runtimeLogs.jag", {
                action: "getApplicationRevisionStatus",
                applicationKey: applicationKey,
                selectedRevision: selectedRevision
            }, function(result) {
                result = result.trim();
                var revisionStatus = result;
                if (revisionStatus == "stopped") {
                    jagg.message({
                        content: "Application is stopped. Please go to back to the application and click the" +
                        " Start button.",
                        type: 'information',
                        id: 'view_log',
                        timeout: '5000'
                    });
                } else {
                    jagg.message({
                        content: "Deployment in progress. Please wait",
                        type: 'information',
                        id: 'view_log',
                        timeout: '5000'
                    });
                }
                setTimeout(function() {
                    $.noty.closeAll();
                    initData(selectedRevision, true);
                }, 5000);
            }, function(jqXHR, textStatus, errorThrown) {
                jagg.message({
                    content: "Error occured while getting application revision status.",
                    type: 'error',
                    id: 'view_log'
                });
            });
        }
    },function (jqXHR, textStatus, errorThrown) {
        $('#revision').prop("disabled", false);
        $("#log-reload").removeClass("btn-action btn disabled").addClass("btn-action");
        jagg.message({content: "Error occurred while loading the logs.", type: 'error', id:'view_log'});
    });
}

function initelements(){
    //Url text loaded from the span element
    var urlText = $('.version-url a span').text();

    //Maximum character limit is 90. further than that the text would not show and the title would!
    if(urlText.length > 90){
        $('.version-url a').prop('title',urlText).find('span').text(urlText);
    }else{
        $('.version-url a span').text(urlText);
    }

    var revisionElement = $('#revision');
    revisionElement.prop("disabled", false);

    revisionElement.on('change', function (e) {
        selectedRevision = this.value;
        $(this).prop("disabled", true);
        initData(selectedRevision, true);
    });

    $('#replicas').on('change', function (e) {
        selectedReplica = this.value;
        setLogArea(selectedRevisionLogMap[selectedReplica],true);
    });

    $('#log-reload').on('click', function (e) {
        $("#log-reload").removeClass("btn-action").addClass("btn-action btn disabled");
        selectedReplica = $('#replicas').val();
        setLogArea("Loading...", true);
        setTimeout(function(){initData(selectedRevision, true);setLogArea(selectedRevisionLogMap[selectedReplica], true);}, 1000);
    });
}
<commit_msg>fixing browser crash issue<commit_after>/*
 *
 *   Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *   WSO2 Inc. licenses this file to you under the Apache License,
 *   Version 2.0 (the "License"); you may not use this file except
 *   in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on anselectedRevision
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

var selectedRevisionLogMap = {};
var selectedRevisionReplicaList = [];
var selectedReplica;
var editor;
var isLogsAvailable = false;
$(document).ready(function () {
    editor = CodeMirror.fromTextArea(document.getElementById("build-logs"), {
        styleActiveLine: true,
        lineNumbers: true,
        readOnly: true,
        searchonly: true,
        lineWrapping: true,
        theme:'icecoder'
    });
    initData(selectedRevision, true);
    setInterval(function(){ initData(selectedRevision, false); }, 3000);
});

function regerateReplicasList(selectedRevisionReplicaList) {
    $('#replicas').empty();
    for (var i = 0; i < selectedRevisionReplicaList.length; i++) {
        var $option = $('<option value="' + selectedRevisionReplicaList[i] + '">' + selectedRevisionReplicaList[i] + '</option>');
        if (i == 0) {
            selectedReplica = selectedRevisionReplicaList[i];
            $option.attr('selected', 'selected');
        }
        $('#replicas').append($option);
    }
}

function setLogArea(logVal, isFirstRequest){
    $('#build-logs').empty();
    editor.setValue("");
    if(!isFirstRequest) {
        var currentLog = $('#build-logs').val();
        logVal = currentLog + logVal;
    }
    $('#build-logs').val(logVal);
    editor.setValue(logVal);
    var scroller = editor.getScrollInfo();
    editor.scrollTo(0, scroller.height);
    $('.log-search').focus();
}

function initData(selectedRevision, isFirstRequest){
    if(isFirstRequest){
        $('#replicas').empty();
        setLogArea("Loading...", true);
    }
    jagg.post("../blocks/runtimeLogs/ajax/runtimeLogs.jag", {
        action:"getSnapshotLogs",
        applicationKey:applicationKey,
        selectedRevision:selectedRevision,
        isFirstRequest:isFirstRequest
    },function (result) {
        initelements();
        result = result.replace(/\t+/g, "    ");
        selectedRevisionLogMap = jQuery.parseJSON(result);
        if(!jQuery.isEmptyObject(selectedRevisionLogMap)){
            $("#log-reload").removeClass("btn-action btn disabled").addClass("btn-action");
            selectedRevisionReplicaList = Object.keys(selectedRevisionLogMap);
            if(isFirstRequest){
                regerateReplicasList(selectedRevisionReplicaList);
            }
            setLogArea(selectedRevisionLogMap[selectedRevisionReplicaList[0]], isFirstRequest);
        } else {
            //Check for application revision status and display correct message
            jagg.post("../blocks/runtimeLogs/ajax/runtimeLogs.jag", {
                action: "getApplicationRevisionStatus",
                applicationKey: applicationKey,
                selectedRevision: selectedRevision
            }, function(result) {
                result = result.trim();
                var revisionStatus = result;
                if (revisionStatus == "stopped") {
                    jagg.message({
                        content: "Application is stopped. Please go to back to the application and click the" +
                        " Start button.",
                        type: 'information',
                        id: 'view_log',
                        timeout: '5000'
                    });
                } else {
                    jagg.message({
                        content: "Deployment in progress. Please wait",
                        type: 'information',
                        id: 'view_log',
                        timeout: '5000'
                    });
                }
            }, function(jqXHR, textStatus, errorThrown) {
                jagg.message({
                    content: "Error occured while getting application revision status.",
                    type: 'error',
                    id: 'view_log'
                });
            });
        }
    },function (jqXHR, textStatus, errorThrown) {
        $('#revision').prop("disabled", false);
        $("#log-reload").removeClass("btn-action btn disabled").addClass("btn-action");
        jagg.message({content: "Error occurred while loading the logs.", type: 'error', id:'view_log'});
    });
}

function initelements(){
    //Url text loaded from the span element
    var urlText = $('.version-url a span').text();

    //Maximum character limit is 90. further than that the text would not show and the title would!
    if(urlText.length > 90){
        $('.version-url a').prop('title',urlText).find('span').text(urlText);
    }else{
        $('.version-url a span').text(urlText);
    }

    var revisionElement = $('#revision');
    revisionElement.prop("disabled", false);

    revisionElement.on('change', function (e) {
        selectedRevision = this.value;
        $(this).prop("disabled", true);
        initData(selectedRevision, true);
    });

    $('#replicas').on('change', function (e) {
        selectedReplica = this.value;
        setLogArea(selectedRevisionLogMap[selectedReplica],true);
    });

    $('#log-reload').on('click', function (e) {
        $("#log-reload").removeClass("btn-action").addClass("btn-action btn disabled");
        selectedReplica = $('#replicas').val();
        setLogArea("Loading...", true);
        setTimeout(function(){initData(selectedRevision, true);setLogArea(selectedRevisionLogMap[selectedReplica], true);}, 1000);
    });
}
<|endoftext|>


<commit_before><commit_msg>add folder for embedded video<commit_after><|endoftext|>


<commit_before>// WARNING
$(function(){
  $.widget( "custom.catcomplete", $.ui.autocomplete, {
    _create: function() {
      this._super();
      this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" );
    },
    _renderMenu: function( ul, items ) {
      var that = this,
      currentCategory = "";
      function sortBy(a, b) {
        if (a.category.toLowerCase()  b.category.toLowerCase()) {
          return 1;
        } else if (a.value.toLowerCase()  b.value.toLowerCase()) {
          return 1;
        } else {
          return 0;
        }
      }
      $.each( items.sort(sortBy), function( index, item ) {
        var li;
        if ( item.category != currentCategory ) {
          ul.append( "
" + item.category + "
" );
          currentCategory = item.category;
        }
        li = that._renderItemData( ul, item );
        if ( item.category ) {
          li.attr( "aria-label", item.category + " : " + item.label );
        }
      });
    }
  });
  $("#query").attr('placeholder', '🔍').catcomplete({
      response: function( e, ui ) {
        if ( ! ui.content.length ) {
            $('#search').addClass('not-found')
                .find('#try-web-search').attr(
                    'href', 'https://www.google.com/search?q=site%3Adocs.perl6.org+'
                    + encodeURIComponent( $("#query").val() )
                );
        }
        else {
            $('#search').removeClass('not-found')
        }
      },
      open: function() {
        var ui_el = $('.ui-autocomplete');
        if ( ui_el.offset().left < 0 ) {
            ui_el.css({left: 0})
        }
      },
      position: { my: "right top", at: "right bottom", of: "#search div" },
      source: [
          PREDEFINED
          ITEMS
      ],
      select: function (event, ui) { window.location.href = ui.item.url; },
      autoFocus: true
  });
});
<commit_msg>Display 5to6 items in search results last<commit_after>// WARNING
$(function(){
  $.widget( "custom.catcomplete", $.ui.autocomplete, {
    _create: function() {
      this._super();
      this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" );
    },
    _renderMenu: function( ul, items ) {
      var that = this,
      currentCategory = "";
      function sortBy(a, b) {
        // We want to place 5to6 docs to the end of the list.
        // See if either a or b are in 5to6 category.
        var isp5a = false, isp5b = false;
        if ( a.category.substr(0,4) == '5to6' ) { isp5a = true; }
        if ( b.category.substr(0,4) == '5to6' ) { isp5b = true; }

        // If one of the categories is a 5to6 but other isn't,
        // move 5to6 to be last
        if ( isp5a  && !isp5b ) {return  1}
        if ( !isp5a && isp5b  ) {return -1}

        // Sort by category alphabetically; 5to6 items would both have
        // the same category if we reached this point and category sort
        // will happen only on non-5to6 items
        if ( a.category.toLowerCase()  b.category.toLowerCase() ) {return  1}

        // We reach this point when categories are the same; so
        // we sort items by value
        if ( a.value.toLowerCase()  b.value.toLowerCase() ) {return  1}
        return 0;
      }
      $.each( items.sort(sortBy), function( index, item ) {
        var li;
        if ( item.category != currentCategory ) {
          ul.append( "
" + item.category + "
" );
          currentCategory = item.category;
        }
        li = that._renderItemData( ul, item );
        if ( item.category ) {
          li.attr( "aria-label", item.category + " : " + item.label );
        }
      });
    }
  });
  $("#query").attr('placeholder', '🔍').catcomplete({
      response: function( e, ui ) {
        if ( ! ui.content.length ) {
            $('#search').addClass('not-found')
                .find('#try-web-search').attr(
                    'href', 'https://www.google.com/search?q=site%3Adocs.perl6.org+'
                    + encodeURIComponent( $("#query").val() )
                );
        }
        else {
            $('#search').removeClass('not-found')
        }
      },
      open: function() {
        var ui_el = $('.ui-autocomplete');
        if ( ui_el.offset().left < 0 ) {
            ui_el.css({left: 0})
        }
      },
      position: { my: "right top", at: "right bottom", of: "#search div" },
      source: [
          PREDEFINED
          ITEMS
      ],
      select: function (event, ui) { window.location.href = ui.item.url; },
      autoFocus: true
  });
});
<|endoftext|>


<commit_before>// const chai = require('chai');
// const expect = chai.expect;
// const { entitySearch, entityFetch } = require('../../../src/server/routes/summary/entity');

describe ('Enrichment service: analysis', function () {
  //TODO - no live api calls to third-party services
});<commit_msg>First pass at ncbi summary tests<commit_after>// const chai = require('chai');
// const expect = chai.expect;
// const { entitySearch, entityFetch } = require('../../../src/server/routes/summary/entity');
// const config = require('../../../src/config');

// const NCBI_GENE_FETCH_URL = `${config.NCBI_EUTILS_BASE_URL}/esummary.fcgi?retmode=json&db=gene&id=`;
// const HGNC_SYMBOL_FETCH_URL = `${config.NCBI_EUTILS_BASE_URL}/esummary.fcgi?retmode=json&db=gene&id=`;
// const HGNC_SYMBOL_FETCH_URL = `${UNIPROT_API_BASE_URL}/proteins?offset=0&accession=${accessions.join(',')}`

// describe ('Summary Entity service', function () {
//   describe ('entityFetch', function () {

//     before(function() {
//       global.fetch = function(){
//         var args = Array.prototype.slice.call( arguments );
//         this.console.log( args );
//         return new Promise( resolve => {
//           resolve({
//             ok: true,
//             json: () => ({ "key": "value" })
//           });
//         });
//       };
//     });

//     it('Should be true', async () => {
//       const result =  await entityFetch( ['TP53'] );
//       expect( result ).not.to.be( null );
//     });
//   });
// });<|endoftext|>


<commit_before>(function() {
  'use strict';

  moj.Modules.FormErrors = {
    init: function() {
      _.bindAll(this, 'postToFormErrors', 'onAjaxSuccess', 'onAjaxError');
      this.bindEvents();
      this.loadTemplates();
    },

    bindEvents: function() {
      $('form')
        .on('submit', this.postToFormErrors)
        // Focus back on summary if field-error is focused and escape key is pressed
        .on('keyup', function(e) {
          var $target = $(e.target);
          if(e.keyCode === 27 && $target.is('.form-error')) {
            $target.closest('form').find('> .alert').focus();
          }
        })
        .on('blur', '.form-group', function(e) {
          $(e.target).removeAttr('tabindex');
        });

      $('[type=submit]').on('click', function(e) {
        var $target = $(e.target);
        $target.closest('form').attr('submit-name', $target.attr('name'));
      });

      // Focus on field with error
      $('#content').on('click', '.error-summary a', function(e) {
        e.preventDefault();
        var targetId = e.target.href.replace(/.*#/, '#');
        if(targetId.length < 2) {
          return;
        }
        var $target = $(targetId);

        $('html, body').animate({
          scrollTop: $target.offset().top - 20
        }, 300, function() {
          $target.attr('tabindex', -1).focus();
        });
      });
    },

    postToFormErrors: function(e) {
      this.$form = $(e.target);

      // Return if button has a name, which is attached as form attribute on click
      // (assuming secondary buttons)
      if(this.$form.attr('submit-name') ||
         this.$form.attr('method') && this.$form.attr('method').toLowerCase() === 'get') {
        return;
      }

      if (this.$form.length) {
        e.preventDefault();
        e.stopPropagation();
        $.ajax({
          type: 'OPTIONS',
          url: '',
          contentType: 'application/x-www-form-urlencoded',
          data: this.$form.serialize()
        })
        .done(this.onAjaxSuccess)
        .fail(this.onAjaxError);
      }
    },

    onAjaxSuccess: function(errors) {
      if (!$.isEmptyObject(errors)) {
        this.loadErrors(errors);
        var errorBanner = $('.alert-error:visible:first');

        if(!errorBanner.length) {
          return;
        }

        $('html, body').animate({
          scrollTop: errorBanner.offset().top - 20
        }, 300, function() {
          errorBanner.attr({'tabindex': -1}).focus();
        });
      } else {
        this.$form.off('submit');
        this.$form.submit();
      }
    },

    onAjaxError: function() {
      this.$form.off('submit');
      this.$form.submit();
    },

    formatErrors: function(errors) {
      var errorFields = {};

      (function fieldName (errorsObj, prefix) {
        prefix = (typeof prefix === 'undefined') ? '' : prefix + '-';
        for (var key in errorsObj) {
          var field = prefix + key;
          if ($.isArray(errorsObj[key])) {
            errorFields[field] = errorsObj[key];
          } else {
            fieldName(errorsObj[key], field);
          }
        }
      })(errors);

      return errorFields;
    },

    createErrorSummary: function(unattachedErrors) {
      var errorSummary = [];

      // Loop through errors on the page to retain the fields order
      $('.form-error').map(function() {
        var $this = $(this);

        if(!this.id || $this.hasClass('s-hidden') || $this.parent().hasClass('s-hidden')) {
          return;
        }
        var name = this.id.replace(/^field-/, '');

        errorSummary.push({
          label: $this.find('#field-label-' + name).text(),
          name: name,
          errors: $this.find('> .field-error p').map(function() {
            return $(this).text();
          })
        });
      });

      _.each(unattachedErrors, function(error) {
        errorSummary.push({
          errors: [error]
        });
      });

      return errorSummary;
    },

    loadErrors: function(errors) {
      var errorFields = this.formatErrors(errors);
      var self = this;
      var unattachedErrors = [];

      this.clearErrors();

      function insertError($afterElement, errors, fieldName) {
        $afterElement.after(self.fieldError({
          errors: errors,
          fieldName: fieldName
        }));
      }

      function addSimpleErrors(errors, fieldName) {
        if(!errors.length) {
          return;
        }

        $('#field-' + fieldName)
          .addClass('form-error')
          .attr({
            'aria-invalid': true,
            'aria-describedby': 'error-' + fieldName
          });

        var label = $('#field-label-' + fieldName);

        if(!label.length) {
          unattachedErrors = _.extend(unattachedErrors, errors);
        } else if(label.is('legend')) {
          insertError(label, errors, fieldName);
        } else {
          insertError(label.closest('.form-group-label'), errors, fieldName);
        }
      }

      function addSubformErrors(errors, fieldName) {
        if(!errors.length) {
          return;
        }
        _.each(errors, function(subformErrors) {
          addErrors(subformErrors[1], fieldName + '-' + subformErrors[0]);
        });
      }

      function addRepeatedFieldErrors(errors, fieldName) {
        if(!errors.length) {
          return;
        }
        // Multiple forms (e.g. properties)
        _.each(errors, function(errors) {
          _.each(errors._errors, function(subformErrors, subformFieldName) {
            addErrors(subformErrors, fieldName + '-' + errors._index + '-' + subformFieldName);
          });
        });
      }

      function addErrors(errors, fieldName) {
        addSimpleErrors(_.filter(errors, _.isString), fieldName);
        addSubformErrors(_.filter(errors, _.isArray), fieldName);
        addRepeatedFieldErrors(_.filter(errors, function(error) {
          return _.isObject(error) && !_.isArray(error);
        }), fieldName);
      }

      _.each(errorFields, addErrors);

      if(this.$form.data('error-banner') !== false) {
        this.$form.prepend(this.mainFormError({ errors: this.createErrorSummary(unattachedErrors)}));
      }

      // Report to GA about form errors
      var errorFieldNames = _.keys(errorFields);
      if(!window.ga) return;
      window.ga('send', 'event', 'form-errors',
        window.location.pathname,
        errorFieldNames.join('|'),
        errorFieldNames.length
      )
    },

    loadTemplates: function() {
      this.mainFormError = _.template($('#mainFormError').html());
      this.fieldError = _.template($('#fieldError').html());
    },

    clearErrors: function() {
      $('.form-row.field-error').remove();
      $('.alert.alert-error').remove();
      $('.form-error')
        .removeClass('form-error')
        .removeAttr('aria-invalid');
    }
  };
}());
<commit_msg>Fix lint warnings<commit_after>(function() {
  'use strict';

  moj.Modules.FormErrors = {
    init: function() {
      _.bindAll(this, 'postToFormErrors', 'onAjaxSuccess', 'onAjaxError');
      this.bindEvents();
      this.loadTemplates();
    },

    bindEvents: function() {
      $('form')
        .on('submit', this.postToFormErrors)
        // Focus back on summary if field-error is focused and escape key is pressed
        .on('keyup', function(e) {
          var $target = $(e.target);
          if(e.keyCode === 27 && $target.is('.form-error')) {
            $target.closest('form').find('> .alert').focus();
          }
        })
        .on('blur', '.form-group', function(e) {
          $(e.target).removeAttr('tabindex');
        });

      $('[type=submit]').on('click', function(e) {
        var $target = $(e.target);
        $target.closest('form').attr('submit-name', $target.attr('name'));
      });

      // Focus on field with error
      $('#content').on('click', '.error-summary a', function(e) {
        e.preventDefault();
        var targetId = e.target.href.replace(/.*#/, '#');
        if(targetId.length < 2) {
          return;
        }
        var $target = $(targetId);

        $('html, body').animate({
          scrollTop: $target.offset().top - 20
        }, 300, function() {
          $target.attr('tabindex', -1).focus();
        });
      });
    },

    postToFormErrors: function(e) {
      this.$form = $(e.target);

      // Return if button has a name, which is attached as form attribute on click
      // (assuming secondary buttons)
      if(this.$form.attr('submit-name') ||
         this.$form.attr('method') && this.$form.attr('method').toLowerCase() === 'get') {
        return;
      }

      if (this.$form.length) {
        e.preventDefault();
        e.stopPropagation();
        $.ajax({
          type: 'OPTIONS',
          url: '',
          contentType: 'application/x-www-form-urlencoded',
          data: this.$form.serialize()
        })
        .done(this.onAjaxSuccess)
        .fail(this.onAjaxError);
      }
    },

    onAjaxSuccess: function(errors) {
      if (!$.isEmptyObject(errors)) {
        this.loadErrors(errors);
        var errorBanner = $('.alert-error:visible:first');

        if(!errorBanner.length) {
          return;
        }

        $('html, body').animate({
          scrollTop: errorBanner.offset().top - 20
        }, 300, function() {
          errorBanner.attr({'tabindex': -1}).focus();
        });
      } else {
        this.$form.off('submit');
        this.$form.submit();
      }
    },

    onAjaxError: function() {
      this.$form.off('submit');
      this.$form.submit();
    },

    formatErrors: function(errors) {
      var errorFields = {};

      (function fieldName (errorsObj, prefix) {
        prefix = (typeof prefix === 'undefined') ? '' : prefix + '-';
        for (var key in errorsObj) {
          var field = prefix + key;
          if ($.isArray(errorsObj[key])) {
            errorFields[field] = errorsObj[key];
          } else {
            fieldName(errorsObj[key], field);
          }
        }
      })(errors);

      return errorFields;
    },

    createErrorSummary: function(unattachedErrors) {
      var errorSummary = [];

      // Loop through errors on the page to retain the fields order
      $('.form-error').map(function() {
        var $this = $(this);

        if(!this.id || $this.hasClass('s-hidden') || $this.parent().hasClass('s-hidden')) {
          return;
        }
        var name = this.id.replace(/^field-/, '');

        errorSummary.push({
          label: $this.find('#field-label-' + name).text(),
          name: name,
          errors: $this.find('> .field-error p').map(function() {
            return $(this).text();
          })
        });
      });

      _.each(unattachedErrors, function(error) {
        errorSummary.push({
          errors: [error]
        });
      });

      return errorSummary;
    },

    loadErrors: function(errors) {
      var errorFields = this.formatErrors(errors);
      var self = this;
      var unattachedErrors = [];

      this.clearErrors();

      function insertError($afterElement, errors, fieldName) {
        $afterElement.after(self.fieldError({
          errors: errors,
          fieldName: fieldName
        }));
      }

      function addSimpleErrors(errors, fieldName) {
        if(!errors.length) {
          return;
        }

        $('#field-' + fieldName)
          .addClass('form-error')
          .attr({
            'aria-invalid': true,
            'aria-describedby': 'error-' + fieldName
          });

        var label = $('#field-label-' + fieldName);

        if(!label.length) {
          unattachedErrors = _.extend(unattachedErrors, errors);
        } else if(label.is('legend')) {
          insertError(label, errors, fieldName);
        } else {
          insertError(label.closest('.form-group-label'), errors, fieldName);
        }
      }

      function addSubformErrors(errors, fieldName) {
        if(!errors.length) {
          return;
        }
        _.each(errors, function(subformErrors) {
          addErrors(subformErrors[1], fieldName + '-' + subformErrors[0]);
        });
      }

      function addRepeatedFieldErrors(errors, fieldName) {
        if(!errors.length) {
          return;
        }
        // Multiple forms (e.g. properties)
        _.each(errors, function(errors) {
          _.each(errors._errors, function(subformErrors, subformFieldName) {
            addErrors(subformErrors, fieldName + '-' + errors._index + '-' + subformFieldName);
          });
        });
      }

      function addErrors(errors, fieldName) {
        addSimpleErrors(_.filter(errors, _.isString), fieldName);
        addSubformErrors(_.filter(errors, _.isArray), fieldName);
        addRepeatedFieldErrors(_.filter(errors, function(error) {
          return _.isObject(error) && !_.isArray(error);
        }), fieldName);
      }

      _.each(errorFields, addErrors);

      if(this.$form.data('error-banner') !== false) {
        this.$form.prepend(this.mainFormError({ errors: this.createErrorSummary(unattachedErrors)}));
      }

      // Report to GA about form errors
      var errorFieldNames = _.keys(errorFields);
      if(!window.ga) {
        return;
      }
      window.ga('send', 'event', 'form-errors',
        window.location.pathname,
        errorFieldNames.join('|'),
        errorFieldNames.length
      );
    },

    loadTemplates: function() {
      this.mainFormError = _.template($('#mainFormError').html());
      this.fieldError = _.template($('#fieldError').html());
    },

    clearErrors: function() {
      $('.form-row.field-error').remove();
      $('.alert.alert-error').remove();
      $('.form-error')
        .removeClass('form-error')
        .removeAttr('aria-invalid');
    }
  };
}());
<|endoftext|>


<commit_before>// can't use export * with babel: see https://github.com/babel/babel/issues/4446
export {convertStudent} from './convert-imported-student'

export {getStudentInfo} from './import-student'
<commit_msg>export the rest of the used things from import-student<commit_after>// can't use export * with babel: see https://github.com/babel/babel/issues/4446
export {convertStudent} from './convert-imported-student'

export {
	getStudentInfo,
	checkIfLoggedIn,
	ExtensionNotLoadedError,
	ExtensionTooOldError,
} from './import-student'
<|endoftext|>


<commit_before>/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

var SOGoDragHandlesInterface = {
    leftMargin: 180,
    topMargin: 160,
    dhType: null,
    dhLimit: -1,
    origX: -1,
    origLeft: -1,
    origRight: -1,
    origY: -1,
    origUpper: -1,
    origLower: -1,
    delta: -1,
    btn: null,
    leftBlock: null,
    rightBlock: null,
    upperBlock: null,
    lowerBlock: null,
    startHandleDraggingBound: null,
    stopHandleDraggingBound: null,
    moveBound: null,
    delayedSave: null,
    bind: function () {
        this.startHandleDraggingBound = this.startHandleDragging.bindAsEventListener(this);
        this.observe("mousedown", this.startHandleDraggingBound, false);
    },
    adjust: function () {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            this.dhLimit = window.width() - 20;
            if (parseInt(this.getStyle("left")) > this.dhLimit) {
                this.setStyle({ left: this.dhLimit + "px" });
                this.rightBlock.setStyle({ left: (this.dhLimit) + 'px' });
                this.leftBlock.setStyle({ width: (this.dhLimit) + 'px' });
                if (this.delayedSave) window.clearTimeout(this.delayedSave);
                this.delayedSave = this.saveDragHandleState.delay(3, this.dhType, this.dhLimit, this.saveDragHandleStateCallback);
            }
        }
        else if (this.dhType == 'vertical') {
            var windowHeight = window.height();
            this.dhLimit = windowHeight - 20 - this.upperBlock.cumulativeOffset().top + this.upperBlock.offsetTop;
            if (parseInt(this.getStyle("top")) > this.dhLimit &&
                windowHeight > this.topMargin) {
                this.setStyle({ top: this.dhLimit + 'px' });
                this.lowerBlock.setStyle({ top: this.dhLimit + 'px' });
                this.upperBlock.setStyle({ height: (this.dhLimit - this.upperBlock.offsetTop) + 'px' });
                if (this.delayedSave) window.clearTimeout(this.delayedSave);
                this.delayedSave = this.saveDragHandleState.delay(3, this.dhType, this.dhLimit, this.saveDragHandleStateCallback);
            }
        }
    },
    _determineType: function () {
        if (this.leftBlock && this.rightBlock)
            this.dhType = 'horizontal';
        else if (this.upperBlock && this.lowerBlock)
            this.dhType = 'vertical';
    },
    startHandleDragging: function (event) {
        this.btn = event.button;
        if (!this.dhType)
            this._determineType();
        var targ = getTarget(event);
        if (targ.nodeType == 1) {
            if (this.dhType == 'horizontal') {
                this.dhLimit = window.width() - 20;
                this.origX = this.offsetLeft;
                this.origLeft = this.leftBlock.offsetWidth;
                this.delta = 0;
                this.origRight = this.rightBlock.offsetLeft - 5;
                document.body.setStyle({ cursor: "e-resize" });
            } else if (this.dhType == 'vertical') {
                this.dhLimit = window.height() - 20;
                this.origY = this.offsetTop;
                this.origUpper = this.upperBlock.offsetHeight;
                var pointY = Event.pointerY(event);
                this.delta = pointY - this.offsetTop - 5;
                this.origLower = this.lowerBlock.offsetTop - 5;
                document.body.setStyle({ cursor: "n-resize" });
            }
            this.stopHandleDraggingBound = this.stopHandleDragging.bindAsEventListener(this);
            if (Prototype.Browser.IE)
                Event.observe(document.body, "mouseup", this.stopHandleDraggingBound);
            else
                Event.observe(window, "mouseup", this.stopHandleDraggingBound);
            this.moveBound = this.move.bindAsEventListener(this);
            Event.observe(document.body, "mousemove", this.moveBound);
            this.move(event);
        }

        return false;
    },
    stopHandleDragging: function (event) {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            var pointerX = Event.pointerX(event);
            if (pointerX <= this.leftMargin) {
                this.rightBlock.setStyle({ left: (this.leftMargin) + 'px' });
                this.leftBlock.setStyle({ width: (this.leftMargin) + 'px' });
            }
            else if (pointerX >= this.dhLimit) {
                this.rightBlock.setStyle({ left: (this.dhLimit) + 'px' });
                this.leftBlock.setStyle({ width: (this.dhLimit) + 'px' });
            }
            else {
                var deltaX = Math.floor(pointerX - this.origX - (this.offsetWidth / 2));
                this.rightBlock.setStyle({ left: (this.origRight + deltaX) + 'px' });
                this.leftBlock.setStyle({ width: (this.origLeft + deltaX) + 'px' });
            }
            this.saveDragHandleState(this.dhType, parseInt(this.leftBlock.getStyle("width")));
        }
        else if (this.dhType == 'vertical') {
            var pointerY = Event.pointerY(event);
            var deltaY;
            if (pointerY <= this.topMargin)
                deltaY = Math.floor(this.topMargin - this.origY - (this.offsetHeight / 2));
            else if (pointerY >= this.dhLimit)
                deltaY = Math.floor(this.dhLimit - this.origY - (this.offsetHeight / 2));
            else
                deltaY = Math.floor(pointerY - this.origY - (this.offsetHeight / 2));
            this.lowerBlock.setStyle({ top: (this.origLower + deltaY - this.delta) + 'px' });
            this.upperBlock.setStyle({ height: (this.origUpper + deltaY - this.delta) + 'px' });
            //this.lowerBlock.fire("handle:resize");
            this.upperBlock.fire("handle:resize");
            this.saveDragHandleState(this.dhType, parseInt(this.lowerBlock.getStyle("top")));
        }
        if (Prototype.Browser.IE)
            Event.stopObserving(document.body, "mouseup", this.stopHandleDraggingBound);
        else
            Event.stopObserving(window, "mouseup", this.stopHandleDraggingBound);
        Event.stopObserving(document.body, "mousemove", this.moveBound);

        document.body.setAttribute('style', '');
        document.body.setStyle({ cursor: "default" });
        this.fire("handle:dragged");

        Event.stop(event);
    },
    move: function (event) {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            var hX =  Event.pointerX(event);
            var width = this.offsetWidth;
            if (hX < this.leftMargin)
                hX = this.leftMargin + Math.floor(width / 2);
            else if (hX > this.dhLimit)
                hX = this.dhLimit + Math.floor(width / 2);
            var newLeft = Math.floor(hX - (width / 2));
            this.setStyle({ left: newLeft + 'px' });
        } else if (this.dhType == 'vertical') {
            var hY = Event.pointerY(event);
            var height = this.offsetHeight;
            if (hY < this.topMargin)
                hY = this.topMargin;
            else if (hY > this.dhLimit)
                hY = this.dhLimit;

            var newTop = Math.floor(hY - (height / 2)) - this.delta;
            this.setStyle({ top: newTop + 'px' });
        }
        Event.stop(event);
        if (Prototype.Browser.IE && event.button != this.btn)
            this.stopHandleDragging(event);
    },
    doubleClick: function (event) {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            var lLeft = this.leftBlock.offsetLeft;

            if (this.offsetLeft > lLeft) {
                var leftdelta = this.rightBlock.offsetLeft - this.offsetLeft;

                this.setStyle({ left: lLeft + 'px' });
                this.leftBlock.setStyle({ width: '0px' });
                this.rightBlock.setStyle({ left: (lLeft + leftdelta) + 'px' });
            }
        } else if (this.dhType == 'vertical') {
            var uTop = this.upperBlock.offsetTop;

            if (this.offsetTop > uTop) {
                var topdelta = this.lowerBlock.offsetTop - this.offsetTop;

                this.setStyle({ top: uTop + 'px' });
                this.upperBlock.setStyle({ width: '0px' });
                this.lowerBlock.setStyle({ top: (uTop + topdelta) + 'px' });
            }
        }
    },
    saveDragHandleState: function (type, position, fcn) {
        if (!$(document.body).hasClassName("popup")) {
            var urlstr =  ApplicationBaseURL + "saveDragHandleState"
            + "?" + type + "=" + position;
            var callbackFunction = fcn || this.saveDragHandleStateCallback;
            triggerAjaxRequest(urlstr, callbackFunction);
        }
    },
    saveDragHandleStateCallback: function (http) {
        if (isHttpStatus204(http.status)) {
            log ("Drag handle state saved");
        }
        else if (http.readyState == 4) {
            log ("Can't save handle state");
        }
    }
};
<commit_msg>Increased minimum space above horizontal drag handle bar.<commit_after>/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

var SOGoDragHandlesInterface = {
    leftMargin: 180,
    topMargin: 180,
    dhType: null,
    dhLimit: -1,
    origX: -1,
    origLeft: -1,
    origRight: -1,
    origY: -1,
    origUpper: -1,
    origLower: -1,
    delta: -1,
    btn: null,
    leftBlock: null,
    rightBlock: null,
    upperBlock: null,
    lowerBlock: null,
    startHandleDraggingBound: null,
    stopHandleDraggingBound: null,
    moveBound: null,
    delayedSave: null,
    bind: function () {
        this.startHandleDraggingBound = this.startHandleDragging.bindAsEventListener(this);
        this.observe("mousedown", this.startHandleDraggingBound, false);
    },
    adjust: function () {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            this.dhLimit = window.width() - 20;
            if (parseInt(this.getStyle("left")) > this.dhLimit) {
                this.setStyle({ left: this.dhLimit + "px" });
                this.rightBlock.setStyle({ left: (this.dhLimit) + 'px' });
                this.leftBlock.setStyle({ width: (this.dhLimit) + 'px' });
                if (this.delayedSave) window.clearTimeout(this.delayedSave);
                this.delayedSave = this.saveDragHandleState.delay(3, this.dhType, this.dhLimit, this.saveDragHandleStateCallback);
            }
        }
        else if (this.dhType == 'vertical') {
            var windowHeight = window.height();
            this.dhLimit = windowHeight - 20 - this.upperBlock.cumulativeOffset().top + this.upperBlock.offsetTop;
            if (parseInt(this.getStyle("top")) > this.dhLimit &&
                windowHeight > this.topMargin) {
                this.setStyle({ top: this.dhLimit + 'px' });
                this.lowerBlock.setStyle({ top: this.dhLimit + 'px' });
                this.upperBlock.setStyle({ height: (this.dhLimit - this.upperBlock.offsetTop) + 'px' });
                if (this.delayedSave) window.clearTimeout(this.delayedSave);
                this.delayedSave = this.saveDragHandleState.delay(3, this.dhType, this.dhLimit, this.saveDragHandleStateCallback);
            }
        }
    },
    _determineType: function () {
        if (this.leftBlock && this.rightBlock)
            this.dhType = 'horizontal';
        else if (this.upperBlock && this.lowerBlock)
            this.dhType = 'vertical';
    },
    startHandleDragging: function (event) {
        this.btn = event.button;
        if (!this.dhType)
            this._determineType();
        var targ = getTarget(event);
        if (targ.nodeType == 1) {
            if (this.dhType == 'horizontal') {
                this.dhLimit = window.width() - 20;
                this.origX = this.offsetLeft;
                this.origLeft = this.leftBlock.offsetWidth;
                this.delta = 0;
                this.origRight = this.rightBlock.offsetLeft - 5;
                document.body.setStyle({ cursor: "e-resize" });
            } else if (this.dhType == 'vertical') {
                this.dhLimit = window.height() - 20;
                this.origY = this.offsetTop;
                this.origUpper = this.upperBlock.offsetHeight;
                var pointY = Event.pointerY(event);
                this.delta = pointY - this.offsetTop - 5;
                this.origLower = this.lowerBlock.offsetTop - 5;
                document.body.setStyle({ cursor: "n-resize" });
            }
            this.stopHandleDraggingBound = this.stopHandleDragging.bindAsEventListener(this);
            if (Prototype.Browser.IE)
                Event.observe(document.body, "mouseup", this.stopHandleDraggingBound);
            else
                Event.observe(window, "mouseup", this.stopHandleDraggingBound);
            this.moveBound = this.move.bindAsEventListener(this);
            Event.observe(document.body, "mousemove", this.moveBound);
            this.move(event);
        }

        return false;
    },
    stopHandleDragging: function (event) {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            var pointerX = Event.pointerX(event);
            if (pointerX <= this.leftMargin) {
                this.rightBlock.setStyle({ left: (this.leftMargin) + 'px' });
                this.leftBlock.setStyle({ width: (this.leftMargin) + 'px' });
            }
            else if (pointerX >= this.dhLimit) {
                this.rightBlock.setStyle({ left: (this.dhLimit) + 'px' });
                this.leftBlock.setStyle({ width: (this.dhLimit) + 'px' });
            }
            else {
                var deltaX = Math.floor(pointerX - this.origX - (this.offsetWidth / 2));
                this.rightBlock.setStyle({ left: (this.origRight + deltaX) + 'px' });
                this.leftBlock.setStyle({ width: (this.origLeft + deltaX) + 'px' });
            }
            this.saveDragHandleState(this.dhType, parseInt(this.leftBlock.getStyle("width")));
        }
        else if (this.dhType == 'vertical') {
            var pointerY = Event.pointerY(event);
            var deltaY;
            if (pointerY <= this.topMargin)
                deltaY = Math.floor(this.topMargin - this.origY - (this.offsetHeight / 2));
            else if (pointerY >= this.dhLimit)
                deltaY = Math.floor(this.dhLimit - this.origY - (this.offsetHeight / 2));
            else
                deltaY = Math.floor(pointerY - this.origY - (this.offsetHeight / 2));
            this.lowerBlock.setStyle({ top: (this.origLower + deltaY - this.delta) + 'px' });
            this.upperBlock.setStyle({ height: (this.origUpper + deltaY - this.delta) + 'px' });
            //this.lowerBlock.fire("handle:resize");
            this.upperBlock.fire("handle:resize");
            this.saveDragHandleState(this.dhType, parseInt(this.lowerBlock.getStyle("top")));
        }
        if (Prototype.Browser.IE)
            Event.stopObserving(document.body, "mouseup", this.stopHandleDraggingBound);
        else
            Event.stopObserving(window, "mouseup", this.stopHandleDraggingBound);
        Event.stopObserving(document.body, "mousemove", this.moveBound);

        document.body.setAttribute('style', '');
        document.body.setStyle({ cursor: "default" });
        this.fire("handle:dragged");

        Event.stop(event);
    },
    move: function (event) {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            var hX =  Event.pointerX(event);
            var width = this.offsetWidth;
            if (hX < this.leftMargin)
                hX = this.leftMargin + Math.floor(width / 2);
            else if (hX > this.dhLimit)
                hX = this.dhLimit + Math.floor(width / 2);
            var newLeft = Math.floor(hX - (width / 2));
            this.setStyle({ left: newLeft + 'px' });
        } else if (this.dhType == 'vertical') {
            var hY = Event.pointerY(event);
            var height = this.offsetHeight;
            if (hY < this.topMargin)
                hY = this.topMargin;
            else if (hY > this.dhLimit)
                hY = this.dhLimit;

            var newTop = Math.floor(hY - (height / 2)) - this.delta;
            this.setStyle({ top: newTop + 'px' });
        }
        Event.stop(event);
        if (Prototype.Browser.IE && event.button != this.btn)
            this.stopHandleDragging(event);
    },
    doubleClick: function (event) {
        if (!this.dhType)
            this._determineType();
        if (this.dhType == 'horizontal') {
            var lLeft = this.leftBlock.offsetLeft;

            if (this.offsetLeft > lLeft) {
                var leftdelta = this.rightBlock.offsetLeft - this.offsetLeft;

                this.setStyle({ left: lLeft + 'px' });
                this.leftBlock.setStyle({ width: '0px' });
                this.rightBlock.setStyle({ left: (lLeft + leftdelta) + 'px' });
            }
        } else if (this.dhType == 'vertical') {
            var uTop = this.upperBlock.offsetTop;

            if (this.offsetTop > uTop) {
                var topdelta = this.lowerBlock.offsetTop - this.offsetTop;

                this.setStyle({ top: uTop + 'px' });
                this.upperBlock.setStyle({ width: '0px' });
                this.lowerBlock.setStyle({ top: (uTop + topdelta) + 'px' });
            }
        }
    },
    saveDragHandleState: function (type, position, fcn) {
        if (!$(document.body).hasClassName("popup")) {
            var urlstr =  ApplicationBaseURL + "saveDragHandleState"
            + "?" + type + "=" + position;
            var callbackFunction = fcn || this.saveDragHandleStateCallback;
            triggerAjaxRequest(urlstr, callbackFunction);
        }
    },
    saveDragHandleStateCallback: function (http) {
        if (isHttpStatus204(http.status)) {
            log ("Drag handle state saved");
        }
        else if (http.readyState == 4) {
            log ("Can't save handle state");
        }
    }
};
<|endoftext|>


<commit_before>var dgram = require("dgram");
var fs = require('fs');
var child = require('child_process');

var pulsar;
var server = dgram.createSocket("udp4");

server.on("listening", function () {
  var address = server.address();
  //console.log("server listening " +
  //  address.address + ":" + address.port);
});

server.on("error", function (err) {
  //console.log("server error:\n" + err.stack);
  server.close();
  console.log("dgram socket failure: " + err.stack);
});

server.on("message", function (msg, rinfo) {
  server.recievedPulse = JSON.parse(msg);

  if (server.recievedPulse.supernova) {
    if (server.recievedPulse.action &&
        server.recievedPulse.action === "die") {

      console.log("DIE RECIEVED");
      if (pulsar) {
        pulsar.kill('SIGTERM');
        pulsar = undefined;
      }
      process.exit();
    }

    if (!pulsar) {
      copyFile('/Volumes/Transit/PULSAR/Pulsar.json', './Pulsar.json', function() {
        console.log("Pulsar.json downloaded");
        copyFile('/Volumes/Transit/PULSAR/PULSAR.jar', './Pulsar.jar', function() {
          console.log("Pulsar.jar downloaded");
          //pulsar = child.spawn('java', ['-jar', 'PULSAR.jar']);
          pulsar = child.spawn("/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome" ['--start-fullscreen', 'http://localhost:3000']);

          pulsar.stdout.on('data', function (data) {
            console.log('stdout: ' + data);
          });

          pulsar.stderr.on('data', function (data) {
            console.log('stderr: ' + data);
          });

          pulsar.on('close', function (code) {
            console.log('pulsar process exited with code ' + code);
          });
        });
      });
    } else {
      pulsar.kill('SIGTERM');
      pulsar = undefined;
    }
  }
});

// stolen from http://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js
function copyFile(source, target, cb) {
  var cbCalled = false;

  var rd = fs.createReadStream(source);
  rd.on("error", function(err) {
    done(err);
  });
  var wr = fs.createWriteStream(target);
  wr.on("error", function(err) {
    done(err);
  });
  wr.on("close", function(ex) {
    done();
  });
  rd.pipe(wr);

  function done(err) {
    if (!cbCalled) {
      cb(err);
      cbCalled = true;
    }
  }
}

server.bind(6661);
<commit_msg>Get rid of file downloads since we're all chrome now<commit_after>var dgram = require("dgram");
var fs = require('fs');
var child = require('child_process');

var pulsar;
var server = dgram.createSocket("udp4");

server.on("listening", function () {
  var address = server.address();
  //console.log("server listening " +
  //  address.address + ":" + address.port);
});

server.on("error", function (err) {
  //console.log("server error:\n" + err.stack);
  server.close();
  console.log("dgram socket failure: " + err.stack);
});

server.on("message", function (msg, rinfo) {
  server.recievedPulse = JSON.parse(msg);

  if (server.recievedPulse.supernova) {
    if (server.recievedPulse.action &&
        server.recievedPulse.action === "die") {

      console.log("DIE RECIEVED");
      if (pulsar) {
        pulsar.kill('SIGTERM');
        pulsar = undefined;
      }
      process.exit();
    }

    if (!pulsar) {
      console.log("Supernova detected, starting Chrome containing PULSAR");
      //pulsar = child.spawn('java', ['-jar', 'PULSAR.jar']);
      pulsar = child.spawn("/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome" ['--start-fullscreen', 'http://localhost:3000']);

      pulsar.stdout.on('data', function (data) {
        console.log('stdout: ' + data);
      });

      pulsar.stderr.on('data', function (data) {
        console.log('stderr: ' + data);
      });

      pulsar.on('close', function (code) {
        console.log('pulsar process exited with code ' + code);
      });
    } else {
      console.log("Supernova detected, killing Chrome");
      pulsar.kill('SIGTERM');
      pulsar = undefined;
    }
  }
});

// stolen from http://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js
function copyFile(source, target, cb) {
  var cbCalled = false;

  var rd = fs.createReadStream(source);
  rd.on("error", function(err) {
    done(err);
  });
  var wr = fs.createWriteStream(target);
  wr.on("error", function(err) {
    done(err);
  });
  wr.on("close", function(ex) {
    done();
  });
  rd.pipe(wr);

  function done(err) {
    if (!cbCalled) {
      cb(err);
      cbCalled = true;
    }
  }
}

server.bind(6661);
<|endoftext|>


<commit_before>'use strict';

const {
  readFileSync,
  writeFileSync,
  existsSync,
  unlinkSync,
  renameSync,
} = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const tar = require('tar');
const validatePackageName = require('validate-npm-package-name');
const pm = require('./package-manager');

function readPackageManifest(file) {
  return JSON.parse(readFileSync(file).toString('utf-8'));
}

function writePackageManifest(file, manifest) {
  writeFileSync(file, JSON.stringify(manifest, null, 2));
}

function sortObjectKeys(input) {
  const result = {};
  Object.keys(input)
    .sort()
    .forEach(k => {
      result[k] = input[k];
    });
  return result;
}

function mergePackageManifest(oldManifest, newManifest) {
  return Object.assign({}, newManifest, oldManifest, {
    dependencies: sortObjectKeys(
      Object.assign(newManifest.dependencies, oldManifest.dependencies)
    ),
    devDependencies: sortObjectKeys(
      Object.assign(newManifest.devDependencies, oldManifest.devDependencies)
    ),
  });
}

function getValidatedTemplateName(name, root) {
  if (name.indexOf('@') > -1) {
    if (!existsSync(path.resolve(root, name))) {
      return name;
    }
  }
  const validationResult = validatePackageName(name);
  if (
    !(
      validationResult.validForNewPackages ||
      validationResult.validForOldPackages
    )
  ) {
    return path.resolve(root, name);
  } else if (name.indexOf('hops-template') === 0) {
    return name;
  }
  return null;
}

function isCLIInstalledGlobally() {
  try {
    execSync('hops --version', { stdio: 'ignore' });
    return true;
  } catch (_) {
    return false;
  }
}

function init(root, appName, options) {
  const appRoot = path.resolve(root, appName);
  const template = getValidatedTemplateName(options.template, root);
  const pathToPackageManifest = path.resolve(appRoot, 'package.json');
  const oldPackageManifest = readPackageManifest(pathToPackageManifest);
  let tarball = null;
  options.npm = options.npm || !pm.isGlobalCliUsingYarn(appRoot);

  if (template) {
    tarball = pm.getTarball(template, options);
  } else {
    console.error(
      'Could not find a hops-template with the specified name:',
      options.template
    );
    process.exit(1);
  }

  if (tarball) {
    tar
      .extract({
        file: tarball,
        strip: 1,
      })
      .then(() => {
        unlinkSync(tarball);

        ['_gitignore', '_npmrc'].forEach(ignoredFile => {
          if (existsSync(path.join(appRoot, ignoredFile))) {
            renameSync(
              path.join(appRoot, ignoredFile),
              path.join(appRoot, '.' + ignoredFile.slice(1))
            );
          }
        });

        const newPackageManifest = readPackageManifest(pathToPackageManifest);
        writePackageManifest(
          pathToPackageManifest,
          mergePackageManifest(oldPackageManifest, newPackageManifest)
        );
        pm.installPackages([], null, options);

        console.log('Hooray \\o/');
        console.log('Your project has been successfully created.');
        console.log(
          'You should change into its directory and execute',
          '`' +
            (isCLIInstalledGlobally()
              ? 'hops'
              : pm.isGlobalCliUsingYarn(appRoot)
                ? 'yarn'
                : 'npm'),
          'start`',
          'to fire up a development server with hot module reloading.'
        );
        console.log(
          'To see a list of available commands through Hops presets execute:',
          isCLIInstalledGlobally()
            ? '`hops`'
            : (pm.isGlobalCliUsingYarn(appRoot)
                ? '`yarn hops`'
                : '`npx hops@' + options.hopsVersion + '`') +
              ' or install the "hops" package globally.'
        );
      })
      .catch(error => {
        console.error('Error while unpacking tar archive:', tarball);
        console.error(error);
      });
  } else {
    console.error('Could not download tarball for:', template);
    process.exit(1);
  }
}
module.exports = { init };
<commit_msg>chore(cli): make linter happy<commit_after>'use strict';

const {
  readFileSync,
  writeFileSync,
  existsSync,
  unlinkSync,
  renameSync,
} = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const tar = require('tar');
const validatePackageName = require('validate-npm-package-name');
const pm = require('./package-manager');

function readPackageManifest(file) {
  return JSON.parse(readFileSync(file).toString('utf-8'));
}

function writePackageManifest(file, manifest) {
  writeFileSync(file, JSON.stringify(manifest, null, 2));
}

function sortObjectKeys(input) {
  const result = {};
  Object.keys(input)
    .sort()
    .forEach(k => {
      result[k] = input[k];
    });
  return result;
}

function mergePackageManifest(oldManifest, newManifest) {
  return Object.assign({}, newManifest, oldManifest, {
    dependencies: sortObjectKeys(
      Object.assign(newManifest.dependencies, oldManifest.dependencies)
    ),
    devDependencies: sortObjectKeys(
      Object.assign(newManifest.devDependencies, oldManifest.devDependencies)
    ),
  });
}

function getValidatedTemplateName(name, root) {
  if (name.indexOf('@') > -1) {
    if (!existsSync(path.resolve(root, name))) {
      return name;
    }
  }
  const validationResult = validatePackageName(name);
  if (
    !(
      validationResult.validForNewPackages ||
      validationResult.validForOldPackages
    )
  ) {
    return path.resolve(root, name);
  } else if (name.indexOf('hops-template') === 0) {
    return name;
  }
  return null;
}

function isCLIInstalledGlobally() {
  try {
    execSync('hops --version', { stdio: 'ignore' });
    return true;
  } catch (_) {
    return false;
  }
}

function init(root, appName, options) {
  const appRoot = path.resolve(root, appName);
  const template = getValidatedTemplateName(options.template, root);
  const pathToPackageManifest = path.resolve(appRoot, 'package.json');
  const oldPackageManifest = readPackageManifest(pathToPackageManifest);
  let tarball = null;
  options.npm = options.npm || !pm.isGlobalCliUsingYarn(appRoot);

  if (template) {
    tarball = pm.getTarball(template, options);
  } else {
    console.error(
      'Could not find a hops-template with the specified name:',
      options.template
    );
    process.exit(1);
  }

  if (tarball) {
    tar
      .extract({
        file: tarball,
        strip: 1,
      })
      .then(() => {
        unlinkSync(tarball);

        ['_gitignore', '_npmrc'].forEach(ignoredFile => {
          if (existsSync(path.join(appRoot, ignoredFile))) {
            renameSync(
              path.join(appRoot, ignoredFile),
              path.join(appRoot, '.' + ignoredFile.slice(1))
            );
          }
        });

        const newPackageManifest = readPackageManifest(pathToPackageManifest);
        writePackageManifest(
          pathToPackageManifest,
          mergePackageManifest(oldPackageManifest, newPackageManifest)
        );
        pm.installPackages([], null, options);

        console.log('Hooray \\o/');
        console.log('Your project has been successfully created.');
        console.log(
          'You should change into its directory and execute',
          '`' +
            (isCLIInstalledGlobally()
              ? 'hops'
              : pm.isGlobalCliUsingYarn(appRoot)
              ? 'yarn'
              : 'npm'),
          'start`',
          'to fire up a development server with hot module reloading.'
        );
        console.log(
          'To see a list of available commands through Hops presets execute:',
          isCLIInstalledGlobally()
            ? '`hops`'
            : (pm.isGlobalCliUsingYarn(appRoot)
                ? '`yarn hops`'
                : '`npx hops@' + options.hopsVersion + '`') +
                ' or install the "hops" package globally.'
        );
      })
      .catch(error => {
        console.error('Error while unpacking tar archive:', tarball);
        console.error(error);
      });
  } else {
    console.error('Could not download tarball for:', template);
    process.exit(1);
  }
}
module.exports = { init };
<|endoftext|>


<commit_before>;(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof exports === 'object') {
        module.exports = factory();
    } else {
        root.iNotify = factory();
    }
}(this, function(root, undefined) {
    var repeatableEffects = ['flash', 'scroll']
    var iNotify = {
        init:function(config){
            this.interval = config.interval || 200//响应时长
            this.effect = config.effect || 'flash' //效果
            this.title = config.title || document.title; //标题
            this.message = config.message || this.title; //原来的标题
            this.updateFavicon = config.updateFavicon || {
                id: "favicon",
                textColor: "#fff",
                backgroundColor: "#2F9A00",
                location: "full",
                shape: "square"
            }
            this.favicon = document.querySelectorAll('link[rel~=shortcut]')[0]
            this.favicon = this.favicon;
            this.cloneFavicon = this.favicon.cloneNode(true);;
            if ( 0 <= repeatableEffects.indexOf(this.effect)) this.addTimer()
            return this;
        },
        render: function() {
            switch (this.effect) {
                case 'flash':
                    document.title = (this.title === document.title) ? this.message : this.title;
                    break;
                case 'scroll':
                    document.title = document.title.slice(1);
                    if (0 === document.title.length) {
                        document.title = this.message
                    }
                    break;
            }
        },
        //设置标题
        setTitle:function(str){
            if(str) {
                this.message = str,this.addTimer()
            }else {
                this.clearTimer(),
                this.title = this.title
                console.log("this.title:",this.title)
            }
            return this
        },
        //设置时间间隔
        setInterval:function(num){
            if(num) this.interval = num,this.addTimer()
        },
        //设置网页Icon
        setFavicon:function(num){
            var oldicon = document.getElementById('new'+this.updateFavicon.id)
            if(this.favicon) this.favicon.remove();
            if(oldicon) oldicon.remove();
            changeFavicon(num,this.updateFavicon)
        },
        //添加计数器
        addTimer:function(){
            this.clearTimer()
            if ( 0 <= repeatableEffects.indexOf(this.effect)) {
                this.timer = setInterval(this.render.bind(this), this.interval);
            }
            return this
        },
        //清除Icon
        faviconClear:function(){
            var newicon = document.getElementById('new'+this.updateFavicon.id)
                head = document.getElementsByTagName('head')[0]
            newicon.remove()
            head.appendChild(this.cloneFavicon);
            this.favicon = this.cloneFavicon
        },
        //清除计数器
        clearTimer:function(){
            clearInterval(this.timer);
            document.title = this.title;
            return this
        }
    };
    function changeFavicon(num,settings){
        if (num > 0) {
            var canvas = document.createElement('canvas'),
                img = document.createElement('img'),
                head = document.getElementsByTagName('head')[0],
                linkTag = document.createElement('link'),
                ctx;

            canvas.height = canvas.width = 16;
            ctx = canvas.getContext('2d');
            ctx.fillStyle = settings.backgroundColor;
            ctx.fillRect(0, 0, 16, 16);
            var centerX = canvas.width / 2;
            var centerY = canvas.height / 2;
            var radius = 8;
            ctx.beginPath();
            ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
            ctx.fill();

            ctx.textAlign = "center";
            ctx.font = '10px "helvetica", sans-serif';
            ctx.fillStyle = settings.textColor;
            ctx.fillText(num, 8, 12);

            //生成到
            linkTag.setAttribute('rel','shortcut icon');
            linkTag.setAttribute('type','image/x-icon');
            linkTag.setAttribute('id', 'new'+settings.id);
            linkTag.setAttribute('href', canvas.toDataURL('image/png'));
            head.appendChild(linkTag);
        }
    };
    return iNotify
}));<commit_msg>fix 修复iNotify.faviconClear()重复清除报错<commit_after>;(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof exports === 'object') {
        module.exports = factory();
    } else {
        root.iNotify = factory();
    }
}(this, function(root, undefined) {
    var repeatableEffects = ['flash', 'scroll']
    var iNotify = {
        init:function(config){
            this.interval = config.interval || 200//响应时长
            this.effect = config.effect || 'flash' //效果
            this.title = config.title || document.title; //标题
            this.message = config.message || this.title; //原来的标题
            this.updateFavicon = config.updateFavicon || {
                id: "favicon",
                textColor: "#fff",
                backgroundColor: "#2F9A00",
                location: "full",
                shape: "square"
            }
            this.favicon = document.querySelectorAll('link[rel~=shortcut]')[0]
            this.favicon = this.favicon;
            this.cloneFavicon = this.favicon.cloneNode(true);;
            if ( 0 <= repeatableEffects.indexOf(this.effect)) this.addTimer()
            return this;
        },
        render: function() {
            switch (this.effect) {
                case 'flash':
                    document.title = (this.title === document.title) ? this.message : this.title;
                    break;
                case 'scroll':
                    document.title = document.title.slice(1);
                    if (0 === document.title.length) {
                        document.title = this.message
                    }
                    break;
            }
        },
        //设置标题
        setTitle:function(str){
            if(str) {
                this.message = str,this.addTimer()
            }else {
                this.clearTimer(),
                this.title = this.title
                console.log("this.title:",this.title)
            }
            return this
        },
        //设置时间间隔
        setInterval:function(num){
            if(num) this.interval = num,this.addTimer()
        },
        //设置网页Icon
        setFavicon:function(num){
            var oldicon = document.getElementById('new'+this.updateFavicon.id)
            if(this.favicon) this.favicon.remove();
            if(oldicon) oldicon.remove();
            changeFavicon(num,this.updateFavicon)
        },
        //添加计数器
        addTimer:function(){
            this.clearTimer()
            if ( 0 <= repeatableEffects.indexOf(this.effect)) {
                this.timer = setInterval(this.render.bind(this), this.interval);
            }
            return this
        },
        //清除Icon
        faviconClear:function(){
            var newicon = document.getElementById('new'+this.updateFavicon.id)
                head = document.getElementsByTagName('head')[0]
            newicon&&newicon.remove()
            head.appendChild(this.cloneFavicon);
            this.favicon = this.cloneFavicon
        },
        //清除计数器
        clearTimer:function(){
            clearInterval(this.timer);
            document.title = this.title;
            return this
        }
    };
    function changeFavicon(num,settings){
        if (num > 0) {
            var canvas = document.createElement('canvas'),
                img = document.createElement('img'),
                head = document.getElementsByTagName('head')[0],
                linkTag = document.createElement('link'),
                ctx;

            canvas.height = canvas.width = 16;
            ctx = canvas.getContext('2d');
            ctx.fillStyle = settings.backgroundColor;
            ctx.fillRect(0, 0, 16, 16);
            var centerX = canvas.width / 2;
            var centerY = canvas.height / 2;
            var radius = 8;
            ctx.beginPath();
            ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
            ctx.fill();

            ctx.textAlign = "center";
            ctx.font = '10px "helvetica", sans-serif';
            ctx.fillStyle = settings.textColor;
            ctx.fillText(num, 8, 12);

            //生成到
            linkTag.setAttribute('rel','shortcut icon');
            linkTag.setAttribute('type','image/x-icon');
            linkTag.setAttribute('id', 'new'+settings.id);
            linkTag.setAttribute('href', canvas.toDataURL('image/png'));
            head.appendChild(linkTag);
        }
    };
    return iNotify
}));<|endoftext|>


<commit_before>
window.normalWidth = window.outerWidth;
window.normalHeight = window.outerHeight;

window.minWidth = 250;
window.minHeight = 160;

function freshbooksResize(){
  var resizeButton = document.getElementById("freshbooks-resize-button");

  if(window.outerHeight == window.normalHeight){
    window.resizeTo(window.minWidth,window.minHeight);
    resizeButton.innerHTML = "▲";
  }
  else{
    window.resizeTo(window.normalWidth,window.normalHeight);
    resizeButton.innerHTML = "▼";
  }
}
<commit_msg>Keeping width the same throughout resize<commit_after>
window.normalWidth = window.outerWidth;
window.normalHeight = window.outerHeight;

window.minWidth = window.outerWidth;
window.minHeight = 160;

function freshbooksResize(){
  var resizeButton = document.getElementById("freshbooks-resize-button");

  if(window.outerHeight == window.normalHeight){
    window.resizeTo(window.minWidth,window.minHeight);
    resizeButton.innerHTML = "▲";
  }
  else{
    window.resizeTo(window.normalWidth,window.normalHeight);
    resizeButton.innerHTML = "▼";
  }
}
<|endoftext|>