<commit_before>within("ukulo.com/flies-fly", function( publish, subscribe, get, set ) {

  var
    // maximum duration of a round (when player hand stays down), in ms
    MAX_ROUND_DURATION_MS = 2000,

    // timeout for end of round
    endRoundTimeout = null;

  set( "game-over", false );

  function resetTimeout( timeout ) {
    if ( timeout !== null ) {
      clearTimeout( timeout );
    }
    timeout = null;
  }

  function startRound() {
    if ( get( "game-over" ) ) {
      return;
    }
    if ( !get( "start-game" ) ) {
      publish( "start-game" );
    }
    publish( "start-round" );
    endRoundTimeout = setTimeout(endRound, MAX_ROUND_DURATION_MS);
  }

  function endRound() {
    resetTimeout( endRoundTimeout );
    if ( get( "game-over" ) ){
      return;
    }
    publish( "end-round" );
    if ( get( "player-hand-position" ) !== get( "expected-hand-position" ) ) {
      publish( "player-eliminated" );
      set( "game-over", true );
      publish( "end-game" );
    }
  }

  subscribe( "player-hand-position", function( position ) {
    if ( position === "down" ) {
      startRound();
    } else {
      endRound();
    }
  });

});
<commit_msg>Remove "start-game" event (not used)<commit_after>within("ukulo.com/flies-fly", function( publish, subscribe, get, set ) {

  var
    // maximum duration of a round (when player hand stays down), in ms
    MAX_ROUND_DURATION_MS = 2000,

    // timeout for end of round
    endRoundTimeout = null;

  set( "game-over", false );

  function resetTimeout( timeout ) {
    if ( timeout !== null ) {
      clearTimeout( timeout );
    }
    timeout = null;
  }

  function startRound() {
    if ( get( "game-over" ) ) {
      return;
    }
    publish( "start-round" );
    endRoundTimeout = setTimeout(endRound, MAX_ROUND_DURATION_MS);
  }

  function endRound() {
    resetTimeout( endRoundTimeout );
    if ( get( "game-over" ) ){
      return;
    }
    publish( "end-round" );
    if ( get( "player-hand-position" ) !== get( "expected-hand-position" ) ) {
      publish( "player-eliminated" );
      set( "game-over", true );
      publish( "end-game" );
    }
  }

  subscribe( "player-hand-position", function( position ) {
    if ( position === "down" ) {
      startRound();
    } else {
      endRound();
    }
  });

});
<|endoftext|>


<commit_before>'use strict';
'use babel';

var _atom = require('atom');

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _settings = require('./settings');

var _settings2 = _interopRequireDefault(_settings);

var _child_process = require('child_process');

var _child_process2 = _interopRequireDefault(_child_process);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

module.exports = {
  config: _settings2.default,
  subscriptions: null,

  activate: function activate() {
    var _this = this;

    this.subscriptions = new _atom.CompositeDisposable();
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'elm-format:file': function elmFormatFile() {
        return _this.formatCurrentFile();
      }
    }));
    this.subscriptions.add(atom.workspace.observeTextEditors(function (e) {
      return _this.handleEvents(e);
    }));
  },
  handleEvents: function handleEvents(editor) {
    var _this2 = this;

    editor.getBuffer().onWillSave(function () {
      if (atom.config.get('elm-format.formatOnSave') && _this2.isElmEditor(editor)) {
        _this2.format(editor);
      }
    });
  },
  deactivate: function deactivate() {
    this.subscriptions.dispose();
  },
  error: function error(str) {
    if (atom.config.get('elm-format.showErrorNotifications')) {
      atom.notifications.addError(str);
    }
  },
  success: function success(str) {
    if (atom.config.get('elm-format.showNotifications')) {
      atom.notifications.addSuccess(str);
    }
  },
  formatCurrentFile: function formatCurrentFile() {
    var editor = atom.workspace.getActiveTextEditor();
    if (!editor) {
      return;
    }
    if (this.isElmEditor(editor)) {
      this.format(editor);
    } else {
      atom.notifications.addInfo('Not an Elm file', {
        dismissable: false,
        detail: 'I only know how to format .elm-files, sorry!'
      });
    }
  },
  isElmEditor: function isElmEditor(editor) {
    return editor && editor.getPath && editor.getPath() && _path2.default.extname(editor.getPath()) === '.elm';
  },
  format: function format(editor) {
    try {
      var _childProcess$spawnSy = _child_process2.default.spawnSync(atom.config.get('elm-format.binary'), ['--stdin'], { input: editor.getText() });

      var status = _childProcess$spawnSy.status;
      var stdout = _childProcess$spawnSy.stdout;

      if (status === 0) {
        var cursorPosition = editor.getCursorScreenPosition();
        // const marker = editor.markScreenRange([cursorPosition, cursorPosition], {
        //   invalidate: 'never', persistent: false
        // });
        editor.buffer.setTextViaDiff(stdout.toString());
        // editor.setCursorScreenPosition(marker.getStartScreenPosition());
        // marker.destroy();
        editor.setCursorScreenPosition(cursorPosition);

        this.success('Formatted file');
      } else {
        this.error('elm-format exited with code ' + status);
      }
    } catch (exception) {
      this.error('elm-format exception: ' + exception);
    }
  }
};<commit_msg>Compile to lib<commit_after>'use strict';
'use babel';

var _atom = require('atom');

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _settings = require('./settings');

var _settings2 = _interopRequireDefault(_settings);

var _child_process = require('child_process');

var _child_process2 = _interopRequireDefault(_child_process);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

module.exports = {
  config: _settings2.default,
  subscriptions: null,

  activate: function activate() {
    var _this = this;

    this.subscriptions = new _atom.CompositeDisposable();
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'elm-format:file': function elmFormatFile() {
        return _this.formatCurrentFile();
      }
    }));
    this.subscriptions.add(atom.workspace.observeTextEditors(function (e) {
      return _this.handleEvents(e);
    }));
  },
  handleEvents: function handleEvents(editor) {
    var _this2 = this;

    editor.getBuffer().onWillSave(function () {
      if (atom.config.get('elm-format.formatOnSave') && _this2.isElmEditor(editor)) {
        _this2.format(editor);
      }
    });
  },
  deactivate: function deactivate() {
    this.subscriptions.dispose();
  },
  error: function error(str) {
    if (atom.config.get('elm-format.showErrorNotifications')) {
      atom.notifications.addError(str);
    }
  },
  success: function success(str) {
    if (atom.config.get('elm-format.showNotifications')) {
      atom.notifications.addSuccess(str);
    }
  },
  formatCurrentFile: function formatCurrentFile() {
    var editor = atom.workspace.getActiveTextEditor();
    if (!editor) {
      return;
    }
    if (this.isElmEditor(editor)) {
      this.format(editor);
    } else {
      atom.notifications.addInfo('Not an Elm file', {
        dismissable: false,
        detail: 'I only know how to format .elm-files, sorry!'
      });
    }
  },
  isElmEditor: function isElmEditor(editor) {
    return editor && editor.getPath && editor.getPath() && _path2.default.extname(editor.getPath()) === '.elm';
  },
  format: function format(editor) {
    try {
      var _childProcess$spawnSy = _child_process2.default.spawnSync(atom.config.get('elm-format.binary'), ['--stdin'], { input: editor.getText() });

      var status = _childProcess$spawnSy.status;
      var stdout = _childProcess$spawnSy.stdout;

      if (status === 0) {
        var cursorPosition = editor.getCursorScreenPosition();
        editor.buffer.setTextViaDiff(stdout.toString());
        editor.setCursorScreenPosition(cursorPosition);

        this.success('Formatted file');
      } else {
        this.error('elm-format exited with code ' + status);
      }
    } catch (exception) {
      this.error('elm-format exception: ' + exception);
    }
  }
};<|endoftext|>


<commit_before>/*
Error.js
Handles compatibility checks and user viewable errors.
*/

