<commit_before>var templateName = 'dropdown';
var TemplateClass = Template[templateName];

var defaultText = 'Select';

TemplateClass.created = function() {
  var data = this.data;
  var name = data.name;
  if (!name) {
    throw new Error('Name required for dropdown.');
  }
  // The next value to set once the item becomes available.
  this.nextValue = null;
};

TemplateClass.rendered = function() {
  this.isRendered = true;
  var data = this.data;
  // "atts" is only provided when used with AutoForm.
  var atts = data.atts || data;
  var $input = getValueInput(this);

  var schemaKey = atts.schemaKey;
  schemaKey = schemaKey !== undefined ? schemaKey : true;
  if (!schemaKey) {
    $input.removeAttr('data-schema-key');
  }

  var $dropdown = getDropdown(this).dropdown();
  setUpDropdown();

  // Handle changes to the collection.
  var items = atts.items;
  var cursor = items;
  // TODO(aramk) Add dependency to Collections.
  if (Collections.isCollection(items)) {
    cursor = items.find();
  }
  if (Collections.isCursor(cursor)) {
    var shouldObserve = false;
    // If passed a cursor, listen for changes and update the items reactively.
    var changeHandler = _.debounce(function() {
      shouldObserve && setUpDropdown(this);
    }.bind(this), 500);
    this._changeHandle = cursor.observe({
      added: changeHandler,
      changed: changeHandler,
      removed: changeHandler
    });
    // Delay observing to avoid the added() callback firing for existing items.
    shouldObserve = true;
  }
};

TemplateClass.destroyed = function() {
  this._changeHandle && this._changeHandle.stop();
};

TemplateClass.hasValue = function(em, value) {
  return $('.menu [data-value="' + value + '"]', resolveElement(em)).length > 0;
};

TemplateClass.setValue = function(em, value, force) {
  var $em = resolveElement(em);
  var template = Templates.getInstanceFromElement(em);
  // Sanitize the values to null if they are falsey so we don't attempt to set the value to null
  // when it's currently an empty string.
  var existingValue = TemplateClass.getValue($em);
  value = value != null ? value : null;
  var hasValue = TemplateClass.hasValue($em, value);
  if (force || value !== existingValue || !hasValue) {
    if (hasValue) {
      $em.dropdown('set value', value).dropdown('set selected', value);
      // Necessary in some cases to ensure selection has the right text.
      clearTimeout(template.setSelectedHandle);
      template.setSelectedHandle = _.defer(function() {
        $em.dropdown('set selected', value);
      });
    } else {
      $em.dropdown('set value', null).dropdown('set text', defaultText);
    }
    template.nextValue = hasValue ? null : value;
    return true;
  } else {
    return false;
  }
};

TemplateClass.getValue = function(em) {
  var $em = resolveElement(em);
  var value = null;
  if ($em.length > 0) {
    value = $em.dropdown('get value');
    if (value.toString().trim().length === 0) {
      value = null;
    }
  }
  return value;
};

TemplateClass.getItem = function(em, value) {
  var $menu = $('.menu', resolveElement(em));
  return $('.item[data-value=' + value + ']', $menu);
};

TemplateClass.bindVarToElement = function(em, reactiveVariable, args) {
  var $em = resolveElement(em);
  return Templates.bindVarToElement($em, reactiveVariable, _.extend({
    getValue: function() {
      return TemplateClass.getValue($em);
    },
    setValue: function(value) {
      TemplateClass.setValue($em, value);
    }
  }, args));
};

TemplateClass.isDropdown = function(em) {
  return resolveElement(em).length === 1;
};