define(["lib/jquery-1.6.3.min",
        "utils/Shared"],
    function () {
        var shared = require('utils/Shared'),
            errorContainer = $('#error_container'),
            errorID = 'error',
            errorHash = 'error=',
            errorMessages = {
                general: {
                    header: "Oops! That wasn't supposed to happen!",
                    message: "Something broke and we're very sorry about that. No worries though, any progress you've made has been saved. All you need to do is reload the page!"
                },
                webgl: {
                    header: "Oops! We need WebGL!",
                    message: "We are sorry, but it appears that your browser does not support WebGL. This could be due to a number of different reasons. For more information visit the WebGL troubleshooting page."
                },
                fourohfour: {
                    header: "Oops! Not found!",
                    message: "Sorry, but the page you were trying to view does not exist. This is probably the result of either a mistyped address or an out-of-date link."
                }
            };

        // remove all error dom elements
        function clear () {
            errorContainer.empty();
        }

        // show error to user
        function show ( id ) {
            var section, header, article;

            // header

            // article
        }

        // check for internal errors
        function check () {
            var webgl;

            // webgl check
            webgl = has_webgl();
            if (webgl === true) {
                window.location.hash = errorHash + 'webgl';
            }

            // check url
            check_url();
        }

        // check url for errors
        function check_url () {
            var hashError, hashErrorIndex, errorType;

            // check url hash for error message
            hashError = window.location.hash.toString().replace(/#/, '');
            hashErrorIndex = hashError.indexOf(errorHash);
            if (hashErrorIndex != -1) {
                // get error type
                errorType = hashError.replace(/error=/i, '');

                // does error type match a specific errors?
                if (errorMessages.hasOwnProperty(errorType)) {
                    alert(errorMessages[errorType].message);
                }
                // else trigger general error
                else {
                    alert(errorMessages.general.message);
                }

                // clear hash out with history states
                history.pushState( { "pState": shared.originLink }, '', shared.originLink );
            }
        }

        // has webgl
        function has_webgl () {
            try {
                return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' );
            }
            catch( e ) {
                return false;
            }
        }

        // clear error container
        clear();

        // check once
        check();

        // return something to define module
        return {
            check: check,
            clear: clear
        };
    }
);<commit_msg>updated error checking<commit_after>/*
Error.js
Handles compatibility checks and user viewable errors.
*/

define(["lib/jquery-1.6.3.min",
        "utils/Shared"],
    function () {
        var shared = require('utils/Shared'),
            errorContainer = $('#error_container'),
            errorID = 'error',
            errorHash = 'error=',
            errorMessages = {
                general: {
                    header: "Oops! That wasn't supposed to happen!",
                    message: "Something broke and we're very sorry about that. No worries though, if you were playing any progress you've made has been saved. All you need to do is reload the page!"
                },
                webgl: {
                    header: "Hey! We need WebGL!",
                    message: "We are sorry, but it appears that your browser does not support WebGL. This could be due to a number of different reasons. For more information visit the WebGL troubleshooting page."
                },
                fourohfour: {
                    header: "Oops! Not found!",
                    message: "Sorry, but the page you were trying to view does not exist. This is probably the result of either a mistyped address or an out-of-date link."
                },
                forbidden: {
                    header: "We're afraid we can't let you do that.",
                    message: "Sorry, but the page you were trying to view is locked or hidden for a reason we can't tell you."
                }
            };

        // remove all error dom elements
        function clear () {
            errorContainer.empty();
        }

        // show error to user
        function show ( id ) {
            var section, header, article;

            // header

            // article
        }

        // check for internal errors
        function check () {
            var webgl;

            // webgl check
            webgl = has_webgl();
            if (webgl === true) {
                window.location.hash = errorHash + 'webgl';
            }

            // check url
            check_url();
        }

        // check url for errors
        function check_url () {
            var hashError, hashErrorIndex, errorType;

            // check url hash for error message
            hashError = window.location.hash.toString().replace(/#/, '');
            hashErrorIndex = hashError.indexOf(errorHash);
            if (hashErrorIndex != -1) {
                // get error type
                errorType = hashError.replace(/error=/i, '');

                // does error type match a specific errors?
                if (errorMessages.hasOwnProperty(errorType)) {
                    alert(errorMessages[errorType].message);
                }
                // else trigger general error
                else {
                    alert(errorMessages.general.message);
                }

                // clear hash out with history states
                history.pushState( { "pState": shared.originLink }, '', shared.originLink );
            }
        }

        // has webgl
        function has_webgl () {
            try {
                return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' );
            }
            catch( e ) {
                return false;
            }
        }

        // clear error container
        clear();

        // check once
        check();

        // return something to define module
        return {
            check: check,
            clear: clear
        };
    }
);<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const start = require('./start');

// TODO set default values
// TODO validate config data

module.exports = function (entrypoint, infrastructure, config_path) {
    config_path = path.resolve(config_path);
    fs.readFile(config_path, (err, data) => {

        if (err) {
            throw new Error(err);
        }

        let config = checkConfig(JSON.parse(data.toString()));
        let command = getEntrypointCommand(infrastructure, config);

        // add base path to config
        config.base = path.dirname(config_path);

        // build and start entrypoints
        if (entrypoint) {
            entrypoint = buildEntrypoint(config, config.entrypoints.find((item) => {
                return item.name === entrypoint;
            }));

            start(entrypoint, command);
        } else {
            config.entrypoints.forEach((item) => {
                entrypoint = buildEntrypoint(config, item);
                start(entrypoint, command);
            });
        }
    });
};

function checkConfig (config) {
    // TODO use jsonld schema + content validation

    if (!config) {
        error('No config defined.');
    }

    if (!config.entrypoints && !config.entrypoints.length) {
        error('No entrypoints defined in config.');
    }

    if (!config.entrypoints && !config.entrypoints.length) {
        error('No infrastructure defined in conig.');
    }

    return config;
}

function buildEntrypoint (config, entrypoint) {

    checkEntrypoint(entrypoint);

    // resolve network path
    // TODO only if network is a dir!
    // TODO check if folder exists
    if (entrypoint.network.type === 'fs') {
        entrypoint.network = path.resolve(config.base, entrypoint.network.path);
    }

    // build environment
    if (entrypoint.env && entrypoint.env.length) {
        environment(entrypoint, config);
    }

    return entrypoint;
}

function checkEntrypoint (entrypoint) {
    if (!entrypoint) {
        error('Entrypoint not found.');
    }

    if (!entrypoint.event) {
        error('No event defined in entrypoint.');
    }

    if (!entrypoint.network) {
        error('No network defined in entrypoint.');
    }

    return entrypoint;
}

function environment (entrypoint, config) {
    let environment = {};

    entrypoint.env.forEach((name) => {
        let env = config.environments.find((env) => {
            return env.name === name;
        });

        if (!env) {
            throw new Error('Flow-app.environment: Entrypoint environment reference "' + name + '" does not exist.');
        }

        Object.assign(environment, env.vars);
    });

    entrypoint.env = environment;
}

function getEntrypointCommand (inf_config, config) {

    inf_config = config.infrastructure.find((item) => {
        return item.name === inf_config;
    });

    if (!inf_config) {
        error('Infrastructure config not found.');
    }

    inf_config = inf_config.config;
    if (!inf_config.start) {
        error('No CLI command defined in infrastructure config.');
    }

    return inf_config.start;
}

function error (msg) {
    throw new Error('Flow-app: ' + msg);
}
<commit_msg>add project base path to entrypoint<commit_after>const fs = require('fs');
const path = require('path');
const start = require('./start');

// TODO set default values
// TODO validate config data

module.exports = function (entrypoint, infrastructure, config_path) {
    config_path = path.resolve(config_path);
    fs.readFile(config_path, (err, data) => {

        if (err) {
            throw new Error(err);
        }

        let config = checkConfig(JSON.parse(data.toString()));
        let command = getEntrypointCommand(infrastructure, config);

        // add base path to config
        config.base = path.dirname(config_path);

        // build and start entrypoints
        if (entrypoint) {
            entrypoint = buildEntrypoint(config, config.entrypoints.find((item) => {
                return item.name === entrypoint;
            }));

            start(entrypoint, command);
        } else {
            config.entrypoints.forEach((item) => {
                entrypoint = buildEntrypoint(config, item);
                start(entrypoint, command);
            });
        }
    });
};

function checkConfig (config) {
    // TODO use jsonld schema + content validation

    if (!config) {
        error('No config defined.');
    }

    if (!config.entrypoints && !config.entrypoints.length) {
        error('No entrypoints defined in config.');
    }

    if (!config.entrypoints && !config.entrypoints.length) {
        error('No infrastructure defined in conig.');
    }

    return config;
}

function buildEntrypoint (config, entrypoint) {

    checkEntrypoint(entrypoint);

    // resolve network path
    // TODO only if network is a dir!
    // TODO check if folder exists
    if (entrypoint.network.type === 'fs') {
        entrypoint.network = path.resolve(config.base, entrypoint.network.path);
    }

    entrypoint.base = config.base;

    // build environment
    if (entrypoint.env && entrypoint.env.length) {
        environment(entrypoint, config);
    }

    return entrypoint;
}

function checkEntrypoint (entrypoint) {
    if (!entrypoint) {
        error('Entrypoint not found.');
    }

    if (!entrypoint.event) {
        error('No event defined in entrypoint.');
    }

    if (!entrypoint.network) {
        error('No network defined in entrypoint.');
    }

    return entrypoint;
}

function environment (entrypoint, config) {
    let environment = {};

    entrypoint.env.forEach((name) => {
        let env = config.environments.find((env) => {
            return env.name === name;
        });

        if (!env) {
            throw new Error('Flow-app.environment: Entrypoint environment reference "' + name + '" does not exist.');
        }

        Object.assign(environment, env.vars);
    });

    entrypoint.env = environment;
}

function getEntrypointCommand (inf_config, config) {

    inf_config = config.infrastructure.find((item) => {
        return item.name === inf_config;
    });

    if (!inf_config) {
        error('Infrastructure config not found.');
    }

    inf_config = inf_config.config;
    if (!inf_config.start) {
        error('No CLI command defined in infrastructure config.');
    }

    return inf_config.start;
}

function error (msg) {
    throw new Error('Flow-app: ' + msg);
}
<|endoftext|>


<commit_before>'use strict';

var listing = {
  selectMultiple: false
};

listing.reload = function (callback) {
  let request = new XMLHttpRequest();

  request.open('GET', window.location);
  request.setRequestHeader('Minimal', 'true');
  request.send();
  request.onreadystatechange = function () {
    if(request.readyState == 4) {
      if(request.status == 200) {
        document.querySelector('body main').innerHTML = request.responseText;
        listing.addDoubleTapEvent();

        if(typeof callback == 'function') {
          callback();
        }
      }
    }
  }
}

listing.itemDragStart = function (event) {
  let el = event.target;

  for(let i = 0; i < 5; i++) {
    if(!el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  event.dataTransfer.setData("id", el.id);
  event.dataTransfer.setData("name", el.querySelector('.name').innerHTML);
}

listing.itemDragOver = function (event) {
  event.preventDefault();
  let el = event.target;

  for(let i = 0; i < 5; i++) {
    if(!el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  el.style.opacity = 1;
}

listing.itemDrop = function (e) {
  e.preventDefault();

  let el = e.target,
    id = e.dataTransfer.getData("id"),
    name = e.dataTransfer.getData("name");

  if(id == "" || name == "") return;

  for(let i = 0; i < 5; i++) {
    if(!el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  if(el.id === id) return;

  let oldLink = document.getElementById(id).dataset.url,
    newLink = el.dataset.url + name;

  webdav.move(oldLink, newLink)
    .then(() => listing.reload())
    .catch(e => console.log(e));
}

listing.documentDrop = function (event) {
  event.preventDefault();
  let dt = event.dataTransfer,
    files = dt.files,
    el = event.target,
    items = document.getElementsByClassName('item');

  for(let i = 0; i < 5; i++) {
    if(el != null && !el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  if(files.length > 0) {
    if(el != null && el.classList.contains('item') && el.dataset.dir == "true") {
      listing.handleFiles(files, el.querySelector('.name').innerHTML + "/");
      return;
    }

    listing.handleFiles(files, "");
  } else {
    Array.from(items).forEach(file => {
      file.style.opacity = 1;
    });
  }
}

listing.rename = function (event) {
  if(!selectedItems.length || selectedItems.length > 1) {
    return false;
  }

  let item = document.getElementById(selectedItems[0]);

  if(item.classList.contains('disabled')) {
    return false;
  }

  let link = item.dataset.url,
    field = item.querySelector('.name'),
    name = field.innerHTML;

  let submit = (event) => {
    event.preventDefault();

    let newName = event.currentTarget.querySelector('input').value,
      newLink = removeLastDirectoryPartOf(link) + "/" + newName;

    closePrompt(event);
    buttons.setLoading('rename');

    webdav.move(link, newLink).then(() => {
      listing.reload(() => {
        newName = btoa(newName);
        selectedItems = [newName];
        document.getElementById(newName).setAttribute("aria-selected", true);
        listing.handleSelectionChange();
      });

      buttons.setDone('rename');
    }).catch(error => {
      field.innerHTML = name;
      buttons.setDone('rename', false);
      console.log(error);
    });

    return false;
  }

  let clone = document.importNode(templates.question.content, true);
  clone.querySelector('h3').innerHTML = 'Rename';
  clone.querySelector('input').value = name;
  clone.querySelector('.ok').innerHTML = 'Rename';
  clone.querySelector('form').addEventListener('submit', submit);

  document.querySelector('body').appendChild(clone)
  document.querySelector('.overlay').classList.add('active');
  document.querySelector('.prompt').classList.add('active');

  return false;
}

listing.handleFiles = function (files, base) {
  buttons.setLoading('upload');

  let promises = [];

  for(let file of files) {
    promises.push(webdav.put(window.location.pathname + base + file.name, file));
  }

  Promise.all(promises)
    .then(() => {
      listing.reload();
      buttons.setDone('upload');
    })
    .catch(e => {
      console.log(e);
      buttons.setDone('upload', false);
    })

  return false;
}

listing.unselectAll = function () {
  let items = document.getElementsByClassName('item');
  Array.from(items).forEach(link => {
    link.setAttribute("aria-selected", false);
  });

  selectedItems = [];

  listing.handleSelectionChange();
  return false;
}

listing.handleSelectionChange = function (event) {
  listing.redefineDownloadURLs();

  let selectedNumber = selectedItems.length,
    fileAction = document.getElementById("file-only");

  if(selectedNumber) {
    fileAction.classList.remove("disabled");

    if(selectedNumber > 1) {
      buttons.open.classList.add("disabled");
      buttons.rename.classList.add("disabled");
    }

    if(selectedNumber == 1) {
      if(document.getElementById(selectedItems[0]).dataset.dir == "true") {
        buttons.open.classList.add("disabled");
      } else {
        buttons.open.classList.remove("disabled");
      }

      buttons.rename.classList.remove("disabled");
    }

    return false;
  }

  fileAction.classList.add("disabled");
  return false;
}

listing.redefineDownloadURLs = function () {
  let files = "";

  for(let i = 0; i < selectedItems.length; i++) {
    let url = document.getElementById(selectedItems[i]).dataset.url;
    files += url.replace(window.location.pathname, "") + ",";
  }

  files = files.substring(0, files.length - 1);
  files = encodeURIComponent(files);

  let links = document.querySelectorAll("#download ul a");
  Array.from(links).forEach(link => {
    link.href = "?download=" + link.dataset.format + "&files=" + files;
  });
}

listing.openItem = function (event) {
  window.location = event.currentTarget.dataset.url;
}

listing.selectItem = function (event) {
  let el = event.currentTarget;

  if(selectedItems.length != 0) event.preventDefault();
  if(selectedItems.indexOf(el.id) == -1) {
    if(!event.ctrlKey && !listing.selectMultiple) listing.unselectAll();

    el.setAttribute("aria-selected", true);
    selectedItems.push(el.id);
  } else {
    el.setAttribute("aria-selected", false);
    selectedItems.removeElement(el.id);
  }

  listing.handleSelectionChange();
  return false;
}

listing.newFileButton = function (event) {
  event.preventDefault();

  let clone = document.importNode(templates.question.content, true);
  clone.querySelector('h3').innerHTML = 'New file';
  clone.querySelector('p').innerHTML = 'End with a trailing slash to create a dir.';
  clone.querySelector('.ok').innerHTML = 'Create';
  clone.querySelector('form').addEventListener('submit', listing.newFilePrompt);

  document.querySelector('body').appendChild(clone)
  document.querySelector('.overlay').classList.add('active');
  document.querySelector('.prompt').classList.add('active');
}

listing.newFilePrompt = function (event) {
  event.preventDefault();
  buttons.setLoading('new');

  let name = event.currentTarget.querySelector('input').value;

  webdav.new(window.location.pathname + name)
    .then(() => {
      buttons.setDone('new');
      listing.reload();
    })
    .catch(e => {
      console.log(e);
      buttons.setDone('new', false);
    });

  closePrompt(event);
  return false;
}

listing.updateColumns = function (event) {
  let columns = Math.floor(document.getElementById('listing').offsetWidth / 300),
    items = getCSSRule(['#listing.mosaic .item', '.mosaic#listing .item']);

  items.style.width = `calc(${100/columns}% - 1em)`;
}

listing.addDoubleTapEvent = function () {
  let items = document.getElementsByClassName('item'),
    touches = {
      id: '',
      count: 0
    };

  Array.from(items).forEach(file => {
    file.addEventListener('touchstart', event => {
      if(touches.id != file.id) {
        touches.id = file.id;
        touches.count = 1;

        setTimeout(() => {
          touches.count = 0;
        }, 300)

        return;
      }

      touches.count++;

      if(touches.count > 1) {
        window.location = file.dataset.url;
      }
    });
  });
}

// Keydown events
window.addEventListener('keydown', (event) => {
  if(event.keyCode == 27) {
    listing.unselectAll();

    if(document.querySelectorAll('.prompt').length) {
      closePrompt(event);
    }
  }

  if(event.keyCode == 113) {
    listing.rename();
  }

  if(event.ctrlKey || event.metaKey) {
    switch(String.fromCharCode(event.which).toLowerCase()) {
    case 's':
      event.preventDefault();
      window.location = "?download=true"
    }
  }
});

window.addEventListener("resize", () => {
  listing.updateColumns();
});

listing.selectMoveFolder = function (event) {
  if(event.target.getAttribute("aria-selected") === "true") {
    event.target.setAttribute("aria-selected", false);
    return;
  } else {
    if(document.querySelector(".file-list li[aria-selected=true]")) {
      document.querySelector(".file-list li[aria-selected=true]").setAttribute("aria-selected", false);
    }
    event.target.setAttribute("aria-selected", true);
    return;
  }
}

listing.getJSON = function (link) {
  return new Promise((resolve, reject) => {
    let request = new XMLHttpRequest();
    request.open("GET", link);
    request.setRequestHeader("Accept", "application/json");
    request.onload = () => {
      if(request.status == 200) {
        resolve(request.responseText);
      } else {
        reject(request.statusText);
      }
    }
    request.onerror = () => reject(request.statusText);
    request.send();
  });
}

listing.moveMakeItem = function (url, name) {
  let node = document.createElement("li");

  node.dataset.url = url;
  node.innerHTML = name;
  node.setAttribute("aria-selected", false);

  node.addEventListener("dblclick", listing.moveDialogNext);
  node.addEventListener("click", listing.selectMoveFolder);
  return node;
}

listing.moveDialogNext = function (event) {
  let request = new XMLHttpRequest(),
    prompt = document.querySelector("form.prompt.active"),
    list = prompt.querySelector("div.file-list ul");

  prompt.addEventListener("submit", listing.moveSelected);

  listing.getJSON(event.target.dataset.url)
    .then((data) => {
      let dirs = 0;

      prompt.querySelector("ul").innerHTML = "";
      prompt.querySelector('code').innerHTML = event.target.dataset.url;

      if(event.target.dataset.url != baseURL + "/") {
        let node = listing.moveMakeItem(removeLastDirectoryPartOf(event.target.dataset.url) + "/", "..")
        list.appendChild(node);
      }

      if(JSON.parse(data) == null) {
        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
        return;
      }

      for(let f of JSON.parse(data)) {
        if(f.IsDir === true) {
          dirs++;
          list.appendChild(listing.moveMakeItem(f.URL, f.Name));
        }
      }

      if(dirs === 0)
        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
    })
    .catch(e => console.log(e));
}

listing.moveSelected = function (event) {
  event.preventDefault();

  let promises = [];
  buttons.setLoading("move");

  for(let file of selectedItems) {
    let fileElement = document.getElementById(file),
      destFolder = event.target.querySelector("p code").innerHTML;

    if(event.srcElement.querySelector("li[aria-selected=true]") != null)
      destFolder = event.srcElement.querySelector("li[aria-selected=true]").innerHTML;

    let destPath = "/" + destFolder + "/" + fileElement.querySelector(".name").innerHTML;
    destPath = destPath.replace('//', '/');

    promises.push(webdav.move(fileElement.dataset.url, destPath));
  }

  Promise.all(promises)
    .then(() => {
      closePrompt(event);
      buttons.setDone("move");
      listing.reload();
    })
    .catch(e => {
      console.log(e);
    })
}

listing.moveEvent = function (event) {
  if(event.currentTarget.classList.contains("disabled"))
    return;

  listing.getJSON(window.location.pathname)
    .then((data) => {
      let prompt = document.importNode(templates.move.content, true),
        list = prompt.querySelector("div.file-list ul"),
        dirs = 0;

      prompt.querySelector("form").addEventListener("submit", listing.moveSelected);
      prompt.querySelector('code').innerHTML = window.location.pathname;

      if(window.location.pathname !== baseURL + "/") {
        list.appendChild(listing.moveMakeItem(removeLastDirectoryPartOf(window.location.pathname) + "/", ".."));
      }

      for(let f of JSON.parse(data)) {
        if(f.IsDir === true) {
          dirs++;
          list.appendChild(listing.moveMakeItem(f.URL, f.Name));
        }
      }

      if(dirs === 0) {
        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
      }

      document.body.appendChild(prompt);
      document.querySelector(".overlay").classList.add("active");
      document.querySelector(".prompt").classList.add("active");
    })
    .catch(e => console.log(e));
}

document.addEventListener('DOMContentLoaded', event => {
  listing.updateColumns();
  listing.addDoubleTapEvent();

  buttons.rename = document.getElementById("rename");
  buttons.upload = document.getElementById("upload");
  buttons.new = document.getElementById('new');
  buttons.download = document.getElementById('download');
  buttons.move = document.getElementById("move");

  buttons.move.addEventListener("click", listing.moveEvent);

  document.getElementById('multiple-selection-activate').addEventListener('click', event => {
    listing.selectMultiple = true;
    clickOverlay.click();

    document.getElementById('multiple-selection').classList.add('active');
    document.querySelector('body').style.paddingBottom = "4em";
  })

  document.getElementById('multiple-selection-cancel').addEventListener('click', event => {
    listing.selectMultiple = false;

    document.querySelector('body').style.paddingBottom = "0";
    document.getElementById('multiple-selection').classList.remove('active');
  })

  if(user.AllowEdit) {
    buttons.rename.addEventListener("click", listing.rename);
  }

  let items = document.getElementsByClassName('item');

  if(user.AllowNew) {
    buttons.upload.addEventListener("click", (event) => {
      document.getElementById("upload-input").click();
    });

    buttons.new.addEventListener('click', listing.newFileButton);

    // Drag and Drop
    document.addEventListener("dragover", function (event) {
      event.preventDefault();
    }, false);

    document.addEventListener("dragenter", (event) => {
      Array.from(items).forEach(file => {
        file.style.opacity = 0.5;
      });
    }, false);

    document.addEventListener("dragend", (event) => {
      Array.from(items).forEach(file => {
        file.style.opacity = 1;
      });
    }, false);

    document.addEventListener("drop", listing.documentDrop, false);
  }

});
<commit_msg>fix move #70<commit_after>'use strict';

var listing = {
  selectMultiple: false
};

listing.reload = function (callback) {
  let request = new XMLHttpRequest();

  request.open('GET', window.location);
  request.setRequestHeader('Minimal', 'true');
  request.send();
  request.onreadystatechange = function () {
    if(request.readyState == 4) {
      if(request.status == 200) {
        document.querySelector('body main').innerHTML = request.responseText;
        listing.addDoubleTapEvent();

        if(typeof callback == 'function') {
          callback();
        }
      }
    }
  }
}

listing.itemDragStart = function (event) {
  let el = event.target;

  for(let i = 0; i < 5; i++) {
    if(!el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  event.dataTransfer.setData("id", el.id);
  event.dataTransfer.setData("name", el.querySelector('.name').innerHTML);
}

listing.itemDragOver = function (event) {
  event.preventDefault();
  let el = event.target;

  for(let i = 0; i < 5; i++) {
    if(!el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  el.style.opacity = 1;
}

listing.itemDrop = function (e) {
  e.preventDefault();

  let el = e.target,
    id = e.dataTransfer.getData("id"),
    name = e.dataTransfer.getData("name");

  if(id == "" || name == "") return;

  for(let i = 0; i < 5; i++) {
    if(!el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  if(el.id === id) return;

  let oldLink = document.getElementById(id).dataset.url,
    newLink = el.dataset.url + name;

  webdav.move(oldLink, newLink)
    .then(() => listing.reload())
    .catch(e => console.log(e));
}

listing.documentDrop = function (event) {
  event.preventDefault();
  let dt = event.dataTransfer,
    files = dt.files,
    el = event.target,
    items = document.getElementsByClassName('item');

  for(let i = 0; i < 5; i++) {
    if(el != null && !el.classList.contains('item')) {
      el = el.parentElement;
    }
  }

  if(files.length > 0) {
    if(el != null && el.classList.contains('item') && el.dataset.dir == "true") {
      listing.handleFiles(files, el.querySelector('.name').innerHTML + "/");
      return;
    }

    listing.handleFiles(files, "");
  } else {
    Array.from(items).forEach(file => {
      file.style.opacity = 1;
    });
  }
}

listing.rename = function (event) {
  if(!selectedItems.length || selectedItems.length > 1) {
    return false;
  }

  let item = document.getElementById(selectedItems[0]);

  if(item.classList.contains('disabled')) {
    return false;
  }

  let link = item.dataset.url,
    field = item.querySelector('.name'),
    name = field.innerHTML;

  let submit = (event) => {
    event.preventDefault();

    let newName = event.currentTarget.querySelector('input').value,
      newLink = removeLastDirectoryPartOf(link) + "/" + newName;

    closePrompt(event);
    buttons.setLoading('rename');

    webdav.move(link, newLink).then(() => {
      listing.reload(() => {
        newName = btoa(newName);
        selectedItems = [newName];
        document.getElementById(newName).setAttribute("aria-selected", true);
        listing.handleSelectionChange();
      });

      buttons.setDone('rename');
    }).catch(error => {
      field.innerHTML = name;
      buttons.setDone('rename', false);
      console.log(error);
    });

    return false;
  }

  let clone = document.importNode(templates.question.content, true);
  clone.querySelector('h3').innerHTML = 'Rename';
  clone.querySelector('input').value = name;
  clone.querySelector('.ok').innerHTML = 'Rename';
  clone.querySelector('form').addEventListener('submit', submit);

  document.querySelector('body').appendChild(clone)
  document.querySelector('.overlay').classList.add('active');
  document.querySelector('.prompt').classList.add('active');

  return false;
}

listing.handleFiles = function (files, base) {
  buttons.setLoading('upload');

  let promises = [];

  for(let file of files) {
    promises.push(webdav.put(window.location.pathname + base + file.name, file));
  }

  Promise.all(promises)
    .then(() => {
      listing.reload();
      buttons.setDone('upload');
    })
    .catch(e => {
      console.log(e);
      buttons.setDone('upload', false);
    })

  return false;
}

listing.unselectAll = function () {
  let items = document.getElementsByClassName('item');
  Array.from(items).forEach(link => {
    link.setAttribute("aria-selected", false);
  });

  selectedItems = [];

  listing.handleSelectionChange();
  return false;
}

listing.handleSelectionChange = function (event) {
  listing.redefineDownloadURLs();

  let selectedNumber = selectedItems.length,
    fileAction = document.getElementById("file-only");

  if(selectedNumber) {
    fileAction.classList.remove("disabled");

    if(selectedNumber > 1) {
      buttons.open.classList.add("disabled");
      buttons.rename.classList.add("disabled");
    }

    if(selectedNumber == 1) {
      if(document.getElementById(selectedItems[0]).dataset.dir == "true") {
        buttons.open.classList.add("disabled");
      } else {
        buttons.open.classList.remove("disabled");
      }

      buttons.rename.classList.remove("disabled");
    }

    return false;
  }

  fileAction.classList.add("disabled");
  return false;
}

listing.redefineDownloadURLs = function () {
  let files = "";

  for(let i = 0; i < selectedItems.length; i++) {
    let url = document.getElementById(selectedItems[i]).dataset.url;
    files += url.replace(window.location.pathname, "") + ",";
  }

  files = files.substring(0, files.length - 1);
  files = encodeURIComponent(files);

  let links = document.querySelectorAll("#download ul a");
  Array.from(links).forEach(link => {
    link.href = "?download=" + link.dataset.format + "&files=" + files;
  });
}

listing.openItem = function (event) {
  window.location = event.currentTarget.dataset.url;
}

listing.selectItem = function (event) {
  let el = event.currentTarget;

  if(selectedItems.length != 0) event.preventDefault();
  if(selectedItems.indexOf(el.id) == -1) {
    if(!event.ctrlKey && !listing.selectMultiple) listing.unselectAll();

    el.setAttribute("aria-selected", true);
    selectedItems.push(el.id);
  } else {
    el.setAttribute("aria-selected", false);
    selectedItems.removeElement(el.id);
  }

  listing.handleSelectionChange();
  return false;
}

listing.newFileButton = function (event) {
  event.preventDefault();

  let clone = document.importNode(templates.question.content, true);
  clone.querySelector('h3').innerHTML = 'New file';
  clone.querySelector('p').innerHTML = 'End with a trailing slash to create a dir.';
  clone.querySelector('.ok').innerHTML = 'Create';
  clone.querySelector('form').addEventListener('submit', listing.newFilePrompt);

  document.querySelector('body').appendChild(clone)
  document.querySelector('.overlay').classList.add('active');
  document.querySelector('.prompt').classList.add('active');
}

listing.newFilePrompt = function (event) {
  event.preventDefault();
  buttons.setLoading('new');

  let name = event.currentTarget.querySelector('input').value;

  webdav.new(window.location.pathname + name)
    .then(() => {
      buttons.setDone('new');
      listing.reload();
    })
    .catch(e => {
      console.log(e);
      buttons.setDone('new', false);
    });

  closePrompt(event);
  return false;
}

listing.updateColumns = function (event) {
  let columns = Math.floor(document.getElementById('listing').offsetWidth / 300),
    items = getCSSRule(['#listing.mosaic .item', '.mosaic#listing .item']);

  items.style.width = `calc(${100/columns}% - 1em)`;
}

listing.addDoubleTapEvent = function () {
  let items = document.getElementsByClassName('item'),
    touches = {
      id: '',
      count: 0
    };

  Array.from(items).forEach(file => {
    file.addEventListener('touchstart', event => {
      if(touches.id != file.id) {
        touches.id = file.id;
        touches.count = 1;

        setTimeout(() => {
          touches.count = 0;
        }, 300)

        return;
      }

      touches.count++;

      if(touches.count > 1) {
        window.location = file.dataset.url;
      }
    });
  });
}

// Keydown events
window.addEventListener('keydown', (event) => {
  if(event.keyCode == 27) {
    listing.unselectAll();

    if(document.querySelectorAll('.prompt').length) {
      closePrompt(event);
    }
  }

  if(event.keyCode == 113) {
    listing.rename();
  }

  if(event.ctrlKey || event.metaKey) {
    switch(String.fromCharCode(event.which).toLowerCase()) {
    case 's':
      event.preventDefault();
      window.location = "?download=true"
    }
  }
});

window.addEventListener("resize", () => {
  listing.updateColumns();
});

listing.selectMoveFolder = function (event) {
  if(event.target.getAttribute("aria-selected") === "true") {
    event.target.setAttribute("aria-selected", false);
    return;
  } else {
    if(document.querySelector(".file-list li[aria-selected=true]")) {
      document.querySelector(".file-list li[aria-selected=true]").setAttribute("aria-selected", false);
    }
    event.target.setAttribute("aria-selected", true);
    return;
  }
}

listing.getJSON = function (link) {
  return new Promise((resolve, reject) => {
    let request = new XMLHttpRequest();
    request.open("GET", link);
    request.setRequestHeader("Accept", "application/json");
    request.onload = () => {
      if(request.status == 200) {
        resolve(request.responseText);
      } else {
        reject(request.statusText);
      }
    }
    request.onerror = () => reject(request.statusText);
    request.send();
  });
}

listing.moveMakeItem = function (url, name) {
  let node = document.createElement("li");

  node.dataset.url = url;
  node.innerHTML = name;
  node.setAttribute("aria-selected", false);

  node.addEventListener("dblclick", listing.moveDialogNext);
  node.addEventListener("click", listing.selectMoveFolder);
  return node;
}

listing.moveDialogNext = function (event) {
  let request = new XMLHttpRequest(),
    prompt = document.querySelector("form.prompt.active"),
    list = prompt.querySelector("div.file-list ul");

  prompt.addEventListener("submit", listing.moveSelected);

  listing.getJSON(event.target.dataset.url)
    .then((data) => {
      let dirs = 0;

      prompt.querySelector("ul").innerHTML = "";
      prompt.querySelector('code').innerHTML = event.target.dataset.url;

      if(event.target.dataset.url != baseURL + "/") {
        let node = listing.moveMakeItem(removeLastDirectoryPartOf(event.target.dataset.url) + "/", "..")
        list.appendChild(node);
      }

      if(JSON.parse(data) == null) {
        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
        return;
      }

      for(let f of JSON.parse(data)) {
        if(f.IsDir === true) {
          dirs++;
          list.appendChild(listing.moveMakeItem(f.URL, f.Name));
        }
      }

      if(dirs === 0)
        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
    })
    .catch(e => console.log(e));
}

listing.moveSelected = function (event) {
  event.preventDefault();

  let promises = [];
  buttons.setLoading("move");

  for(let file of selectedItems) {
    let fileElement = document.getElementById(file),
      destFolder = event.target.querySelector("p code").innerHTML;

    if(event.currentTarget.querySelector("li[aria-selected=true]") != null) {
      destFolder = event.currentTarget.querySelector("li[aria-selected=true]").dataset.url;
    }

    let destPath = "/" + destFolder + "/" + fileElement.querySelector(".name").innerHTML;
    destPath = destPath.replace('//', '/');

    promises.push(webdav.move(fileElement.dataset.url, destPath));
  }

  Promise.all(promises)
    .then(() => {
      closePrompt(event);
      buttons.setDone("move");
      listing.reload();
    })
    .catch(e => {
      console.log(e);
    })
}

listing.moveEvent = function (event) {
  if(event.currentTarget.classList.contains("disabled"))
    return;

  listing.getJSON(window.location.pathname)
    .then((data) => {
      let prompt = document.importNode(templates.move.content, true),
        list = prompt.querySelector("div.file-list ul"),
        dirs = 0;

      prompt.querySelector("form").addEventListener("submit", listing.moveSelected);
      prompt.querySelector('code').innerHTML = window.location.pathname;

      if(window.location.pathname !== baseURL + "/") {
        list.appendChild(listing.moveMakeItem(removeLastDirectoryPartOf(window.location.pathname) + "/", ".."));
      }

      for(let f of JSON.parse(data)) {
        if(f.IsDir === true) {
          dirs++;
          list.appendChild(listing.moveMakeItem(f.URL, f.Name));
        }
      }

      if(dirs === 0) {
        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
      }

      document.body.appendChild(prompt);
      document.querySelector(".overlay").classList.add("active");
      document.querySelector(".prompt").classList.add("active");
    })
    .catch(e => console.log(e));
}

document.addEventListener('DOMContentLoaded', event => {
  listing.updateColumns();
  listing.addDoubleTapEvent();

  buttons.rename = document.getElementById("rename");
  buttons.upload = document.getElementById("upload");
  buttons.new = document.getElementById('new');
  buttons.download = document.getElementById('download');
  buttons.move = document.getElementById("move");

  buttons.move.addEventListener("click", listing.moveEvent);

  document.getElementById('multiple-selection-activate').addEventListener('click', event => {
    listing.selectMultiple = true;
    clickOverlay.click();

    document.getElementById('multiple-selection').classList.add('active');
    document.querySelector('body').style.paddingBottom = "4em";
  })

  document.getElementById('multiple-selection-cancel').addEventListener('click', event => {
    listing.selectMultiple = false;

    document.querySelector('body').style.paddingBottom = "0";
    document.getElementById('multiple-selection').classList.remove('active');
  })

  if(user.AllowEdit) {
    buttons.rename.addEventListener("click", listing.rename);
  }

  let items = document.getElementsByClassName('item');

  if(user.AllowNew) {
    buttons.upload.addEventListener("click", (event) => {
      document.getElementById("upload-input").click();
    });

    buttons.new.addEventListener('click', listing.newFileButton);

    // Drag and Drop
    document.addEventListener("dragover", function (event) {
      event.preventDefault();
    }, false);

    document.addEventListener("dragenter", (event) => {
      Array.from(items).forEach(file => {
        file.style.opacity = 0.5;
      });
    }, false);

    document.addEventListener("dragend", (event) => {
      Array.from(items).forEach(file => {
        file.style.opacity = 1;
      });
    }, false);

    document.addEventListener("drop", listing.documentDrop, false);
  }

});
<|endoftext|>


<commit_before>/*
 EnvJasmine: Jasmine test runner for EnvJS.

 EnvJasmine allows you to run headless JavaScript tests.

 Based on info from:
 http://agile.dzone.com/news/javascript-bdd-jasmine-without
 http://www.mozilla.org/rhino/
 http://www.envjs.com/
 http://pivotal.github.com/jasmine/
 https://github.com/velesin/jasmine-jquery
*/

importPackage(java.lang);
importPackage(java.io);
importPackage(org.mozilla.javascript);

var cx = Context.getCurrentContext();

cx.setOptimizationLevel(-1);

// Create the EnvJasmine namespace
if (!this.EnvJasmine) {
    this.EnvJasmine = {};
}

EnvJasmine.about = function () {
    print("Usage: envjasmine.js --suppressConsoleMsgs --disableColor --environment=<WIN|UNIX> --testDir=<Directory holding tests, if not in the EnvJasmine Directory> --rootDir=<EnvJasmine Root Directory> [<js spec files>...]");
    System.exit(1);
};

EnvJasmine.normalizePath = function(path) {
    var endsInSlash = (path.slice(-1) == "/");

    if (path.slice(0, 1) == ".") {
        path = EnvJasmine.rootDir + "/" + path;
    }

    return File(path).getCanonicalPath() + (endsInSlash ? "/" : "");
};

EnvJasmine.load = (function() {
    var loaded = [];

    return function(path) {
        if (loaded.indexOf(path) == -1) {
            loaded.push(path);

            load(EnvJasmine.normalizePath(path));
        }
    };
}());

// Process command line options

(function(argumentList) {
    var arg, nameValue, spec = "";

    EnvJasmine.specs = [];
    EnvJasmine.passedCount = 0;
    EnvJasmine.failedCount = 0;
    EnvJasmine.totalCount = 0;

    for (var i = 0; i < argumentList.length; i++) {
        arg = argumentList[i];

        if (arg.slice(0, 2) == "--") {
            nameValue = arg.slice(2).split('=');

            switch(nameValue[0]) {
                case "testDir":
                    EnvJasmine.testDir = EnvJasmine.normalizePath(nameValue[1]);
                    break;
                case "rootDir":
                    EnvJasmine.rootDir = EnvJasmine.normalizePath(nameValue[1]);
                    break;
                case "environment":
                    EnvJasmine.environment = nameValue[1];
                    break;
                case "configFile":
                    EnvJasmine.configFile = EnvJasmine.normalizePath(nameValue[1]);
                    break;
                case "disableColor":
                    EnvJasmine.disableColor = true;
                    break;
                case "supressConsoleMsgs":
                    EnvJasmine.suppressConsoleMsgs = true;
                    break;
                default:
                    print("Unknown option: " + arg);
                    break;
            }
        } else {
            if (arg.slice(-3) !== ".js") {
                spec += arg + " ";
            } else {
                spec += arg;
                EnvJasmine.specs.push(EnvJasmine.normalizePath(EnvJasmine.rootDir + "/" + spec));
                spec = "";
            }
        }
    }
}(arguments));

if (typeof EnvJasmine.rootDir == "undefined" || typeof EnvJasmine.environment == "undefined") {
    EnvJasmine.about();
}

EnvJasmine.SEPARATOR = (function (env) {
    if (env == "UNIX") {
        return "/";
    } else if  (env == "WIN") {
        return "\\";
    } else {
        EnvJasmine.about();
    }
}(EnvJasmine.environment));

EnvJasmine.disableColor = (function (env) {
    return EnvJasmine.disableColor || (env == "WIN");
}(EnvJasmine.environment));

if (EnvJasmine.disableColor) {
    EnvJasmine.green = "";
    EnvJasmine.red = "";
    EnvJasmine.endColor = "";
} else {
    EnvJasmine.green = "\033[32m";
    EnvJasmine.red = "\033[31m";
    EnvJasmine.endColor = "\033[0m";
}

// These are standard driectories in the EnvJasmine project.
EnvJasmine.libDir = EnvJasmine.rootDir + "/lib/";
EnvJasmine.includeDir = EnvJasmine.rootDir + "/include/";
EnvJasmine.specSuffix = new RegExp(/.spec.js$/);

// Load the envjasmine environment
EnvJasmine.loadEnv = function () {
    EnvJasmine.load(EnvJasmine.libDir + "envjs/env.rhino.1.2.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine/jasmine.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-ajax/mock-ajax.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-ajax/spec-helper.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-jquery/jasmine-jquery-1.2.0.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-rhino-reporter/jasmine-rhino-reporter.js");
};

// Load external dependencies
if (typeof EnvJasmine.configFile == "undefined") {
    EnvJasmine.configFile = EnvJasmine.includeDir + "dependencies.js";
}
EnvJasmine.loadConfig = function () {
    EnvJasmine.load(EnvJasmine.configFile);
};

if (typeof EnvJasmine.testDir == 'undefined') {
    EnvJasmine.testDir = EnvJasmine.rootDir;
}

if (typeof EnvJasmine.mocksDir == 'undefined') {
    EnvJasmine.mocksDir = EnvJasmine.testDir + "/mocks/";
}

if (typeof EnvJasmine.specsDir == 'undefined') {
    EnvJasmine.specsDir = EnvJasmine.testDir + "/specs/";
}

EnvJasmine.testDir = EnvJasmine.normalizePath(EnvJasmine.testDir);
EnvJasmine.mocksDir = EnvJasmine.normalizePath(EnvJasmine.mocksDir);
EnvJasmine.specsDir = EnvJasmine.normalizePath(EnvJasmine.specsDir);

(function() {
    var i, fileIn, len, scope;

    EnvJasmine.loadEnv();
    EnvJasmine.loadConfig();

    if (EnvJasmine.suppressConsoleMsgs === true) {
        // suppress console messages
        window.console = $.extend({}, window.console, {
            info: jasmine.createSpy(),
            log: jasmine.createSpy(),
            debug: jasmine.createSpy(),
            warning: jasmine.createSpy(),
            error: jasmine.createSpy()
        });
    }

    EnvJasmine.load(EnvJasmine.libDir + "spanDir/spanDir.js");
    if (EnvJasmine.specs.length == 0) {
        spanDir(EnvJasmine.specsDir, function(spec) {
            if (EnvJasmine.specSuffix.test(spec)) {
                EnvJasmine.specs.push(spec);
            }
        });
    }

    for (i = 0, len = EnvJasmine.specs.length >>> 0; i < len; i += 1) {
        print("Loading " + EnvJasmine.specs[i]);
        try {
            scope = {};
            fileIn = new FileReader(EnvJasmine.specs[i]);
            cx.evaluateReader(scope, fileIn, '<load>', 0, null);
            cx.evaluateString(scope, 'window.location.assign(["file://", EnvJasmine.libDir, "envjasmine.html"].join(EnvJasmine.SEPARATOR));', '<exec>', 0, null);
        }
        finally {
            fileIn.close();
        }
    }

    print("Final Results:");
    print(EnvJasmine.green + "Final Passed: " + EnvJasmine.passedCount + EnvJasmine.endColor);
    print(EnvJasmine.red + "Final Failed: " + EnvJasmine.failedCount + EnvJasmine.endColor);
    print("Final Total: " + EnvJasmine.totalCount);
}());
<commit_msg>Cleaned up how default directories were being allocated.<commit_after>/*
 EnvJasmine: Jasmine test runner for EnvJS.

 EnvJasmine allows you to run headless JavaScript tests.

 Based on info from:
 http://agile.dzone.com/news/javascript-bdd-jasmine-without
 http://www.mozilla.org/rhino/
 http://www.envjs.com/
 http://pivotal.github.com/jasmine/
 https://github.com/velesin/jasmine-jquery
*/

importPackage(java.lang);
importPackage(java.io);
importPackage(org.mozilla.javascript);

var cx = Context.getCurrentContext();

cx.setOptimizationLevel(-1);

// Create the EnvJasmine namespace
if (!this.EnvJasmine) {
    this.EnvJasmine = {};
}

EnvJasmine.about = function () {
    print("Usage: envjasmine.js --suppressConsoleMsgs --disableColor --environment=<WIN|UNIX> --testDir=<Directory holding tests, if not in the EnvJasmine Directory> --rootDir=<EnvJasmine Root Directory> [<js spec files>...]");
    System.exit(1);
};

EnvJasmine.normalizePath = function(path) {
    var endsInSlash = (path.slice(-1) == "/");

    if (path.slice(0, 1) == ".") {
        path = EnvJasmine.rootDir + "/" + path;
    }

    return File(path).getCanonicalPath() + (endsInSlash ? "/" : "");
};

EnvJasmine.load = (function() {
    var loaded = [];

    return function(path) {
        if (loaded.indexOf(path) == -1) {
            loaded.push(path);

            load(EnvJasmine.normalizePath(path));
        }
    };
}());

EnvJasmine.setRootDir = function (rootDir) {
    // These are standard directories in the EnvJasmine project.
    EnvJasmine.rootDir = EnvJasmine.normalizePath(rootDir);
    EnvJasmine.libDir = EnvJasmine.normalizePath(EnvJasmine.rootDir + "/lib/");
    EnvJasmine.includeDir = EnvJasmine.normalizePath(EnvJasmine.rootDir + "/include/");

    // This is the standard spec suffix
    // TODO: Make this configurable.
    EnvJasmine.specSuffix = new RegExp(/.spec.js$/);

    // Load the default dirs and files, these can be overridden with command line options
    EnvJasmine.configFile = EnvJasmine.normalizePath(EnvJasmine.includeDir + "dependencies.js");
};

EnvJasmine.setTestDir = function (testDir, override) {
    if (typeof EnvJasmine.testDir === "undefined" || !EnvJasmine.testDir || override) {
        EnvJasmine.testDir = EnvJasmine.normalizePath(testDir);
        EnvJasmine.mocksDir = EnvJasmine.normalizePath(EnvJasmine.testDir + "/mocks/");
        EnvJasmine.specsDir = EnvJasmine.normalizePath(EnvJasmine.testDir + "/specs/");
    }
};

// Process command line options

(function(argumentList) {
    var arg, nameValue, spec = "";

    EnvJasmine.specs = [];
    EnvJasmine.passedCount = 0;
    EnvJasmine.failedCount = 0;
    EnvJasmine.totalCount = 0;

    for (var i = 0; i < argumentList.length; i++) {
        arg = argumentList[i];

        if (arg.slice(0, 2) == "--") {
            nameValue = arg.slice(2).split('=');

            switch(nameValue[0]) {
                case "testDir":
                    EnvJasmine.setTestDir(nameValue[1], true);
                    break;
                case "rootDir":
                    EnvJasmine.setRootDir(nameValue[1]);
                    EnvJasmine.setTestDir(nameValue[1]); // Set the root as the default testDir.
                    break;
                case "environment":
                    EnvJasmine.environment = nameValue[1];
                    break;
                case "configFile":
                    EnvJasmine.configFile = EnvJasmine.normalizePath(nameValue[1]);
                    break;
                case "disableColor":
                    EnvJasmine.disableColor = true;
                    break;
                case "supressConsoleMsgs":
                    EnvJasmine.suppressConsoleMsgs = true;
                    break;
                default:
                    print("Unknown option: " + arg);
                    break;
            }
        } else {
            if (arg.slice(-3) !== ".js") {
                spec += arg + " ";
            } else {
                spec += arg;
                EnvJasmine.specs.push(EnvJasmine.normalizePath(EnvJasmine.testDir + "/" + spec));
                spec = "";
            }
        }
    }
}(arguments));

if (typeof EnvJasmine.rootDir == "undefined" || typeof EnvJasmine.environment == "undefined") {
    EnvJasmine.about();
}

EnvJasmine.SEPARATOR = (function (env) {
    if (env == "UNIX") {
        return "/";
    } else if  (env == "WIN") {
        return "\\";
    } else {
        EnvJasmine.about();
    }
}(EnvJasmine.environment));

EnvJasmine.disableColor = (function (env) {
    return EnvJasmine.disableColor || (env == "WIN");
}(EnvJasmine.environment));

if (EnvJasmine.disableColor) {
    EnvJasmine.green = "";
    EnvJasmine.red = "";
    EnvJasmine.endColor = "";
} else {
    EnvJasmine.green = "\033[32m";
    EnvJasmine.red = "\033[31m";
    EnvJasmine.endColor = "\033[0m";
}

// Load the envjasmine environment
EnvJasmine.loadEnv = function () {
    EnvJasmine.load(EnvJasmine.libDir + "envjs/env.rhino.1.2.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine/jasmine.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-ajax/mock-ajax.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-ajax/spec-helper.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-jquery/jasmine-jquery-1.2.0.js");
    EnvJasmine.load(EnvJasmine.libDir + "jasmine-rhino-reporter/jasmine-rhino-reporter.js");
};

EnvJasmine.loadConfig = function () {
    EnvJasmine.load(EnvJasmine.configFile);
};

(function() {
    var i, fileIn, len, scope;

    EnvJasmine.loadEnv();
    EnvJasmine.loadConfig();

    if (EnvJasmine.suppressConsoleMsgs === true) {
        // suppress console messages
        window.console = $.extend({}, window.console, {
            info: jasmine.createSpy(),
            log: jasmine.createSpy(),
            debug: jasmine.createSpy(),
            warning: jasmine.createSpy(),
            error: jasmine.createSpy()
        });
    }

    EnvJasmine.load(EnvJasmine.libDir + "spanDir/spanDir.js");
    if (EnvJasmine.specs.length == 0) {
        spanDir(EnvJasmine.specsDir, function(spec) {
            if (EnvJasmine.specSuffix.test(spec)) {
                EnvJasmine.specs.push(spec);
            }
        });
    }

    for (i = 0, len = EnvJasmine.specs.length >>> 0; i < len; i += 1) {
        print("Loading " + EnvJasmine.specs[i]);
        try {
            scope = {};
            fileIn = new FileReader(EnvJasmine.specs[i]);
            cx.evaluateReader(scope, fileIn, '<load>', 0, null);
            cx.evaluateString(scope, 'window.location.assign(["file://", EnvJasmine.libDir, "envjasmine.html"].join(EnvJasmine.SEPARATOR));', '<exec>', 0, null);
        }
        finally {
            fileIn.close();
        }
    }

    print("Final Results:");
    print(EnvJasmine.green + "Final Passed: " + EnvJasmine.passedCount + EnvJasmine.endColor);
    print(EnvJasmine.red + "Final Failed: " + EnvJasmine.failedCount + EnvJasmine.endColor);
    print("Final Total: " + EnvJasmine.totalCount);
}());
<|endoftext|>


<commit_before>"use strict";
var inherits = require('util').inherits;
var StackKeeper = require('./stack_keeper');

var ErrorBase = function () {
	Error.call(this);
	this.stackKeeper = this.createStackKeeper();
};
inherits(ErrorBase, Error);

ErrorBase.prototype.name = 'ErrorBase';

ErrorBase.prototype.createStackKeeper = function () {
	var result = new StackKeeper();
	Error.captureStackTrace(result, this.constructor);
	return result;
};

ErrorBase.prototype.toString = function () {
	var result = this.name;
	var message = this.getMessage();
	if (message)
	{
		result = [result, this.getMessage()].join(': ');
	}
	return result;
};

ErrorBase.prototype.getMessage = function () {
	return 'Generic error';
};

ErrorBase.prototype.getStackTrace = function () {
	return this.toString() + this.stackKeeper.stack;
};

Object.defineProperties(ErrorBase.prototype, {
	stack: {
		get: function () {
			return this.getStackTrace();
		}
	},
	message: {
		get: function () {
			return this.getMessage();
		}
	}
});

module.exports = ErrorBase;
<commit_msg>ErrorBase.prototype.toString - removed unnecessary secondary getMessage call<commit_after>"use strict";
var inherits = require('util').inherits;
var StackKeeper = require('./stack_keeper');

var ErrorBase = function () {
	Error.call(this);
	this.stackKeeper = this.createStackKeeper();
};
inherits(ErrorBase, Error);

ErrorBase.prototype.name = 'ErrorBase';

ErrorBase.prototype.createStackKeeper = function () {
	var result = new StackKeeper();
	Error.captureStackTrace(result, this.constructor);
	return result;
};

ErrorBase.prototype.toString = function () {
	var result = this.name;
	var message = this.getMessage();
	if (message)
	{
		result = [result, message].join(': ');
	}
	return result;
};

ErrorBase.prototype.getMessage = function () {
	return 'Generic error';
};

ErrorBase.prototype.getStackTrace = function () {
	return this.toString() + this.stackKeeper.stack;
};

Object.defineProperties(ErrorBase.prototype, {
	stack: {
		get: function () {
			return this.getStackTrace();
		}
	},
	message: {
		get: function () {
			return this.getMessage();
		}
	}
});

module.exports = ErrorBase;
<|endoftext|>


<commit_before>const _ = require('lodash')
const moment = require('moment-timezone')
const logging = require('../homeautomation-js-lib/logging.js')
var Jexl = require('jexl')
const Queue = require('bull')

const redisHost = process.env.REDIS_HOST
const redisPort = process.env.REDIS_PORT

var TIMEZONE = process.env.TIMEZONE

if (_.isNil(TIMEZONE)) {
    TIMEZONE = process.env.TZ
}

if (_.isNil(TIMEZONE)) {
    TIMEZONE = 'UTC'
}

const utilities = require('./utilities.js')
const actions = require('./actions.js')

var evalQueues = {}

function evaluateProcessor(job, doneEvaluate) {
    const queue_time = job.data.queue_time
    const name = job.data.name
    const topic = job.data.topic
    const context = job.data.context_value
    const rule = job.data.rule
    const allowed_times = rule.allowed_times
    const startTime = new Date().getTime()

    var logResult = {
        action: 'rule-time-evaluation',
        rule_name: name,
        rule: rule,
        topic: topic,
        allowed_times: allowed_times,
        context: context
    }
    var isOKTime = true

    logging.verbose(' evaluation queue: ' + name, {
        action: 'evaluate-process-start',
        rule_name: name,
        queue_time: (startTime - queue_time)
    })
    const currentDate = moment(new Date()).tz(TIMEZONE)

    if (!_.isNil(allowed_times)) {
        isOKTime = false

        allowed_times.forEach(function(timeRange) {
            const split = timeRange.split('-')
            logging.debug(' time range from: ' + split[0] + '   to: ' + split[1])

            const startDate = moment(new Date())
            const endDate = moment(new Date())

            const startHours = split[0].split(':')[0]
            const startMinutes = split[0].split(':')[1]

            const endHours = split[1].split(':')[0]
            const endMinutes = split[1].split(':')[1]

            startDate.hours(Number(startHours))
            startDate.minutes(Number(startMinutes))
            endDate.hours(Number(endHours))
            endDate.minutes(Number(endMinutes))
            const result = currentDate.isBetween(startDate.tz(TIMEZONE), endDate.tz(TIMEZONE))
            if (result == true) {
                isOKTime = true
            }
        }, this)
    }

    if (!isOKTime) {
        logging.info('not evaluating, bad time (' + currentDate + ')  =>(' + name + ')', logResult)
        logging.debug('eval queue: ' + name + '    end - not a good time')
        logging.verbose(' evaluation queue: ' + name, {
            action: 'evaluate-process-done',
            rule_name: name,
            queue_time: ((new Date().getTime()) - startTime)
        })

        if (!_.isNil(doneEvaluate))
            doneEvaluate()

        return
    }
    logging.info('evaluating, good time  (' + currentDate + ') =>(' + name + ')', logResult)

    if (!_.isNil(rule.rules) && !_.isNil(rule.rules.expression)) {
        const expression = utilities.prepareExpression(topic, utilities.update_topic_for_expression(rule.rules.expression), context)
        var jexl = new Jexl.Jexl()
        const beginTime = new Date()
        jexl.eval(expression, context, function(error, result) {
            logging.info('  =>(' + name + ') evaluated expression', Object.assign(logResult, {
                action: 'evaluated-expression',
                result: result,
                evaluation_time: ((new Date().getTime()) - beginTime.getTime()),
                error: error
            }))
            actions.performAction(result, context, name, rule, logResult)
            logging.debug('eval queue: ' + name + '    end expression')
        })
    } else {
        logging.info('  =>(' + name + ') skipped evaluated expression', Object.assign(logResult, {
            action: 'no-expression-to-evaluate'
        }))
        actions.performAction(true, context, name, rule, logResult)
        logging.debug('eval queue: ' + name + '    end expression - no expression')
    }

    logging.verbose(' evaluation queue: ' + name, {
        action: 'evaluate-process-done',
        rule_name: name,
        queue_time: ((new Date().getTime()) - startTime)
    })
    if (!_.isNil(doneEvaluate))
        doneEvaluate()
}

exports.evalulateValue = function(topic, in_context, name, rule) {
    var queueName = name + '_eval'
    var evalQueue = evalQueues[queueName]

    if (!_.isNil(evalQueue)) {
        evalQueue.empty()
    }

    actions.clearQueue(name)
    const customQueueName = rule.queue

    var evaluateAfter = rule.evaluate_after
    if (_.isNil(evaluateAfter)) {
        evaluateAfter = 0
    }

    if (!_.isNil(customQueueName)) {
        queueName = customQueueName
    }

    evalQueue = Queue(queueName, redisPort, redisHost)
    evalQueues[queueName] = evalQueue

    evalQueue.process(evaluateProcessor)

    var job = {
        rule: rule,
        name: '' + name,
        topic: topic,
        queue_time: (new Date().getTime()),
        context_value: {}
    }

    Object.keys(in_context).forEach(function(key) {
        job.context_value[key] = '' + in_context[key]
    }, this)

    if (evaluateAfter > 0)
        logging.info('enqueued expression evaluation =>(' + rule + ')    for: ' + evaluateAfter)

    logging.verbose('enqueued expression evaluation =>(' + queueName + ')', {
        action: 'enqueued-evaluation',
        delay: evaluateAfter,
        rule_name: name,
        rule: rule,
        queue_name: queueName
    })

    if (evaluateAfter === 0) {
        job.data = job
        evaluateProcessor(job, null)
    } else {
        evalQueue.add(job, {
            removeOnComplete: true,
            removeOnFail: true,
            delay: (evaluateAfter * 1000), // milliseconds
        })
    }
}

exports.clearQueues = function() {
    Object.keys(evalQueues).forEach(function(element) {
        var evalQueue = evalQueues[element]
        if (!_.isNil(evalQueue)) {
            evalQueue.empty()
        }

    }, this)

    actions.clearQueues()
}<commit_msg>Fixing format<commit_after>const _ = require('lodash')
const moment = require('moment-timezone')
const logging = require('../homeautomation-js-lib/logging.js')
var Jexl = require('jexl')
const Queue = require('bull')

const redisHost = process.env.REDIS_HOST
const redisPort = process.env.REDIS_PORT

var TIMEZONE = process.env.TIMEZONE

if (_.isNil(TIMEZONE)) {
    TIMEZONE = process.env.TZ
}

if (_.isNil(TIMEZONE)) {
    TIMEZONE = 'UTC'
}

const utilities = require('./utilities.js')
const actions = require('./actions.js')

var evalQueues = {}

function evaluateProcessor(job, doneEvaluate) {
    const queue_time = job.data.queue_time
    const name = job.data.name
    const topic = job.data.topic
    const context = job.data.context_value
    const rule = job.data.rule
    const allowed_times = rule.allowed_times
    const startTime = new Date().getTime()

    var logResult = {
        action: 'rule-time-evaluation',
        rule_name: name,
        rule: rule,
        topic: topic,
        allowed_times: allowed_times,
        context: context
    }
    var isOKTime = true

    logging.verbose(' evaluation queue: ' + name, {
        action: 'evaluate-process-start',
        rule_name: name,
        queue_time: (startTime - queue_time)
    })
    const currentDate = moment(new Date()).tz(TIMEZONE)

    if (!_.isNil(allowed_times)) {
        isOKTime = false

        allowed_times.forEach(function(timeRange) {
            const split = timeRange.split('-')
            logging.debug(' time range from: ' + split[0] + '   to: ' + split[1])

            const startDate = moment(new Date())
            const endDate = moment(new Date())

            const startHours = split[0].split(':')[0]
            const startMinutes = split[0].split(':')[1]

            const endHours = split[1].split(':')[0]
            const endMinutes = split[1].split(':')[1]

            startDate.hours(Number(startHours))
            startDate.minutes(Number(startMinutes))
            endDate.hours(Number(endHours))
            endDate.minutes(Number(endMinutes))
            const result = currentDate.isBetween(startDate.tz(TIMEZONE), endDate.tz(TIMEZONE))
            if (result == true) {
                isOKTime = true
            }
        }, this)
    }

    if (!isOKTime) {
        logging.info('not evaluating, bad time (' + currentDate + ')  =>(' + name + ')', logResult)
        logging.debug('eval queue: ' + name + '    end - not a good time')
        logging.verbose(' evaluation queue: ' + name, {
            action: 'evaluate-process-done',
            rule_name: name,
            queue_time: ((new Date().getTime()) - startTime)
        })

        if (!_.isNil(doneEvaluate))
            doneEvaluate()

        return
    }
    logging.info('evaluating, good time  (' + currentDate.format('MMMM Do YYYY, h:mm:ss a') + ') =>(' + name + ')', logResult)

    if (!_.isNil(rule.rules) && !_.isNil(rule.rules.expression)) {
        const expression = utilities.prepareExpression(topic, utilities.update_topic_for_expression(rule.rules.expression), context)
        var jexl = new Jexl.Jexl()
        const beginTime = new Date()
        jexl.eval(expression, context, function(error, result) {
            logging.info('  =>(' + name + ') evaluated expression', Object.assign(logResult, {
                action: 'evaluated-expression',
                result: result,
                evaluation_time: ((new Date().getTime()) - beginTime.getTime()),
                error: error
            }))
            actions.performAction(result, context, name, rule, logResult)
            logging.debug('eval queue: ' + name + '    end expression')
        })
    } else {
        logging.info('  =>(' + name + ') skipped evaluated expression', Object.assign(logResult, {
            action: 'no-expression-to-evaluate'
        }))
        actions.performAction(true, context, name, rule, logResult)
        logging.debug('eval queue: ' + name + '    end expression - no expression')
    }

    logging.verbose(' evaluation queue: ' + name, {
        action: 'evaluate-process-done',
        rule_name: name,
        queue_time: ((new Date().getTime()) - startTime)
    })
    if (!_.isNil(doneEvaluate))
        doneEvaluate()
}

exports.evalulateValue = function(topic, in_context, name, rule) {
    var queueName = name + '_eval'
    var evalQueue = evalQueues[queueName]

    if (!_.isNil(evalQueue)) {
        evalQueue.empty()
    }

    actions.clearQueue(name)
    const customQueueName = rule.queue

    var evaluateAfter = rule.evaluate_after
    if (_.isNil(evaluateAfter)) {
        evaluateAfter = 0
    }

    if (!_.isNil(customQueueName)) {
        queueName = customQueueName
    }

    evalQueue = Queue(queueName, redisPort, redisHost)
    evalQueues[queueName] = evalQueue

    evalQueue.process(evaluateProcessor)

    var job = {
        rule: rule,
        name: '' + name,
        topic: topic,
        queue_time: (new Date().getTime()),
        context_value: {}
    }

    Object.keys(in_context).forEach(function(key) {
        job.context_value[key] = '' + in_context[key]
    }, this)

    if (evaluateAfter > 0)
        logging.info('enqueued expression evaluation =>(' + name + ')    for: ' + evaluateAfter)

    logging.verbose('enqueued expression evaluation =>(' + queueName + ')', {
        action: 'enqueued-evaluation',
        delay: evaluateAfter,
        rule_name: name,
        rule: rule,
        queue_name: queueName
    })

    if (evaluateAfter === 0) {
        job.data = job
        evaluateProcessor(job, null)
    } else {
        evalQueue.add(job, {
            removeOnComplete: true,
            removeOnFail: true,
            delay: (evaluateAfter * 1000), // milliseconds
        })
    }
}

exports.clearQueues = function() {
    Object.keys(evalQueues).forEach(function(element) {
        var evalQueue = evalQueues[element]
        if (!_.isNil(evalQueue)) {
            evalQueue.empty()
        }

    }, this)

    actions.clearQueues()
}<|endoftext|>