function setUpDropdown(template) {
  template = getTemplate(template);
  if (!template.isRendered) {
    return;
  }

  var data = template.data;
  // "atts" is only provided when used with AutoForm.
  var atts = data.atts || data;
  var labelAttr = atts.labelAttr || 'name';
  var valueAttr = atts.valueAttr || '_id';
  var allowEmpty = atts.allowEmpty;
  var emptyLabel = atts.emptyLabel || 'None';
  var sorted = atts.sorted;
  sorted = sorted !== undefined ? sorted : false;
  var origValue = data.value;
  // The last non-empty value.
  var lastValue;
  var nextValue = template.nextValue;
  var $dropdown = getDropdown(template);

  // Save the last valid selection and restore it when possible after setup.
  var currentValue = TemplateClass.getValue($dropdown);
  if (currentValue != null) {
    lastValue = currentValue;
  } else if (nextValue) {
    lastValue = nextValue;
  }
  // TODO(aramk) This isn't efficient since we're manually recreating all items instead of
  // using the reactive template. We need a way to detect the template is re-rendered. Until then
  // this is a compromise.
  var items;
  if (data.selectOptions) {
    // AutoForm schema allowedValues.
    items = _.map(data.selectOptions, function(option) {
      var item = {};
      item[valueAttr] = option.value;
      item[labelAttr] = option.label;
      return item;
    });
  } else if (atts.items) {
    // Collection, cursor or array.
    items = Collections.getItems(atts.items);
  }
  if (!items) {
    throw new Error('Dropdown items not defined.');
  }

  // Sort items based on label.
  if (sorted) {
    items.sort(function(itemA, itemB) {
      return itemA[labelAttr].toLowerCase() < itemB[labelAttr].toLowerCase() ? -1 : 1;
    });
  }

  if (allowEmpty) {
    var emptyItem = {};
    emptyItem[labelAttr] = emptyLabel;
    emptyItem[valueAttr] = null;
    items.unshift(emptyItem);
  }
  var $menu = template.$('.menu');
  $menu.empty();
  _.each(items, function(item) {
    if (!Types.isObject(item)) {
      var value = item;
      item = {};
      item[valueAttr] = value;
      item[labelAttr] = value;
    }
    var $item = $('
' + item[labelAttr] +
        '
');
    $menu.append($item);
  });
  $dropdown.trigger('load');

  $dropdown.on('change', function() {
    var text = atts.text;
    if (text !== undefined) {
      $dropdown.dropdown('set text', text);
    }
  });

  var value = lastValue !== undefined ? lastValue : origValue;
  if (value) {
    var result = TemplateClass.setValue($dropdown, value);
    if (result) {
      TemplateClass.setValue($dropdown, value, true);
    }
    if (!TemplateClass.hasValue($dropdown, value)) {
      $dropdown.dropdown('set selected', '');
    }
  }
}

function getDropdown(template) {
  return getTemplate(template).$('.ui.dropdown');
}

function getValueInput(template) {
  return getTemplate(template).$('input');
}

function getTemplate(template) {
  return Templates.getNamedInstance(templateName, template);
}

function resolveElement(em) {
  return $(em).closest('.ui.dropdown');
}

function registerAutoForm() {
  var autoform = Package['aldeed:autoform'];
  if (typeof autoform === 'undefined') {
    console.error('Cannot register input type - AutoForm not found.');
    return;
  }
  autoform.AutoForm.addInputType('dropdown', {
    template: 'dropdown',
    valueOut: function() {
      return TemplateClass.getValue(this.closest('.dropdown'));
    }
  });
}

registerAutoForm();

TemplateClass.helpers({

  cls: function() {
    return this.name.trim().replace(/[\.\s]+/g, '-');
  },

  setUpDropdown: function() {
    setUpDropdown();
  }

});
<commit_msg>Allow modifier properties<commit_after>var templateName = 'dropdown';
var TemplateClass = Template[templateName];

var defaultText = 'Select';

TemplateClass.created = function() {
  var data = this.data;
  var name = data.name;
  if (!name) {
    throw new Error('Name required for dropdown.');
  }
  // The next value to set once the item becomes available.
  this.nextValue = null;
};

TemplateClass.rendered = function() {
  this.isRendered = true;
  var data = this.data;
  // "atts" is only provided when used with AutoForm.
  var atts = data.atts || data;
  var $input = getValueInput(this);

  var schemaKey = atts.schemaKey;
  schemaKey = schemaKey !== undefined ? schemaKey : true;
  if (!schemaKey) {
    $input.removeAttr('data-schema-key');
  }

  var $dropdown = getDropdown(this).dropdown();
  setUpDropdown();

  // Handle changes to the collection.
  var items = atts.items;
  var cursor = items;
  // TODO(aramk) Add dependency to Collections.
  if (Collections.isCollection(items)) {
    cursor = items.find();
  }
  if (Collections.isCursor(cursor)) {
    var shouldObserve = false;
    // If passed a cursor, listen for changes and update the items reactively.
    var changeHandler = _.debounce(function() {
      shouldObserve && setUpDropdown(this);
    }.bind(this), 500);
    this._changeHandle = cursor.observe({
      added: changeHandler,
      changed: changeHandler,
      removed: changeHandler
    });
    // Delay observing to avoid the added() callback firing for existing items.
    shouldObserve = true;
  }
};

TemplateClass.destroyed = function() {
  this._changeHandle && this._changeHandle.stop();
};

TemplateClass.hasValue = function(em, value) {
  return $('.menu [data-value="' + value + '"]', resolveElement(em)).length > 0;
};

TemplateClass.setValue = function(em, value, force) {
  var $em = resolveElement(em);
  var template = Templates.getInstanceFromElement(em);
  // Sanitize the values to null if they are falsey so we don't attempt to set the value to null
  // when it's currently an empty string.
  var existingValue = TemplateClass.getValue($em);
  value = value != null ? value : null;
  var hasValue = TemplateClass.hasValue($em, value);
  if (force || value !== existingValue || !hasValue) {
    if (hasValue) {
      $em.dropdown('set value', value).dropdown('set selected', value);
      // Necessary in some cases to ensure selection has the right text.
      clearTimeout(template.setSelectedHandle);
      template.setSelectedHandle = _.defer(function() {
        $em.dropdown('set selected', value);
      });
    } else {
      $em.dropdown('set value', null).dropdown('set text', defaultText);
    }
    template.nextValue = hasValue ? null : value;
    return true;
  } else {
    return false;
  }
};

TemplateClass.getValue = function(em) {
  var $em = resolveElement(em);
  var value = null;
  if ($em.length > 0) {
    value = $em.dropdown('get value');
    if (value.toString().trim().length === 0) {
      value = null;
    }
  }
  return value;
};

TemplateClass.getItem = function(em, value) {
  var $menu = $('.menu', resolveElement(em));
  return $('.item[data-value=' + value + ']', $menu);
};

TemplateClass.bindVarToElement = function(em, reactiveVariable, args) {
  var $em = resolveElement(em);
  return Templates.bindVarToElement($em, reactiveVariable, _.extend({
    getValue: function() {
      return TemplateClass.getValue($em);
    },
    setValue: function(value) {
      TemplateClass.setValue($em, value);
    }
  }, args));
};

TemplateClass.isDropdown = function(em) {
  return resolveElement(em).length === 1;
};

function setUpDropdown(template) {
  template = getTemplate(template);
  if (!template.isRendered) {
    return;
  }

  var data = template.data;
  // "atts" is only provided when used with AutoForm.
  var atts = data.atts || data;
  var labelAttr = atts.labelAttr || 'name';
  var valueAttr = atts.valueAttr || '_id';
  var allowEmpty = atts.allowEmpty;
  var emptyLabel = atts.emptyLabel || 'None';
  var sorted = atts.sorted;
  sorted = sorted !== undefined ? sorted : false;
  var origValue = data.value;
  // The last non-empty value.
  var lastValue;
  var nextValue = template.nextValue;
  var $dropdown = getDropdown(template);

  // Save the last valid selection and restore it when possible after setup.
  var currentValue = TemplateClass.getValue($dropdown);
  if (currentValue != null) {
    lastValue = currentValue;
  } else if (nextValue) {
    lastValue = nextValue;
  }
  // TODO(aramk) This isn't efficient since we're manually recreating all items instead of
  // using the reactive template. We need a way to detect the template is re-rendered. Until then
  // this is a compromise.
  var items;
  if (data.selectOptions) {
    // AutoForm schema allowedValues.
    items = _.map(data.selectOptions, function(option) {
      var item = {};
      Objects.setModifierProperty(item, valueAttr, option.value);
      Objects.setModifierProperty(item, labelAttr, option.label);
      return item;
    });
  } else if (atts.items) {
    // Collection, cursor or array.
    items = Collections.getItems(atts.items);
  }
  if (!items) {
    throw new Error('Dropdown items not defined.');
  }

  // Sort items based on label.
  if (sorted) {
    items.sort(function(itemA, itemB) {
      return Objects.getModifierProperty(itemA, labelAttr).toLowerCase() <
          Objects.getModifierProperty(itemB, labelAttr).toLowerCase() ? -1 : 1;
    });
  }

  if (allowEmpty) {
    var emptyItem = {};
    Objects.setModifierProperty(item, labelAttr, emptyLabel);
    Objects.setModifierProperty(item, valueAttr, null);
    items.unshift(emptyItem);
  }
  var $menu = template.$('.menu');
  $menu.empty();
  _.each(items, function(item) {
    if (!Types.isObject(item)) {
      var value = item;
      item = {};
      Objects.setModifierProperty(item, valueAttr, value);
      Objects.setModifierProperty(item, labelAttr, value);
    }
    var $item = $('
' + Objects.getModifierProperty(item, labelAttr) + '
');
    $menu.append($item);
  });
  $dropdown.trigger('load');

  $dropdown.on('change', function() {
    var text = atts.text;
    if (text !== undefined) {
      $dropdown.dropdown('set text', text);
    }
  });

  var value = lastValue !== undefined ? lastValue : origValue;
  if (value) {
    var result = TemplateClass.setValue($dropdown, value);
    if (result) {
      TemplateClass.setValue($dropdown, value, true);
    }
    if (!TemplateClass.hasValue($dropdown, value)) {
      $dropdown.dropdown('set selected', '');
    }
  }
}

function getDropdown(template) {
  return getTemplate(template).$('.ui.dropdown');
}

function getValueInput(template) {
  return getTemplate(template).$('input');
}

function getTemplate(template) {
  return Templates.getNamedInstance(templateName, template);
}

function resolveElement(em) {
  return $(em).closest('.ui.dropdown');
}

function registerAutoForm() {
  var autoform = Package['aldeed:autoform'];
  if (typeof autoform === 'undefined') {
    console.error('Cannot register input type - AutoForm not found.');
    return;
  }
  autoform.AutoForm.addInputType('dropdown', {
    template: 'dropdown',
    valueOut: function() {
      return TemplateClass.getValue(this.closest('.dropdown'));
    }
  });
}

registerAutoForm();

TemplateClass.helpers({

  cls: function() {
    return this.name.trim().replace(/[\.\s]+/g, '-');
  },

  setUpDropdown: function() {
    setUpDropdown();
  }

});
<|endoftext|>


<commit_before>'use strict'

import Scope from './scope'
import compare from './compare'
import EventEmitter from 'events'

/**
 *
 * DysLexer
 *
 * @constructor
 * @param {object} rootScope - The root scope
 */
export default class DysLexer extends EventEmitter {
  constructor (rootScope) {
    super()
    this.chars = ''
    this.current = 0

    // not totally correct, ah well..
    // also do not count \r as character, it has 2 chars
    // for eol.
    // TODO: should override comma as custom,
    // not as default overhere
    this.eol = ['\n', '\r', ',']

    this.scopeChar = undefined

    this.lineNumber = 0

    // default token endings
    // a scope can overwrite this temporarily
    this.tokenEnding = ['\n', '\t', ' ']

    // Tokens
    this.lastToken = undefined

    // token cache
    this.tokens = []

    // will remember all tokens in sync mode.
    this._tokens = []

    // char at which the current token started
    this.tokenStart = 0

    this.token = ''

    // the last character that triggered a scope change.
    this.scoper = undefined

    // char at which the current scope started
    this.scopeStart = 0

    // first level matchers
    this.level = {}

    // only rebuild for logging
    this.line = ''

    this.scope = this.rootScope = rootScope

    // keep track of where we are,
    // with possibility to go back
    // bit wild but works.
    this.track = []
  }

  /**
   *
   * Reset
   *
   */
  reset () {
    this.chars = ''
    this.current = 0

    this.scopeChar = undefined

    // Tokens
    this.lastToken = undefined

    // will only be remembered per line/segment
    this.tokens = []

    // will remember all tokens in sync mode.
    this._tokens = []

    this.token = ''

    // the last character that triggered a scope change.
    this.scoper = undefined

    // line is rebuild for logging
    this.line = ''

    this.lineNumber = 0

    this.scope = this.rootScope

    this.track = []
  }

  /**
   *
   * Add Scope
   *
   * Adds a new scope to the lexer.
   *
   * @param {string} scope
   */
  addScope (Scope) {
    this.level[Scope.name] = new Scope(this)
    return this.level[Scope.name]
  }

  /**
   *
   * Goes back to the scope we entered from.
   *
   * @param {string} c - Current character
   */
  back (c) {
    if (this.track.length) {
      this.toScope(this.track.pop(), c, false)
    } else {
      throw Error('Already at rootScope cannot go back')
    }
  }

  /**
   *
   * Switch to another scope
   *
   * @param {string} scope - Scope to switch to
   * @param {string} c     - Current character
   * @param {string} track - Whether to track this scope switch
   */
  toScope (scope, c, track = true) {
    // Still useful in debug mode
    // console.log('------ ' + scope + '------')
    this.emit('scopeSwitch', {
      from: this.scope,
      to: scope
    })

    if (track) {
      this.track.push(this.scope)
    }

    if (!this.level[scope]) {
      throw Error('Unknown scope: ' + scope)
    }

    // Not used...
    this.level[scope].setParent(
      this.level[this.scope]
    )

    /** check structure of the scope we left */
    this.checkStructure(this.scope)

    /** register the current scope */
    this.scope = scope

    /** inform what char did the scope */
    this.scoper = c

    /** char at which this was scoped */
    this.scopeChar = this.current

    /** reset token list */
    this.level[this.scope].tokens = []

    /** notify new scope we have entered. */
    this.level[this.scope].onEnter()
  }

  /**
   *
   *
   *
   */
  next () {
    /** take the current character */
    var c = this.chars.charAt(this.current)

    /** rebuild the line for debug purposes */
    this.line += c

    // debug
    // console.log(this.scope, ':', c)

    if (this.level[this.scope].rules[c]) {
      // this can cause weird behaviour if the rule itself
      // is redirecting the scope, which happens..
      // it means within this function this.scope is switched...
      this.level[this.scope].rules[c](c)
    } else if (this.level[this.scope].rules['**']) {
      // '**' will run whenever there is not already a match
      this.level[this.scope].rules['**'](c)
    }
    // Ok the above character matching could have switched the scope
    // it's actually the only job the character matching has...
    // but that character matching has a purpose.
    // however because we have switched scopes at _this_ exact point
    // the character will be re-considered by the other scope
    // that's the code following below.

    /** if the scope has set it's own tokenEndings.. */
    if (this.level[this.scope].tokenEnding !== undefined) {
      if (!this.tokenStart) this.tokenStart = this.current
      this.token += c

      if (this.level[this.scope].tokenEnding.indexOf(c) >= 0 &&
          // trick to catch the first ' which is not escaped
          // it's the first
          // Ok, this makes a big difference.
          // if we save the token in the other scope
          // this one will never happen.
          // right hand is set with tokenEnding
          // where left hand is set with the character matchin
          // that's not so good.
          // so switching should be done from within
          // the character matching I think.
          // that will go ok, I hope.
        this.token.length > 1 && !this.isEscaped()) {
        this.fireToken()
      }
    } else if (
      this.tokenEnding.indexOf(c) === -1 &&
      this.eol.indexOf(c) === -1) {
      /** default behaviour, build the token */
      if (!this.tokenStart) this.tokenStart = this.current
      this.token += c
    } else if (
      /** don't act if the scope took control */
    this.level[this.scope].tokenEnding === undefined &&
    this.tokenEnding.indexOf(c) >= 0) {
      this.fireToken()
    }

    // So the same should happen here as onToken, but we got to watch
    // out that we do not have duplicate tokenEnding chars and eol chars.
    if (
      // note, much responsibility for the scope.
    // should take care of it's own ending.
    this.level[this.scope].tokenEnding === undefined &&
    this.eol.indexOf(c) >= 0) {
      // fire last token
      this.fireToken()

      for (var s in this.level) {
        if (this.level.hasOwnProperty(s)) {
          this.level[s].onLineEnd()

          // do not emit lines without tokens. (empty ones)
          if (this.tokens.length) {
            this.emit('lineTokens', this.tokens, this.line, this.lineNumber)

            if (this.sync) {
              // array of tokens per line
              this._tokens.push(this.tokens)
            }

            this.lineNumber++
          }

          this.tokens = []

          this.line = ''

          // reset generic stuff from the scope.
          this.level[s].onLineStart()
        }
      }
    }

    this.current++
  }

  fireToken () {
    if (this.token) {
      if (this.level[this.scope].tokensExpected === undefined) {
        throw new Error('tokensExpected is not set for ' + this.scope)
      }

      /** validate expected token count */
      if (this.level[this.scope].tokensExpected <
        this.level[this.scope].tokens.length) {
        throw new Error([
          'Unexpected token count for',
          this.scope,
          'expected',
          this.level[this.scope].tokensExpected,
          'instead of',
          this.level[this.scope].tokens.length,
          'tokens\n\n\t',
          JSON.stringify(this.level[this.scope].tokens, null, 2),
          '\n'
        ].join(' '))
      }

      /** remember the current scope */
      var realScope = this.scope

      /** switch the current scope to root scope */
      this.scope = this.rootScope

      /**
       * If the scope has set it's own token ending
       * do not run the rootScope 'scanner'
       */
      if (this.level[realScope].tokenEnding !== undefined ||
        /** runs only if the above didn't match, which is important. */ !this.level[this.rootScope].onToken(this.token)) {
        this.scope = realScope
        if (this.scope !== this.rootScope) {
          this.level[this.scope].onToken(this.token)
        }
      }

      /** reset token */
      this.token = ''

      /** reset token start */
      this.tokenStart = undefined
    }
  }

  isEscaped () {
    // leave room to escape the choice.
    if (this.level[this.scope].escape) {
      if (this.chars.charAt(this.current - 1) === '\\') {
        return true
      }
    }

    return false
  }

// TODO: should check whether the token was handled
// or at least make sure that when we fire a token
// it is in sync with what we got presented back.
// This way we can detect unhandled tokens.
  present (name, data) {
    /** validate the token */
    if (this.level[this.scope].validate) {
      var reg = this.level[this.scope].validate[name]
      if (typeof reg === 'string') reg = new RegExp(reg) // ...
      if (reg && !reg.test(data)) {
        throw new Error([
          'Invalid',
          name,
          'token does not match',
          reg.toString(),
          '\n\n\t',
          data,
          '\n'
        ].join(' '))
      }
    }

    /**
     * Note: this relies on the scopes emitting the tokens back.
     * It does not contain each and every token emitted by this matcher.
     */
    this.lastToken = {
      name: name,
      scope: this.scope,
      value: data,
      scopeChar: this.scopeChar,
      start: this.tokenStart,
      end: this.current
    }

    /** remember token */
    this.tokens.push(this.lastToken)

    this.emit('token', this.lastToken)

    /** push token for this scope */
    this.level[this.scope].tokens.push(this.lastToken)

    /** if we've reached the token count, go back a level (or to root maybe) */
    if (this.level[this.scope].tokensExpected ===
      this.level[this.scope].tokens.length) {
      // ok this works but is a bit ugly...
      // this.toScope(this.rootScope)
      this.back()
    }
  }

  start (str, sync) {
    var i, scope

    // TODO: temp fix
    str = str + '\n'

    // will remember all _tokens
    this.sync = sync

    this.chars = str

    if (!this.rootScope) {
      throw new Error('Initial Root Scope required')
    }

    /** notify all scopes we've started */
    for (scope in this.level) {
      if (this.level.hasOwnProperty(scope)) {
        this.level[scope].onLineStart()
      }
    }

    for (i = 0; i < this.chars.length; i++) {
      this.next()
    }

    this.emit('end')

    return (sync) ? this._tokens : null
  }

  readChunk (str) {
    this.reset()
    this.start(str.toString())
  }

  /**
   *
   * Checks whether the scope returns with an expected structure.
   *
   */
  checkStructure (scope) {
    if (!this.level.hasOwnProperty(scope)) {
      throw Error(`No such scope: ${scope}`)
    }
    var s = this.level[scope]

    // output to structure
    var tokens = s.tokens.map(function (t) {
      return t.name
    })

    if (tokens.length) {
      // Check if it matches any of the structures.
      if (s.structure.length) {
        var match = false
        for (var str in s.structure) {
          if (compare(tokens, s.structure[str])) {
            match = true
            break
          }
        }
        if (!match) {
          throw new Error([
            'Structure mismatch for',
            scope,
            JSON.stringify(tokens),
            'did not match any of',
            JSON.stringify(s.structure),
            '\n\n\t',
            JSON.stringify(s.tokens)
          ].join(' '))
        }

        this.emit('structure', {
          scope: scope,
          tokens: tokens
        })
      }
    }
  }
}

DysLexer.Scope = Scope

module.exports = DysLexer
<commit_msg>const, let<commit_after>'use strict'

import Scope from './scope'
import compare from './compare'
import EventEmitter from 'events'

/**
 *
 * DysLexer
 *
 * @constructor
 * @param {object} rootScope - The root scope
 */
export default class DysLexer extends EventEmitter {
  constructor (rootScope) {
    super()
    this.chars = ''
    this.current = 0

    // not totally correct, ah well..
    // also do not count \r as character, it has 2 chars
    // for eol.
    // TODO: should override comma as custom,
    // not as default overhere
    this.eol = ['\n', '\r', ',']

    this.scopeChar = undefined

    this.lineNumber = 0

    // default token endings
    // a scope can overwrite this temporarily
    this.tokenEnding = ['\n', '\t', ' ']

    // Tokens
    this.lastToken = undefined

    // token cache
    this.tokens = []

    // will remember all tokens in sync mode.
    this._tokens = []

    // char at which the current token started
    this.tokenStart = 0

    this.token = ''

    // the last character that triggered a scope change.
    this.scoper = undefined

    // char at which the current scope started
    this.scopeStart = 0

    // first level matchers
    this.level = {}

    // only rebuild for logging
    this.line = ''

    this.scope = this.rootScope = rootScope

    // keep track of where we are,
    // with possibility to go back
    // bit wild but works.
    this.track = []
  }

  /**
   *
   * Reset
   *
   */
  reset () {
    this.chars = ''
    this.current = 0

    this.scopeChar = undefined

    // Tokens
    this.lastToken = undefined

    // will only be remembered per line/segment
    this.tokens = []

    // will remember all tokens in sync mode.
    this._tokens = []

    this.token = ''

    // the last character that triggered a scope change.
    this.scoper = undefined

    // line is rebuild for logging
    this.line = ''

    this.lineNumber = 0

    this.scope = this.rootScope

    this.track = []
  }

  /**
   *
   * Add Scope
   *
   * Adds a new scope to the lexer.
   *
   * @param {string} scope
   */
  addScope (Scope) {
    this.level[Scope.name] = new Scope(this)
    return this.level[Scope.name]
  }

  /**
   *
   * Goes back to the scope we entered from.
   *
   * @param {string} c - Current character
   */
  back (c) {
    if (this.track.length) {
      this.toScope(this.track.pop(), c, false)
    } else {
      throw Error('Already at rootScope cannot go back')
    }
  }

  /**
   *
   * Switch to another scope
   *
   * @param {string} scope - Scope to switch to
   * @param {string} c     - Current character
   * @param {string} track - Whether to track this scope switch
   */
  toScope (scope, c, track = true) {
    // Still useful in debug mode
    // console.log('------ ' + scope + '------')
    this.emit('scopeSwitch', {
      from: this.scope,
      to: scope
    })

    if (track) {
      this.track.push(this.scope)
    }

    if (!this.level[scope]) {
      throw Error('Unknown scope: ' + scope)
    }

    // Not used...
    this.level[scope].setParent(
      this.level[this.scope]
    )

    /** check structure of the scope we left */
    this.checkStructure(this.scope)

    /** register the current scope */
    this.scope = scope

    /** inform what char did the scope */
    this.scoper = c

    /** char at which this was scoped */
    this.scopeChar = this.current

    /** reset token list */
    this.level[this.scope].tokens = []

    /** notify new scope we have entered. */
    this.level[this.scope].onEnter()
  }

  /**
   *
   *
   *
   */
  next () {
    /** take the current character */
    const c = this.chars.charAt(this.current)

    /** rebuild the line for debug purposes */
    this.line += c

    // debug
    // console.log(this.scope, ':', c)

    if (this.level[this.scope].rules[c]) {
      // this can cause weird behaviour if the rule itself
      // is redirecting the scope, which happens..
      // it means within this function this.scope is switched...
      this.level[this.scope].rules[c](c)
    } else if (this.level[this.scope].rules['**']) {
      // '**' will run whenever there is not already a match
      this.level[this.scope].rules['**'](c)
    }
    // Ok the above character matching could have switched the scope
    // it's actually the only job the character matching has...
    // but that character matching has a purpose.
    // however because we have switched scopes at _this_ exact point
    // the character will be re-considered by the other scope
    // that's the code following below.

    /** if the scope has set it's own tokenEndings.. */
    if (this.level[this.scope].tokenEnding !== undefined) {
      if (!this.tokenStart) this.tokenStart = this.current
      this.token += c

      if (this.level[this.scope].tokenEnding.indexOf(c) >= 0 &&
          // trick to catch the first ' which is not escaped
          // it's the first
          // Ok, this makes a big difference.
          // if we save the token in the other scope
          // this one will never happen.
          // right hand is set with tokenEnding
          // where left hand is set with the character matchin
          // that's not so good.
          // so switching should be done from within
          // the character matching I think.
          // that will go ok, I hope.
        this.token.length > 1 && !this.isEscaped()) {
        this.fireToken()
      }
    } else if (
      this.tokenEnding.indexOf(c) === -1 &&
      this.eol.indexOf(c) === -1) {
      /** default behaviour, build the token */
      if (!this.tokenStart) this.tokenStart = this.current
      this.token += c
    } else if (
      /** don't act if the scope took control */
    this.level[this.scope].tokenEnding === undefined &&
    this.tokenEnding.indexOf(c) >= 0) {
      this.fireToken()
    }

    // So the same should happen here as onToken, but we got to watch
    // out that we do not have duplicate tokenEnding chars and eol chars.
    if (
      // note, much responsibility for the scope.
    // should take care of it's own ending.
    this.level[this.scope].tokenEnding === undefined &&
    this.eol.indexOf(c) >= 0) {
      // fire last token
      this.fireToken()

      for (const s in this.level) {
        if (this.level.hasOwnProperty(s)) {
          this.level[s].onLineEnd()

          // do not emit lines without tokens. (empty ones)
          if (this.tokens.length) {
            this.emit('lineTokens', this.tokens, this.line, this.lineNumber)

            if (this.sync) {
              // array of tokens per line
              this._tokens.push(this.tokens)
            }

            this.lineNumber++
          }

          this.tokens = []

          this.line = ''

          // reset generic stuff from the scope.
          this.level[s].onLineStart()
        }
      }
    }

    this.current++
  }

  fireToken () {
    if (this.token) {
      if (this.level[this.scope].tokensExpected === undefined) {
        throw new Error('tokensExpected is not set for ' + this.scope)
      }

      /** validate expected token count */
      if (this.level[this.scope].tokensExpected <
        this.level[this.scope].tokens.length) {
        throw new Error([
          'Unexpected token count for',
          this.scope,
          'expected',
          this.level[this.scope].tokensExpected,
          'instead of',
          this.level[this.scope].tokens.length,
          'tokens\n\n\t',
          JSON.stringify(this.level[this.scope].tokens, null, 2),
          '\n'
        ].join(' '))
      }

      /** remember the current scope */
      const realScope = this.scope

      /** switch the current scope to root scope */
      this.scope = this.rootScope

      /**
       * If the scope has set it's own token ending
       * do not run the rootScope 'scanner'
       */
      if (this.level[realScope].tokenEnding !== undefined ||
        /** runs only if the above didn't match, which is important. */ !this.level[this.rootScope].onToken(this.token)) {
        this.scope = realScope
        if (this.scope !== this.rootScope) {
          this.level[this.scope].onToken(this.token)
        }
      }

      /** reset token */
      this.token = ''

      /** reset token start */
      this.tokenStart = undefined
    }
  }

  isEscaped () {
    // leave room to escape the choice.
    if (this.level[this.scope].escape) {
      if (this.chars.charAt(this.current - 1) === '\\') {
        return true
      }
    }

    return false
  }

// TODO: should check whether the token was handled
// or at least make sure that when we fire a token
// it is in sync with what we got presented back.
// This way we can detect unhandled tokens.
  present (name, data) {
    /** validate the token */
    if (this.level[this.scope].validate) {
      let reg = this.level[this.scope].validate[name]
      if (typeof reg === 'string') reg = new RegExp(reg) // ...
      if (reg && !reg.test(data)) {
        throw new Error([
          'Invalid',
          name,
          'token does not match',
          reg.toString(),
          '\n\n\t',
          data,
          '\n'
        ].join(' '))
      }
    }

    /**
     * Note: this relies on the scopes emitting the tokens back.
     * It does not contain each and every token emitted by this matcher.
     */
    this.lastToken = {
      name: name,
      scope: this.scope,
      value: data,
      scopeChar: this.scopeChar,
      start: this.tokenStart,
      end: this.current
    }

    /** remember token */
    this.tokens.push(this.lastToken)

    this.emit('token', this.lastToken)

    /** push token for this scope */
    this.level[this.scope].tokens.push(this.lastToken)

    /** if we've reached the token count, go back a level (or to root maybe) */
    if (this.level[this.scope].tokensExpected ===
      this.level[this.scope].tokens.length) {
      // ok this works but is a bit ugly...
      // this.toScope(this.rootScope)
      this.back()
    }
  }

  start (str, sync) {
    // will remember all _tokens
    this.sync = sync

    this.chars = str + '\n' // TODO: temp fix

    if (!this.rootScope) {
      throw new Error('Initial Root Scope required')
    }

    /** notify all scopes we've started */
    for (const scope in this.level) {
      if (this.level.hasOwnProperty(scope)) {
        this.level[scope].onLineStart()
      }
    }

    for (let i = 0; i < this.chars.length; i++) {
      this.next()
    }

    this.emit('end')

    return (sync) ? this._tokens : null
  }

  readChunk (str) {
    this.reset()
    this.start(str.toString())
  }

  /**
   *
   * Checks whether the scope returns with an expected structure.
   *
   */
  checkStructure (scope) {
    if (!this.level.hasOwnProperty(scope)) {
      throw Error(`No such scope: ${scope}`)
    }
    const s = this.level[scope]

    // output to structure
    const tokens = s.tokens.map(t => t.name)

    if (tokens.length) {
      // Check if it matches any of the structures.
      if (s.structure.length) {
        let match = false
        for (const str in s.structure) {
          if (compare(tokens, s.structure[str])) {
            match = true
            break
          }
        }
        if (!match) {
          throw new Error([
            'Structure mismatch for',
            scope,
            JSON.stringify(tokens),
            'did not match any of',
            JSON.stringify(s.structure),
            '\n\n\t',
            JSON.stringify(s.tokens)
          ].join(' '))
        }

        this.emit('structure', {
          scope: scope,
          tokens: tokens
        })
      }
    }
  }
}

DysLexer.Scope = Scope

module.exports = DysLexer
<|endoftext|>


<commit_before>const electron = require('electron')

// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
var startNodeServer =true
const path = require("path");
const url = require('url');
var fs = require('fs');
var ip = require('ip');
var isWin         = /^win/.test(process.platform);
var sqlite3                     = require('sqlite3');
var os              = require('os')
var username = os.userInfo().username.toLowerCase();

var dbPath = null

var dbsearch = null
var userData = null
//zzz
var port;
var hostaddress;
  var ls = null
hostaddress = ip.address();
port = 80
var f = 0
var started = false

var visifile
app.on('ready', function() {

    userData = app.getPath('userData')
    dbPath = path.join(userData, username + '.visi')

    visifile = new BrowserWindow({
                                width: 800,
                                height: 600,
                                webPreferences: {
                                    nodeIntegration: false

                                },
                                icon:'public/VisiFileColor.png'
                            })

    visifile.loadURL(url.format({
        pathname: path.join(__dirname, 'loading.html'),
        protocol: 'file:',
        slashes: true
      }))

      outputToBrowser("appPath: " + app.getAppPath())
      outputToBrowser("getPath(userData): " + app.getPath('userData'))
      outputToBrowser("dbPath: " + dbPath)
      outputToBrowser("LOCAL: " + path.join(__dirname, '/'))
    //visifile.webContents.toggleDevTools();

    dbsearch = new sqlite3.Database(dbPath);
    dbsearch.serialize(
        function() {
            dbsearch.all(
                "SELECT count(name) as cnt FROM sqlite_master ;  "
                ,

                function(err, results)
                {
                    for (var i = 0; i < results.length; i++) {
                        outputToBrowser("Sqlite: " + results[i].cnt)
                    }

                })
    }, sqlite3.OPEN_READONLY)

	var nodeConsole = require('console');
	var myConsole = new nodeConsole.Console(process.stdout, process.stderr);
	myConsole.log('Hello World!');

    console.log("New electron app")

    //var index = require(path.resolve('src/index.js'))

    if (startNodeServer) {
        var exec = require('child_process').exec;

    	if (isWin) {
    		ls    = exec('cd ' + path.join(__dirname, '..') + ' & pwd & ls & cd visifile & .\\node .\\src\\index.js --nogui true')
    	} else {
    			ls = exec('cd ' + path.join(__dirname, '..') + ' && pwd && ls && cd visifile && ./node src/index.js --nogui true')
    	}

        var readhost = ''
        var readport = ''
    	ls.stdout.on('data', function (data) {
            var ds = data.toString()
            if (!started) {
                outputToBrowser(ds)
            }

            if (ds.indexOf("****HOST") != -1) {
                readhost = ds.substring(ds.indexOf("****HOST") + 9, ds.indexOf("HOST****")).replace(/\'|\"|\n|\r"/g , "")
                //console.log("readhost=" + readhost)
            }

            if (ds.indexOf("****PORT") != -1) {
                   readport = ds.substring(ds.indexOf("****PORT") + 9, ds.indexOf("PORT****")).replace(/\'|\"|\n|\r"/g , "")
                   //console.log("readport=" + readport)
            		var addrt = 'http://' + readhost + ':' + readport;
                    outputToBrowser("****Started address:= " + addrt)
                    setTimeout(function(){
                        if (startNodeServer) {
                            visifile.loadURL(addrt)
                        }

                    },1000)

                    started = true
                }

    	});
    }
})
process.on('exit', function() {
	if (ls) {
		console.log("Killed Process VisiFile")
		ls.kill();
	}
  });

function outputToBrowser(txt) {
    f++

    //var line = txt.toString().replace(/\'|\"|\n|\r"/g , "").toString()
    var line = txt.toString().replace(/\'/g , "").toString()
    var jsc = "document.write('
" + ": " + line + " ')"
    //console.log(line);
    visifile.webContents.executeJavaScript(jsc);
}
<commit_msg>set Windows path<commit_after>const electron = require('electron')

// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
var startNodeServer =true
const path = require("path");
const url = require('url');
var fs = require('fs');
var ip = require('ip');
var isWin         = /^win/.test(process.platform);
var sqlite3                     = require('sqlite3');
var os              = require('os')
var username = os.userInfo().username.toLowerCase();

var dbPath = null

var dbsearch = null
var userData = null
//zzz
var port;
var hostaddress;
  var ls = null
hostaddress = ip.address();
port = 80
var f = 0
var started = false

var visifile
app.on('ready', function() {

	if (isWin) {
		var localappdata  = process.env.LOCALAPPDATA
		userData = path.join(localappdata, '/Visifile/')
	} else {
		userData = app.getPath('userData')
	}
	dbPath = path.join(userData, username + '.visi')

    visifile = new BrowserWindow({
                                width: 800,
                                height: 600,
                                webPreferences: {
                                    nodeIntegration: false

                                },
                                icon:'public/VisiFileColor.png'
                            })

    visifile.loadURL(url.format({
        pathname: path.join(__dirname, 'loading.html'),
        protocol: 'file:',
        slashes: true
      }))

	  outputToBrowser('process.env.LOCALAPPDATA: ' + JSON.stringify(localappdata ,null,2))
      outputToBrowser("appPath: " + app.getAppPath())
	  outputToBrowser("userData: " + JSON.stringify(userData ,null,2))
      outputToBrowser("getPath(userData): " + app.getPath('userData'))
      outputToBrowser("process.env keys: " + Object.keys(process.env))

      outputToBrowser("dbPath: " + JSON.stringify(dbPath ,null,2))
      outputToBrowser("LOCAL: " + path.join(__dirname, '/'))
    //visifile.webContents.toggleDevTools();

    dbsearch = new sqlite3.Database(dbPath);
    dbsearch.serialize(
        function() {
            dbsearch.all(
                "SELECT count(name) as cnt FROM sqlite_master ;  "
                ,

                function(err, results)
                {
                    for (var i = 0; i < results.length; i++) {
                        outputToBrowser("Sqlite: " + results[i].cnt)
                    }

                })
    }, sqlite3.OPEN_READONLY)

	var nodeConsole = require('console');
	var myConsole = new nodeConsole.Console(process.stdout, process.stderr);
	myConsole.log('Hello World!');

    console.log("New electron app")

    //var index = require(path.resolve('src/index.js'))

    if (startNodeServer) {
        var exec = require('child_process').exec;

    	if (isWin) {
    		ls    = exec('cd ' + path.join(__dirname, '..') + ' & pwd & ls & cd visifile & .\\node .\\src\\index.js --nogui true')
    	} else {
    			ls = exec('cd ' + path.join(__dirname, '..') + ' && pwd && ls && cd visifile && ./node src/index.js --nogui true')
    	}

        var readhost = ''
        var readport = ''
    	ls.stdout.on('data', function (data) {
            var ds = data.toString()
            if (!started) {
                outputToBrowser(ds)
            }

            if (ds.indexOf("****HOST") != -1) {
                readhost = ds.substring(ds.indexOf("****HOST") + 9, ds.indexOf("HOST****")).replace(/\'|\"|\n|\r"/g , "")
                //console.log("readhost=" + readhost)
            }

            if (ds.indexOf("****PORT") != -1) {
                   readport = ds.substring(ds.indexOf("****PORT") + 9, ds.indexOf("PORT****")).replace(/\'|\"|\n|\r"/g , "")
                   //console.log("readport=" + readport)
            		var addrt = 'http://' + readhost + ':' + readport;
                    outputToBrowser("****Started address:= " + addrt)
                    setTimeout(function(){
                        if (startNodeServer) {
                            visifile.loadURL(addrt)
                        }

                    },1000)

                    started = true
                }

    	});
    }
})
process.on('exit', function() {
	if (ls) {
		console.log("Killed Process VisiFile")
		ls.kill();
	}
  });

function outputToBrowser(txt) {
    f++

    //var line = txt.toString().replace(/\'|\"|\n|\r"/g , "").toString()
    var line = txt.toString().replace(/\'/g , "").toString()
    var jsc = "document.write('
" + ": " + line + " ')"
    //console.log(line);
    visifile.webContents.executeJavaScript(jsc);
}
<|endoftext|>


<commit_before>const electron = require('electron')

// Module to control application life.
const electronApp = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
var startNodeServer = false
const path = require("path");
const url = require('url');
var fork            = require('child_process');
var fs = require('fs');
var ip = require('ip');
var isWin         = /^win/.test(process.platform);
var isPiModule = require('detect-rpi');

var isRaspberryPi = isPiModule();
console.log('...');

var socket          = require('socket.io');
var fs              = require('fs');
var mkdirp          = require('mkdirp')
var rmdir           = require('rmdir-sync');
var uuidv1          = require('uuid/v1');
var fork            = require('child_process');
var express         = require('express')
var http            = require('http')
var app             = express()
var expressWs       = require('express-ws')(app);
var request         = require("request");
var open            = require('opn');
var db_helper       = require("./db_helper")
var perf            = require('./perf')
//var Excel           = require('exceljs');
var compression     = require('compression')
var crypto          = require('crypto');
var dns             = require('dns');
//var unzip           = require('unzip');
var postgresdb      = require('pg');

var program         = require('commander');
var bodyParser      = require('body-parser');
var multer          = require('multer');
var diff            = require('deep-diff').diff
var XLSX            = require('xlsx');
var csv             = require('fast-csv');
var mysql           = require('mysql');
var cors            = require('cors')
var mammoth         = require("mammoth");
var isBinaryFile    = require("isbinaryfile");
var csvToJson       = require('csvtojson')

var sqlite3                     = require('sqlite3');

var os              = require('os')
var username = os.userInfo().username.toLowerCase();
var upload

var dbPath = null

var dbsearch = null
var userData = null
//zzz
var port;
var hostaddress;
  var ls = null
hostaddress = ip.address();
port = 80
var f = 0
var started = false

var visifile

var io = null;
var forkedProcesses = new Object();
var timeout                             = 0;
var port;
var hostaddress;
var typeOfSystem;
var centralHostAddress;
var centralHostPort;

var stmt2                               = null;
var stmt3                               = null;
var setIn                               = null;
var stopScan                            = false;
var inScan                              = false;
var numberOfSecondsAliveCheck           = 60;
var username                            = "Unknown user";
var serverwebsockets                    = [];
var portrange                           = 3000
var requestClientInternalHostAddress    = '';
var requestClientInternalPort           = -1;
var requestClientPublicIp               = '';
var requestClientPublicHostName         = '';
var locked;
var requestClientPublicIp;
var hostcount  							= 0;
var queuedResponses                     = new Object();
var queuedResponseSeqNum                = 0;

console.log('Starting services');

app.use(compression())

electronApp.on('ready', function() {

	if (isWin) {
		var localappdata  = process.env.LOCALAPPDATA
		userData = path.join(localappdata, '/Visifile/')
	} else {
		userData = electronApp.getPath('userData')
	}
	dbPath = path.join(userData, username + '.visi')

    upload          = multer( { dest: path.join(userData,  'uploads/')});

    visifile = new BrowserWindow({
                                width: 800,
                                height: 600,
                                webPreferences: {
                                    nodeIntegration: false

                                },
                                icon:'public/VisiFileColor.png'
                            })
    visifile.on('closed', function () {

      visifile = null
    })

    visifile.loadURL(url.format({
        pathname: path.join(__dirname, 'loading.html'),
        protocol: 'file:',
        slashes: true
      }))

	  outputToBrowser('process.env.LOCALAPPDATA: ' + JSON.stringify(localappdata ,null,2))
      outputToBrowser("appPath: " + electronApp.getAppPath())
	  outputToBrowser("userData: " + JSON.stringify(userData ,null,2))
      outputToBrowser("getPath(userData): " + electronApp.getPath('userData'))
      outputToBrowser("process.env keys: " + Object.keys(process.env))

      outputToBrowser("dbPath: " + JSON.stringify(dbPath ,null,2))
      outputToBrowser("LOCAL: " + path.join(__dirname, '/'))
    //visifile.webContents.toggleDevTools();

    dbsearch = new sqlite3.Database(dbPath);
    dbsearch.run("PRAGMA journal_mode=WAL;")

    dbsearch.serialize(
        function() {
            dbsearch.all(
                "SELECT count(name) as cnt FROM sqlite_master ;  "
                ,

                function(err, results)
                {
                    for (var i = 0; i < results.length; i++) {
                        outputToBrowser("Sqlite: " + results[i].cnt)
                    }

                })
    }, sqlite3.OPEN_READONLY)

	var nodeConsole = require('console');
	var myConsole = new nodeConsole.Console(process.stdout, process.stderr);
	myConsole.log('Hello World!');

    console.log("New electron app")

    //var index = require(path.resolve('src/index.js'))

    if (startNodeServer) {
        var exec = require('child_process').exec;

    	if (isWin) {
    		ls    = exec('cd ' + path.join(__dirname, '..') + ' & pwd & ls & cd visifile & .\\node .\\src\\index.js --nogui true')
    	} else {
    			ls = exec('cd ' + path.join(__dirname, '..') + ' && pwd && ls && cd visifile && ./node src/index.js --nogui true')
    	}

        var readhost = ''
        var readport = ''
    	ls.stdout.on('data', function (data) {
            var ds = data.toString()
            if (!started) {
                outputToBrowser(ds)
            }

            if (ds.indexOf("****HOST") != -1) {
                readhost = ds.substring(ds.indexOf("****HOST") + 9, ds.indexOf("HOST****")).replace(/\'|\"|\n|\r"/g , "")
                //console.log("readhost=" + readhost)
            }

            if (ds.indexOf("****PORT") != -1) {
                   readport = ds.substring(ds.indexOf("****PORT") + 9, ds.indexOf("PORT****")).replace(/\'|\"|\n|\r"/g , "")
                   //console.log("readport=" + readport)
            		var addrt = 'http://' + readhost + ':' + readport;
                    outputToBrowser("****Started address:= " + addrt)
                    setTimeout(function(){
                        if (startNodeServer) {
                            visifile.loadURL(addrt)
                        }

                    },1000)

                    started = true
                }

    	});
    }

    var forkedProcessPath

	if (isWin) {
		forkedProcessPath = path.join(__dirname, '..\\src\\child.js')
	} else {
		forkedProcessPath = path.join(__dirname, '../src/child.js')
	}
	console.log('forkedProcessPath: ' + forkedProcessPath)
	var forkedProcess = fork.fork(forkedProcessPath, [], {});

    setTimeout(function() {
        forkedProcess.on('message', (msg) => {
            outputToBrowser("Forking processes 2")
            //console.log("Recieved message from child:" + JSON.stringify(msg,null,2))
            outputToBrowser("Recieved message from child:" )
            outputToBrowser("----" + msg.send_from_child)

            if (msg.message_type == "createdTablesInChild") {
                //forkedProcess.send({ message_type: "init" });
                //if (!mainNodeProcessStarted) {
                    //mainNodeProcessStarted = true
                    //getPort()
                //}
                if (forkedProcess){
                    forkedProcess.send({ message_type: "setUpSql" });

                }
                }
            })

            if (forkedProcess){
                forkedProcess.send({ message_type: "init", user_data_path: userData });
                forkedProcess.send({ message_type: "createTables" });

                forkedProcess.send({ message_type: "parent_test" });
            }
    },1500)

    outputToBrowser("Forking processes 1")

})
process.on('exit', function() {
	if (ls) {
		console.log("Killed Process VisiFile")
		ls.kill();
	}
  });

function outputToBrowser(txt) {
    f++

    //var line = txt.toString().replace(/\'|\"|\n|\r"/g , "").toString()
    var line = txt.toString().replace(/\'/g , "").toString()
    var jsc = "document.write('
" + ": " + line + " ')"
    //console.log(line);
    if (visifile) {
        if (visifile.webContents) {
            visifile.webContents.executeJavaScript(jsc);
        }
    }

}
<commit_msg>Added creation of directories<commit_after>const electron = require('electron')

// Module to control application life.
const electronApp = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
var startNodeServer = false
const path = require("path");
const url = require('url');
var fork            = require('child_process');
var fs = require('fs');
var ip = require('ip');
var isWin         = /^win/.test(process.platform);
var isPiModule = require('detect-rpi');

var isRaspberryPi = isPiModule();
console.log('...');

var socket          = require('socket.io');
var fs              = require('fs');
var mkdirp          = require('mkdirp')
var rmdir           = require('rmdir-sync');
var uuidv1          = require('uuid/v1');
var fork            = require('child_process');
var express         = require('express')
var http            = require('http')
var app             = express()
var expressWs       = require('express-ws')(app);
var request         = require("request");
var open            = require('opn');
var db_helper       = require("./db_helper")
var perf            = require('./perf')
//var Excel           = require('exceljs');
var compression     = require('compression')
var crypto          = require('crypto');
var dns             = require('dns');
//var unzip           = require('unzip');
var postgresdb      = require('pg');

var program         = require('commander');
var bodyParser      = require('body-parser');
var multer          = require('multer');
var diff            = require('deep-diff').diff
var XLSX            = require('xlsx');
var csv             = require('fast-csv');
var mysql           = require('mysql');
var cors            = require('cors')
var mammoth         = require("mammoth");
var isBinaryFile    = require("isbinaryfile");
var csvToJson       = require('csvtojson')

var sqlite3                     = require('sqlite3');

var os              = require('os')
var username = os.userInfo().username.toLowerCase();
var upload

var dbPath = null

var dbsearch = null
var userData = null
//zzz
var port;
var hostaddress;
  var ls = null
hostaddress = ip.address();
port = 80
var f = 0
var started = false

var visifile

var io = null;
var forkedProcesses = new Object();
var timeout                             = 0;
var port;
var hostaddress;
var typeOfSystem;
var centralHostAddress;
var centralHostPort;

var stmt2                               = null;
var stmt3                               = null;
var setIn                               = null;
var stopScan                            = false;
var inScan                              = false;
var numberOfSecondsAliveCheck           = 60;
var username                            = "Unknown user";
var serverwebsockets                    = [];
var portrange                           = 3000
var requestClientInternalHostAddress    = '';
var requestClientInternalPort           = -1;
var requestClientPublicIp               = '';
var requestClientPublicHostName         = '';
var locked;
var requestClientPublicIp;
var hostcount  							= 0;
var queuedResponses                     = new Object();
var queuedResponseSeqNum                = 0;

console.log('Starting services');

app.use(compression())

electronApp.on('ready', function() {

	if (isWin) {
		var localappdata  = process.env.LOCALAPPDATA
		userData = path.join(localappdata, '/Visifile/')
	} else {
		userData = electronApp.getPath('userData')
	}
	dbPath = path.join(userData, username + '.visi')

    upload          = multer( { dest: path.join(userData,  'uploads/')});

    rmdir("uploads");
    mkdirp.sync(path.join(userData,  'uploads'));
    mkdirp.sync(path.join(userData,  'files'));

    visifile = new BrowserWindow({
                                width: 800,
                                height: 600,
                                webPreferences: {
                                    nodeIntegration: false

                                },
                                icon:'public/VisiFileColor.png'
                            })
    visifile.on('closed', function () {

      visifile = null
    })

    visifile.loadURL(url.format({
        pathname: path.join(__dirname, 'loading.html'),
        protocol: 'file:',
        slashes: true
      }))

	  outputToBrowser('process.env.LOCALAPPDATA: ' + JSON.stringify(localappdata ,null,2))
      outputToBrowser("appPath: " + electronApp.getAppPath())
	  outputToBrowser("userData: " + JSON.stringify(userData ,null,2))
      outputToBrowser("getPath(userData): " + electronApp.getPath('userData'))
      outputToBrowser("process.env keys: " + Object.keys(process.env))

      outputToBrowser("dbPath: " + JSON.stringify(dbPath ,null,2))
      outputToBrowser("LOCAL: " + path.join(__dirname, '/'))
    //visifile.webContents.toggleDevTools();

    dbsearch = new sqlite3.Database(dbPath);
    dbsearch.run("PRAGMA journal_mode=WAL;")

    dbsearch.serialize(
        function() {
            dbsearch.all(
                "SELECT count(name) as cnt FROM sqlite_master ;  "
                ,

                function(err, results)
                {
                    for (var i = 0; i < results.length; i++) {
                        outputToBrowser("Sqlite: " + results[i].cnt)
                    }

                })
    }, sqlite3.OPEN_READONLY)

	var nodeConsole = require('console');
	var myConsole = new nodeConsole.Console(process.stdout, process.stderr);
	myConsole.log('Hello World!');

    console.log("New electron app")

    //var index = require(path.resolve('src/index.js'))

    if (startNodeServer) {
        var exec = require('child_process').exec;

    	if (isWin) {
    		ls    = exec('cd ' + path.join(__dirname, '..') + ' & pwd & ls & cd visifile & .\\node .\\src\\index.js --nogui true')
    	} else {
    			ls = exec('cd ' + path.join(__dirname, '..') + ' && pwd && ls && cd visifile && ./node src/index.js --nogui true')
    	}

        var readhost = ''
        var readport = ''
    	ls.stdout.on('data', function (data) {
            var ds = data.toString()
            if (!started) {
                outputToBrowser(ds)
            }

            if (ds.indexOf("****HOST") != -1) {
                readhost = ds.substring(ds.indexOf("****HOST") + 9, ds.indexOf("HOST****")).replace(/\'|\"|\n|\r"/g , "")
                //console.log("readhost=" + readhost)
            }

            if (ds.indexOf("****PORT") != -1) {
                   readport = ds.substring(ds.indexOf("****PORT") + 9, ds.indexOf("PORT****")).replace(/\'|\"|\n|\r"/g , "")
                   //console.log("readport=" + readport)
            		var addrt = 'http://' + readhost + ':' + readport;
                    outputToBrowser("****Started address:= " + addrt)
                    setTimeout(function(){
                        if (startNodeServer) {
                            visifile.loadURL(addrt)
                        }

                    },1000)

                    started = true
                }

    	});
    }

    var forkedProcessPath

	if (isWin) {
		forkedProcessPath = path.join(__dirname, '..\\src\\child.js')
	} else {
		forkedProcessPath = path.join(__dirname, '../src/child.js')
	}
	console.log('forkedProcessPath: ' + forkedProcessPath)
	var forkedProcess = fork.fork(forkedProcessPath, [], {});

    setTimeout(function() {
        forkedProcess.on('message', (msg) => {
            outputToBrowser("Forking processes 2")
            //console.log("Recieved message from child:" + JSON.stringify(msg,null,2))
            outputToBrowser("Recieved message from child:" )
            outputToBrowser("----" + msg.send_from_child)

            if (msg.message_type == "createdTablesInChild") {
                //forkedProcess.send({ message_type: "init" });
                //if (!mainNodeProcessStarted) {
                    //mainNodeProcessStarted = true
                    //getPort()
                //}
                if (forkedProcess){
                    forkedProcess.send({ message_type: "setUpSql" });

                }
                }
            })

            if (forkedProcess){
                forkedProcess.send({ message_type: "init", user_data_path: userData });
                forkedProcess.send({ message_type: "createTables" });

                forkedProcess.send({ message_type: "parent_test" });
            }
    },1500)

    outputToBrowser("Forking processes 1")

})
process.on('exit', function() {
	if (ls) {
		console.log("Killed Process VisiFile")
		ls.kill();
	}
  });

function outputToBrowser(txt) {
    f++

    //var line = txt.toString().replace(/\'|\"|\n|\r"/g , "").toString()
    var line = txt.toString().replace(/\'/g , "").toString()
    var jsc = "document.write('
" + ": " + line + " ')"
    //console.log(line);
    if (visifile) {
        if (visifile.webContents) {
            visifile.webContents.executeJavaScript(jsc);
        }
    }

}
<|endoftext|>


<commit_before>'use strict'

const leftPad = require('left-pad')
const request = require('request')
const xor = require('bitwise-xor')

var Web3 = require('web3')
var web3 = new Web3()

const { sha3 } = require('./hash.js')

const FUNDRAISER_CONTRACT = '0xa4028F2aec0ad18964e368338E5268FebB4F5423'
const GAS_LIMIT = 150000
const MIN_DONATION = 1

// returns 0x prefixed hex address
function getAddress (pub) {
  if (pub == null || pub.length !== 64) {
    throw Error('Invalid public key')
  }

  return '0x' + sha3(pub).slice(-20).toString('hex')
}

// ------------------------
// load the contract abi
// we only care about one function
var abi = [{
  constant: false,
  inputs: [
    {
      name: '_donor',
      type: 'address'
    },
    {
      name: '_returnAddress',
      type: 'address'
    },
    {
      name: 'checksum',
      type: 'bytes4'
    }
  ],
  name: 'donate',
  outputs: [],
  payable: true,
  type: 'function'
}]

let MyContract = web3.eth.contract(abi)
var contractInstance = MyContract.at('0x00')

// compute checksum for the transaction
function addressChecksum (cosmosAddr, ethAddr) {
  let addrlen = 20 * 2 + 2 // 0x prefixed hex
  if (cosmosAddr == null || cosmosAddr.length !== addrlen) {
    throw Error('Invalid cosmosAddr ' + cosmosAddr)
  }
  if (ethAddr == null || ethAddr.length !== addrlen) {
    throw Error('Invalid ethAddr ' + ethAddr)
  }

  // checksum is first 4 bytes of sha3(xor(cosmosAddr, ethAddr)
  var paddedCosmos = leftPad(web3.toAscii(cosmosAddr), 32, '\x00')
  var paddedEth = leftPad(web3.toAscii(ethAddr), 32, '\x00')
  var xord = xor(
    Buffer(paddedCosmos, 'ascii'),
    Buffer(paddedEth, 'ascii')
  )
  var checksum32 = web3.sha3(xord.toString('hex'), {encoding: 'hex'})
  var checksum4 = checksum32.slice(0, 10) // 0x and 4 bytes
  return checksum4
}

// data to send in transaction to fundraiser contract
function getTransactionData (cosmosAddr, ethAddr) {
  var checksum = addressChecksum(cosmosAddr, ethAddr)

  // Cut the right-padded zeros from the transaction data
  // Length: One 0x, 4 byte method id, 32 bytes for each address, 4 byte checksum, times 2 for hex encoded
  let dataLength = (1 + 4 + 32 + 32 + 4) * 2
  return contractInstance.donate.getData(cosmosAddr, ethAddr, checksum).slice(0, dataLength)
}

function getTransaction (cosmosAddr, ethAddr) {
  return {
    to: FUNDRAISER_CONTRACT,
    gas: GAS_LIMIT,
    data: getTransactionData(cosmosAddr, ethAddr)
  }
}

function esiRequest (url, qs, cb) {
  return request({
    url: `https://api.etherscan.io/${url}`,
    qs,
    json: true
  }, (err, res, body) => {
    if (err || res.statusCode !== 200 || body.error) {
      return cb(err || body.error || Error(res.statusCode), body)
    }
    cb(null, body)
  })
}

function ethCall (address, method, cb) {
  let data = web3.sha3(`${method}()`).slice(0, 10)
  esiRequest('api?module=proxy&action=eth_call', {
    to: address,
    data,
    tag: 'latest'
  }, (err, res) => {
    if (err) return cb(err)
    cb(null, res.result)
  })
}

// fetch the current atomRate
function fetchAtomRate (address, cb) {
  let txData = web3.sha3('atomRate()').slice(0, 10) // '0xf5c96216'
  esiRequest('api?module=proxy&action=eth_call', {
    to: address,
    data: txData,
    tag: 'latest'
  }, (err, res) => {
    if (err) return cb(err)
    cb(null, parseInt(res.result, 16))
  })
}

// fetch the total raised and total atoms
function fetchTotals (address, cb) {
  let divisor = 1e18
  ethCall(address, 'totalAtom', (err, res) => {
    if (err) return cb(err)
    let atoms = parseInt(res, 16) / divisor
    ethCall(address, 'totalEther', (err, res) => {
      if (err) return cb(err)
      let ether = parseInt(res, 16) / divisor
      cb(null, { ether, atoms })
    })
  })
}

// TODO: limit so it doesn't fetch all txs
function fetchTxs (address, cb) {
  esiRequest('api?module=account&action=txlist', {
    address,
    startblock: 0,
    endblock: 99999999,
    sort: 'desc'
  }, (err, res) => {
    if (err) return cb(err)
    cb(null, res.result)
  })
}

module.exports = {
  getAddress,
  getTransaction,
  getTransactionData,
  addressChecksum,
  fetchAtomRate,
  fetchTotals,
  fetchTxs,
  FUNDRAISER_CONTRACT,
  MIN_DONATION
}
<commit_msg>fix calling contract getters<commit_after>'use strict'

const leftPad = require('left-pad')
const request = require('request')
const xor = require('bitwise-xor')

var Web3 = require('web3')
var web3 = new Web3()

const { sha3 } = require('./hash.js')

const FUNDRAISER_CONTRACT = '0xa4028F2aec0ad18964e368338E5268FebB4F5423'
const GAS_LIMIT = 150000
const MIN_DONATION = 1

// returns 0x prefixed hex address
function getAddress (pub) {
  if (pub == null || pub.length !== 64) {
    throw Error('Invalid public key')
  }

  return '0x' + sha3(pub).slice(-20).toString('hex')
}

// ------------------------
// load the contract abi
// we only care about one function
var abi = [{
  constant: false,
  inputs: [
    {
      name: '_donor',
      type: 'address'
    },
    {
      name: '_returnAddress',
      type: 'address'
    },
    {
      name: 'checksum',
      type: 'bytes4'
    }
  ],
  name: 'donate',
  outputs: [],
  payable: true,
  type: 'function'
}]

let MyContract = web3.eth.contract(abi)
var contractInstance = MyContract.at('0x00')

// compute checksum for the transaction
function addressChecksum (cosmosAddr, ethAddr) {
  let addrlen = 20 * 2 + 2 // 0x prefixed hex
  if (cosmosAddr == null || cosmosAddr.length !== addrlen) {
    throw Error('Invalid cosmosAddr ' + cosmosAddr)
  }
  if (ethAddr == null || ethAddr.length !== addrlen) {
    throw Error('Invalid ethAddr ' + ethAddr)
  }

  // checksum is first 4 bytes of sha3(xor(cosmosAddr, ethAddr)
  var paddedCosmos = leftPad(web3.toAscii(cosmosAddr), 32, '\x00')
  var paddedEth = leftPad(web3.toAscii(ethAddr), 32, '\x00')
  var xord = xor(
    Buffer(paddedCosmos, 'ascii'),
    Buffer(paddedEth, 'ascii')
  )
  var checksum32 = web3.sha3(xord.toString('hex'), {encoding: 'hex'})
  var checksum4 = checksum32.slice(0, 10) // 0x and 4 bytes
  return checksum4
}

// data to send in transaction to fundraiser contract
function getTransactionData (cosmosAddr, ethAddr) {
  var checksum = addressChecksum(cosmosAddr, ethAddr)

  // Cut the right-padded zeros from the transaction data
  // Length: One 0x, 4 byte method id, 32 bytes for each address, 4 byte checksum, times 2 for hex encoded
  let dataLength = (1 + 4 + 32 + 32 + 4) * 2
  return contractInstance.donate.getData(cosmosAddr, ethAddr, checksum).slice(0, dataLength)
}

function getTransaction (cosmosAddr, ethAddr) {
  return {
    to: FUNDRAISER_CONTRACT,
    gas: GAS_LIMIT,
    data: getTransactionData(cosmosAddr, ethAddr)
  }
}

function esiRequest (url, qs, cb) {
  return request({
    url: `https://api.etherscan.io/${url}`,
    qs,
    json: true
  }, (err, res, body) => {
    if (err || res.statusCode !== 200 || body.error) {
      return cb(err || body.error || Error(res.statusCode), body)
    }
    cb(null, body)
  })
}

function ethCall (address, method, cb) {
  let data = web3.sha3(`${method}()`).slice(0, 10)
  esiRequest('api?module=proxy&action=eth_call', {
    to: address,
    data,
    tag: 'latest'
  }, (err, res) => {
    if (err) return cb(err)
    cb(null, res.result)
  })
}

// fetch the current atomRate
function fetchAtomRate (address, cb) {
  ethCall(address, 'weiPerAtom', (err, res) => {
    if (err) return cb(err)
    cb(null, parseInt(res, 16))
  })
}

// fetch the total raised and total atoms
function fetchTotals (address, cb) {
  let divisor = 1e18
  ethCall(address, 'totalAtom', (err, res) => {
    if (err) return cb(err)
    let atoms = parseInt(res, 16) / divisor
    ethCall(address, 'totalWei', (err, res) => {
      if (err) return cb(err)
      let ether = parseInt(res, 16) / divisor
      cb(null, { ether, atoms })
    })
  })
}

// TODO: limit so it doesn't fetch all txs
function fetchTxs (address, cb) {
  esiRequest('api?module=account&action=txlist', {
    address,
    startblock: 0,
    endblock: 99999999,
    sort: 'desc'
  }, (err, res) => {
    if (err) return cb(err)
    cb(null, res.result)
  })
}

module.exports = {
  getAddress,
  getTransaction,
  getTransactionData,
  addressChecksum,
  fetchAtomRate,
  fetchTotals,
  fetchTxs,
  FUNDRAISER_CONTRACT,
  MIN_DONATION
}
<|endoftext|>


<commit_before>enyo.depends(
	"$lib/layout",
	"$lib/onyx",	// To theme Onyx using Theme.less, change this line to $lib/onyx/source,
	//"Theme.less",	// uncomment this line, and follow the steps described in Theme.less
	"$lib/more-arrangers",
	"$lib/webos-lib",
	// CSS/LESS style files
	"style",
	// Model and data definitions
	"data",
	// View kind definitions
	"views",
	// Include our default entry point
	"app.js"
);
<commit_msg>Name correct file for deployment process<commit_after>enyo.depends(
	"$lib/layout",
	"$lib/onyx",	// To theme Onyx using Theme.less, change this line to $lib/onyx/source,
	//"Theme.less",	// uncomment this line, and follow the steps described in Theme.less
	"$lib/more-arrangers",
	"$lib/webos-lib",
	// CSS/LESS style files
	"style",
	// Model and data definitions
	"data",
	// View kind definitions
	"views",
	// Include our default entry point
	"App.js"
);
<|endoftext|>


<commit_before>'use strict';
var fs = require('fs')

var config = require('../../config')

/**
 * Home Page
 * @param {object} req
 * @param {object} res
 */
exports.index = function(req,res){
  var contentRaw = fs.readFileSync(config.ckpool.logFile)
  var contentParts = contentRaw.split('^[[2K^M')
  var content = contentParts.slice(contentParts.length,-20).join('\n')
  res.render('index',{
    logContent: content
  })
}
<commit_msg>new approach to parsing this stupid log file rev 2<commit_after>var fs = require('fs')

var config = require('../../config')

/**
 * Home Page
 * @param {object} req
 * @param {object} res
 */
exports.index = function(req,res){
  var contentRaw = fs.readFileSync(config.ckpool.logFile).toString()
  var contentParts = contentRaw.split('\033[2K')
  var content = contentParts.slice(contentParts.length - 20,contentParts.length).join('\n')
  res.render('index',{
    logContent: content
  })
}<|endoftext|>


<commit_before>/* jshint -W097 */
"use strict";

var data = {};

/**
 * Dummy definition for IDE support. These objects are
 * generally read from the web socket connection.
 * @constructor
 */
function SourceSection() {
  this.firstIndex = 0;
  this.sourceText = "";
  this.shortName  = "";
}

/**
 * Dummy definition for IDE support. These objects are
 * generally read from the web socket connection.
 * @constructor
 */
function InvocationProfile() {
  this.invocations = 0;
  this.somTypes = [];
}

/**
 * Dummy definition for IDE support. These objects are
 * generally read from the web socket connection.
 * @constructor
 */
function CountingProfile() {
  this.count = 0;
}

function Actor(id, name, typeName) {
  this.id       = id;
  this.name     = name;
  this.typeName = typeName;
}

function MessageHistory(messages, actors) {
  this.messages = messages; // per actor
  this.actors   = actors;
}

function Message(id, sender, receiver) {
  this.id       = id;
  this.sender   = sender;
  this.receiver = receiver;
}

function countNumberOfLines(str) {
  var cnt = 1;
  for (var i = 0; i < str.length; i++) {
    if (str[i] == "\n") {
      cnt += 1;
    }
  }
  return cnt;
}

function loadAndProcessFile(f) {
  var reader = new FileReader();
  reader.onload = (function(theFile) {

    function receivedFile(e) {
      var o = JSON.parse(e.target.result);
      data[theFile.name] = o;
      displaySources(o);
    }

    return receivedFile;
  })(f);

  reader.readAsText(f);
}

/**
 * @param {DragEvent} e
 */
function handleFileSelect(e) {
  e.stopPropagation();
  e.preventDefault();

  var files = e.dataTransfer.files; // FileList object.

  // files is a FileList of File objects. List some properties.
  var output = [];
  for (var i = 0; i < files.length; i++) {
    loadAndProcessFile(files[i]);
  }
}

var accessProfiles = [],
  maxAccessCount = -1;

function Breakpoint(source, line, lineNumSpan) {
  this.source      = source;
  this.line        = line;
  this.enabled     = false;
  this.lineNumSpan = lineNumSpan;
  this.checkbox    = null;
}

Breakpoint.prototype.toggle = function () {
  this.enabled = !this.enabled;
};

Breakpoint.prototype.isEnabled = function () {
  return this.enabled;
};

function handleDragOver(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}

function dbgLog(msg) {
  var tzOffset = (new Date()).getTimezoneOffset() * 60000; // offset in milliseconds
  var localISOTime = (new Date(Date.now() - tzOffset)).toISOString().slice(0,-1);

  $("#debugger-log").html(localISOTime + ": " + msg + "
" + $("#debugger-log").html());
}

function Debugger() {
  this.suspended = false;
  this.lastSuspendEventId = null;
  this.sourceObjects = {};
  this.breakpoints = {};
}

Debugger.prototype.getSource = function (id) {
  for (var fileName in this.sourceObjects) {
    if (this.sourceObjects[fileName].id === id) {
      return this.sourceObjects[fileName];
    }
  }
  return null;
};

Debugger.prototype.addSources = function (msg) {
  for (var sId in msg.sources) {
    this.sourceObjects[msg.sources[sId].name] = msg.sources[sId];
  }
};

Debugger.prototype.getBreakpoint = function (source, line, clickedSpan) {
  if (!this.breakpoints[source]) {
    this.breakpoints[source] = {};
  }

  var bp = this.breakpoints[source][line];
  if (!bp) {
    bp = new Breakpoint(source, line, clickedSpan);
    this.breakpoints[source][line] = bp;
  }
  return bp;
};

Debugger.prototype.setSuspended = function(eventId) {
  console.assert(!this.suspended);
  this.suspended = true;
  this.lastSuspendEventId = eventId;
};

Debugger.prototype.setResumed = function () {
  console.assert(this.suspended);
  this.suspended = false;
};

/* globals View, Controller, VmConnection */
var ctrl;

function init() {
  var view = new View(),
    vmConnection = new VmConnection(),
    dbg = new Debugger();
  ctrl = new Controller(dbg, view, vmConnection);
  ctrl.toggleConnection();

  // Init drag and drop
  var fileDrop = document.getElementById('file-drop');
  fileDrop.addEventListener('dragover', handleDragOver,   false);
  fileDrop.addEventListener('drop',     handleFileSelect, false);
}

function blobToFile(blob, name) {
  blob.lastModifiedDate = new Date();
  blob.name = name;
  return blob;
}

function getFileObjectFromPath(pathOrUrl, callback) {
  var request = new XMLHttpRequest();
  request.open("GET", pathOrUrl);
  request.responseType = "blob";
  request.addEventListener('load', function () {
    callback(blobToFile(request.response, pathOrUrl));
  });
  request.send();
}

function loadStandardFile() {
  getFileObjectFromPath("highlight.json",
    function(file) {
      loadAndProcessFile(file);
    });
}
<commit_msg>Need a proper ES6 Map to represent breakpoints indexed by source objects<commit_after>/* jshint -W097 */
"use strict";

var data = {};

/**
 * Dummy definition for IDE support. These objects are
 * generally read from the web socket connection.
 * @constructor
 */
function SourceSection() {
  this.firstIndex = 0;
  this.sourceText = "";
  this.shortName  = "";
}

/**
 * Dummy definition for IDE support. These objects are
 * generally read from the web socket connection.
 * @constructor
 */
function InvocationProfile() {
  this.invocations = 0;
  this.somTypes = [];
}

/**
 * Dummy definition for IDE support. These objects are
 * generally read from the web socket connection.
 * @constructor
 */
function CountingProfile() {
  this.count = 0;
}

function Actor(id, name, typeName) {
  this.id       = id;
  this.name     = name;
  this.typeName = typeName;
}

function MessageHistory(messages, actors) {
  this.messages = messages; // per actor
  this.actors   = actors;
}

function Message(id, sender, receiver) {
  this.id       = id;
  this.sender   = sender;
  this.receiver = receiver;
}

function countNumberOfLines(str) {
  var cnt = 1;
  for (var i = 0; i < str.length; i++) {
    if (str[i] == "\n") {
      cnt += 1;
    }
  }
  return cnt;
}

function loadAndProcessFile(f) {
  var reader = new FileReader();
  reader.onload = (function(theFile) {

    function receivedFile(e) {
      var o = JSON.parse(e.target.result);
      data[theFile.name] = o;
      displaySources(o);
    }

    return receivedFile;
  })(f);

  reader.readAsText(f);
}

/**
 * @param {DragEvent} e
 */
function handleFileSelect(e) {
  e.stopPropagation();
  e.preventDefault();

  var files = e.dataTransfer.files; // FileList object.

  // files is a FileList of File objects. List some properties.
  var output = [];
  for (var i = 0; i < files.length; i++) {
    loadAndProcessFile(files[i]);
  }
}

var accessProfiles = [],
  maxAccessCount = -1;

function Breakpoint(source, line, lineNumSpan) {
  this.source      = source;
  this.line        = line;
  this.enabled     = false;
  this.lineNumSpan = lineNumSpan;
  this.checkbox    = null;
}

Breakpoint.prototype.toggle = function () {
  this.enabled = !this.enabled;
};

Breakpoint.prototype.isEnabled = function () {
  return this.enabled;
};

function handleDragOver(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}

function dbgLog(msg) {
  var tzOffset = (new Date()).getTimezoneOffset() * 60000; // offset in milliseconds
  var localISOTime = (new Date(Date.now() - tzOffset)).toISOString().slice(0,-1);

  $("#debugger-log").html(localISOTime + ": " + msg + "
" + $("#debugger-log").html());
}

function Debugger() {
  this.suspended = false;
  this.lastSuspendEventId = null;
  this.sourceObjects = {};
  this.breakpoints = new Map();
}

Debugger.prototype.getSource = function (id) {
  for (var fileName in this.sourceObjects) {
    if (this.sourceObjects[fileName].id === id) {
      return this.sourceObjects[fileName];
    }
  }
  return null;
};

Debugger.prototype.addSources = function (msg) {
  for (var sId in msg.sources) {
    this.sourceObjects[msg.sources[sId].name] = msg.sources[sId];
  }
};

Debugger.prototype.getBreakpoint = function (source, line, clickedSpan) {
  if (!this.breakpoints.has(source)) {
    this.breakpoints.set(source, {});
  }

  var bp = this.breakpoints.get(source)[line];
  if (!bp) {
    bp = new Breakpoint(source, line, clickedSpan);
    this.breakpoints.get(source)[line] = bp;
  }
  return bp;
};

Debugger.prototype.setSuspended = function(eventId) {
  console.assert(!this.suspended);
  this.suspended = true;
  this.lastSuspendEventId = eventId;
};

Debugger.prototype.setResumed = function () {
  console.assert(this.suspended);
  this.suspended = false;
};

/* globals View, Controller, VmConnection */
var ctrl;

function init() {
  var view = new View(),
    vmConnection = new VmConnection(),
    dbg = new Debugger();
  ctrl = new Controller(dbg, view, vmConnection);
  ctrl.toggleConnection();

  // Init drag and drop
  var fileDrop = document.getElementById('file-drop');
  fileDrop.addEventListener('dragover', handleDragOver,   false);
  fileDrop.addEventListener('drop',     handleFileSelect, false);
}

function blobToFile(blob, name) {
  blob.lastModifiedDate = new Date();
  blob.name = name;
  return blob;
}

function getFileObjectFromPath(pathOrUrl, callback) {
  var request = new XMLHttpRequest();
  request.open("GET", pathOrUrl);
  request.responseType = "blob";
  request.addEventListener('load', function () {
    callback(blobToFile(request.response, pathOrUrl));
  });
  request.send();
}

function loadStandardFile() {
  getFileObjectFromPath("highlight.json",
    function(file) {
      loadAndProcessFile(file);
    });
}
<|endoftext|>


<commit_before>/** @license
sprintf() for JavaScript 0.7-beta1
http://www.diveintojavascript.com/projects/javascript-sprintf

Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
	* Redistributions of source code must retain the above copyright
	  notice, this list of conditions and the following disclaimer.
	* Redistributions in binary form must reproduce the above copyright
	  notice, this list of conditions and the following disclaimer in the
	  documentation and/or other materials provided with the distribution.
	* Neither the name of sprintf() for JavaScript nor the
	  names of its contributors may be used to endorse or promote products
	  derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Changelog:
2010.09.06 - 0.7-beta1
  - features: vsprintf, support for named placeholders
  - enhancements: format cache, reduced global namespace pollution

2010.05.22 - 0.6:
 - reverted to 0.4 and fixed the bug regarding the sign of the number 0
 Note:
 Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
 who warned me about a bug in 0.5, I discovered that the last update was
 a regress. I appologize for that.

2010.05.09 - 0.5:
 - bug fix: 0 is now preceeded with a + sign
 - bug fix: the sign was not at the right position on padded results (Kamal Abdali)
 - switched from GPL to BSD license

2007.10.21 - 0.4:
 - unit test and patch (David Baird)

2007.09.17 - 0.3:
 - bug fix: no longer throws exception on empty paramenters (Hans Pufal)

2007.09.11 - 0.2:
 - feature: added argument swapping

2007.04.03 - 0.1:
 - initial release
**/

var sprintf = (function() {
	function get_type(variable) {
		return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
	}
	function str_repeat(input, multiplier) {
		for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
		return output.join('');
	}

	var str_format = function() {
		if (!str_format.cache.hasOwnProperty(arguments[0])) {
			str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
		}
		return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
	};

	str_format.format = function(parse_tree, argv) {
		var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
		for (i = 0; i < tree_length; i++) {
			node_type = get_type(parse_tree[i]);
			if (node_type === 'string') {
				output.push(parse_tree[i]);
			}
			else if (node_type === 'array') {
				match = parse_tree[i]; // convenience purposes only
				if (match[2]) { // keyword argument
					arg = argv[cursor];
					for (k = 0; k < match[2].length; k++) {
						if (!arg.hasOwnProperty(match[2][k])) {
							throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
						}
						arg = arg[match[2][k]];
					}
				}
				else if (match[1]) { // positional argument (explicit)
					arg = argv[match[1]];
				}
				else { // positional argument (implicit)
					arg = argv[cursor++];
				}

				if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
					throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
				}
				switch (match[8]) {
					case 'b': arg = arg.toString(2); break;
					case 'c': arg = String.fromCharCode(arg); break;
					case 'd': arg = parseInt(arg, 10); break;
					case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
					case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
					case 'o': arg = arg.toString(8); break;
					case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
					case 'u': arg = Math.abs(arg); break;
					case 'x': arg = arg.toString(16); break;
					case 'X': arg = arg.toString(16).toUpperCase(); break;
				}
				arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
				pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
				pad_length = match[6] - String(arg).length;
				pad = match[6] ? str_repeat(pad_character, pad_length) : '';
				output.push(match[5] ? arg + pad : pad + arg);
			}
		}
		return output.join('');
	};

	str_format.cache = {};

	str_format.parse = function(fmt) {
		var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
		while (_fmt) {
			if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
				parse_tree.push(match[0]);
			}
			else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
				parse_tree.push('%');
			}
			else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
				if (match[2]) {
					arg_names |= 1;
					var field_list = [], replacement_field = match[2], field_match = [];
					if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
						field_list.push(field_match[1]);
						while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
							if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
								field_list.push(field_match[1]);
							}
							else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
								field_list.push(field_match[1]);
							}
							else {
								throw('[sprintf] huh?');
							}
						}
					}
					else {
						throw('[sprintf] huh?');
					}
					match[2] = field_list;
				}
				else {
					arg_names |= 2;
				}
				if (arg_names === 3) {
					throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
				}
				parse_tree.push(match);
			}
			else {
				throw('[sprintf] huh?');
			}
			_fmt = _fmt.substring(match[0].length);
		}
		return parse_tree;
	};

	return str_format;
})();

var vsprintf = function(fmt, argv) {
	argv.unshift(fmt);
	return sprintf.apply(null, argv);
};
<commit_msg>sprintf: move changelog to separate comment to keep closure compiler from keeping it.<commit_after>/** @license
sprintf() for JavaScript 0.7-beta1
http://www.diveintojavascript.com/projects/javascript-sprintf

Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
	* Redistributions of source code must retain the above copyright
	  notice, this list of conditions and the following disclaimer.
	* Redistributions in binary form must reproduce the above copyright
	  notice, this list of conditions and the following disclaimer in the
	  documentation and/or other materials provided with the distribution.
	* Neither the name of sprintf() for JavaScript nor the
	  names of its contributors may be used to endorse or promote products
	  derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/

/*
Changelog:
2010.09.06 - 0.7-beta1
  - features: vsprintf, support for named placeholders
  - enhancements: format cache, reduced global namespace pollution

2010.05.22 - 0.6:
 - reverted to 0.4 and fixed the bug regarding the sign of the number 0
 Note:
 Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
 who warned me about a bug in 0.5, I discovered that the last update was
 a regress. I appologize for that.

2010.05.09 - 0.5:
 - bug fix: 0 is now preceeded with a + sign
 - bug fix: the sign was not at the right position on padded results (Kamal Abdali)
 - switched from GPL to BSD license

2007.10.21 - 0.4:
 - unit test and patch (David Baird)

2007.09.17 - 0.3:
 - bug fix: no longer throws exception on empty paramenters (Hans Pufal)

2007.09.11 - 0.2:
 - feature: added argument swapping

2007.04.03 - 0.1:
 - initial release
*/

var sprintf = (function() {
	function get_type(variable) {
		return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
	}
	function str_repeat(input, multiplier) {
		for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
		return output.join('');
	}

	var str_format = function() {
		if (!str_format.cache.hasOwnProperty(arguments[0])) {
			str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
		}
		return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
	};

	str_format.format = function(parse_tree, argv) {
		var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
		for (i = 0; i < tree_length; i++) {
			node_type = get_type(parse_tree[i]);
			if (node_type === 'string') {
				output.push(parse_tree[i]);
			}
			else if (node_type === 'array') {
				match = parse_tree[i]; // convenience purposes only
				if (match[2]) { // keyword argument
					arg = argv[cursor];
					for (k = 0; k < match[2].length; k++) {
						if (!arg.hasOwnProperty(match[2][k])) {
							throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
						}
						arg = arg[match[2][k]];
					}
				}
				else if (match[1]) { // positional argument (explicit)
					arg = argv[match[1]];
				}
				else { // positional argument (implicit)
					arg = argv[cursor++];
				}

				if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
					throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
				}
				switch (match[8]) {
					case 'b': arg = arg.toString(2); break;
					case 'c': arg = String.fromCharCode(arg); break;
					case 'd': arg = parseInt(arg, 10); break;
					case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
					case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
					case 'o': arg = arg.toString(8); break;
					case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
					case 'u': arg = Math.abs(arg); break;
					case 'x': arg = arg.toString(16); break;
					case 'X': arg = arg.toString(16).toUpperCase(); break;
				}
				arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
				pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
				pad_length = match[6] - String(arg).length;
				pad = match[6] ? str_repeat(pad_character, pad_length) : '';
				output.push(match[5] ? arg + pad : pad + arg);
			}
		}
		return output.join('');
	};

	str_format.cache = {};

	str_format.parse = function(fmt) {
		var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
		while (_fmt) {
			if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
				parse_tree.push(match[0]);
			}
			else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
				parse_tree.push('%');
			}
			else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
				if (match[2]) {
					arg_names |= 1;
					var field_list = [], replacement_field = match[2], field_match = [];
					if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
						field_list.push(field_match[1]);
						while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
							if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
								field_list.push(field_match[1]);
							}
							else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
								field_list.push(field_match[1]);
							}
							else {
								throw('[sprintf] huh?');
							}
						}
					}
					else {
						throw('[sprintf] huh?');
					}
					match[2] = field_list;
				}
				else {
					arg_names |= 2;
				}
				if (arg_names === 3) {
					throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
				}
				parse_tree.push(match);
			}
			else {
				throw('[sprintf] huh?');
			}
			_fmt = _fmt.substring(match[0].length);
		}
		return parse_tree;
	};

	return str_format;
})();

var vsprintf = function(fmt, argv) {
	argv.unshift(fmt);
	return sprintf.apply(null, argv);
};
<|endoftext|>