<commit_before>(function(undefined) {
  // The Opal object that is exposed globally
  var Opal = this.Opal = {};

  // Very root class
  function BasicObject(){}

  // Core Object class
  function Object(){}

  // Class' class
  function Class(){}

  // the class of nil
  function NilClass(){}

  // TopScope is used for inheriting constants from the top scope
  var TopScope = function(){};

  // Opal just acts as the top scope
  TopScope.prototype = Opal;

  // To inherit scopes
  Opal.alloc  = TopScope;

  // This is a useful reference to global object inside ruby files
  Opal.global = this;

  // Minify common function calls
  var __hasOwn = Opal.hasOwnProperty;
  var __slice  = Opal.slice = Array.prototype.slice;

  // Generates unique id for every ruby object
  var unique_id = 0;

  // Return next unique id
  Opal.uid = function() {
    return unique_id++;
  };

  // Table holds all class variables
  Opal.cvars = {};

  // Globals table
  Opal.gvars = {};

  Opal.klass = function(base, superklass, id, constructor) {
    var klass;
    if (base._isObject) {
      base = base._klass;
    }

    if (superklass === null) {
      superklass = Object;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      if (!superklass._methods) {
        var bridged = superklass;
        superklass  = Object;
        klass       = bridge_class(bridged);
      }
      else {
        klass = boot_class(superklass, constructor);
      }

      klass._name = (base === Object ? id : base._name + '::' + id);

      var const_alloc   = function() {};
      var const_scope   = const_alloc.prototype = new base._scope.alloc();
      klass._scope      = const_scope;
      const_scope.base  = klass;
      const_scope.alloc = const_alloc;

      base[id] = base._scope[id] = klass;

      if (superklass.$inherited) {
        superklass.$inherited(klass);
      }
    }

    return klass;
  };

  // Define new module (or return existing module)
  Opal.module = function(base, id, constructor) {
    var klass;
    if (base._isObject) {
      base = base._klass;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      klass = boot_class(Class, constructor);
      klass._name = (base === Object ? id : base._name + '::' + id);

      klass.$included_in = [];

      var const_alloc   = function() {};
      var const_scope   = const_alloc.prototype = new base._scope.alloc();
      klass._scope      = const_scope;
      const_scope.alloc = const_alloc;

      base[id] = base._scope[id]    = klass;
    }

    return klass;
  }

  // Utility function to raise a "no block given" error
  var no_block_given = function() {
    throw new Error('no block given');
  };

  // Boot a base class (makes instances).
  var boot_defclass = function(id, constructor, superklass) {
    if (superklass) {
      var ctor           = function() {};
          ctor.prototype = superklass.prototype;

      constructor.prototype = new ctor();
    }

    var prototype = constructor.prototype;

    prototype.constructor = constructor;
    prototype._isObject   = true;
    prototype._klass      = constructor;

    constructor._inherited    = [];
    constructor._included_in  = [];
    constructor._isClass      = true;
    constructor._name         = id;
    constructor._super        = superklass;
    constructor._methods      = [];
    constructor._smethods     = [];
    constructor._isObject     = false;

    constructor._donate = __donate;
    constructor._defs = __defs;

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    Opal[id] = constructor;

    return constructor;
  };

  // Create generic class with given superclass.
  var boot_class = Opal.boot = function(superklass, constructor) {
    var ctor = function() {};
        ctor.prototype = superklass.prototype;

    constructor.prototype = new ctor();
    var prototype = constructor.prototype;

    prototype._klass      = constructor;
    prototype.constructor = constructor;

    constructor._inherited    = [];
    constructor._included_in  = [];
    constructor._isClass      = true;
    constructor._super        = superklass;
    constructor._methods      = [];
    constructor._isObject     = false;
    constructor._klass        = Class;
    constructor._donate       = __donate
    constructor._defs = __defs;

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    constructor['$[]'] = undefined;
    constructor['$call'] = undefined;

    var smethods;

    smethods = superklass._smethods.slice();

    constructor._smethods = smethods;
    for (var i = 0, length = smethods.length; i < length; i++) {
      var m = smethods[i];
      constructor[m] = superklass[m];
    }

    superklass._inherited.push(constructor);

    return constructor;
  };

  var bridge_class = function(constructor) {
    constructor.prototype._klass = constructor;

    constructor._inherited    = [];
    constructor._included_in  = [];
    constructor._isClass      = true;
    constructor._super        = Object;
    constructor._klass        = Class;
    constructor._methods      = [];
    constructor._smethods     = [];
    constructor._isObject     = false;

    constructor._donate = function(){};
    constructor._defs = __defs;

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    var smethods = constructor._smethods = Class._methods.slice();
    for (var i = 0, length = smethods.length; i < length; i++) {
      var m = smethods[i];
      constructor[m] = Object[m];
    }

    bridged_classes.push(constructor);

    var table = Object.prototype, methods = Object._methods;

    for (var i = 0, length = methods.length; i < length; i++) {
      var m = methods[i];
      constructor.prototype[m] = table[m];
    }

    constructor._smethods.push('$allocate');

    return constructor;
  };

  Opal.puts = function(a) { console.log(a); };

  // Method missing dispatcher
  Opal.mm = function(mid) {
    var dispatcher = function() {
      var args = __slice.call(arguments);

      if (this.$method_missing) {
        this.$method_missing._p = dispatcher._p;
        return this.$method_missing.apply(this, [mid].concat(args));
      }
      else {
        return native_send(this, mid, args);
      }
    };

    return dispatcher;
  };

  // send a method to a native object
  var native_send = function(obj, mid, args) {
    var prop, block = native_send._p;
    native_send._p = null;

    if (prop = native_methods[mid]) {
      return prop(obj, args, block);
    }

    prop = obj[mid];

    if (typeof(prop) === "function") {
      prop = prop.apply(obj, args.$to_native());
    }
    else if (mid.charAt(mid.length - 1) === "=") {
      prop = mid.slice(0, mid.length - 1);
      return obj[prop] = args[0];
    }

    if (prop != null) {
      return prop;
    }

    return nil;
  };

  var native_methods = {
    "==": function(obj, args) {
      return obj === args[0];
    },

    "[]": function(obj, args) {
      var prop = obj[args[0]];

      if (prop != null) {
        return prop;
      }

      return nil;
    },

    "respond_to?": function(obj, args) {
      return obj[args[0]] != null;
    },

    "each": function(obj, args, block) {
      for (var key in obj) {
        var prop = obj[key];

        if (prop == null) {
          prop = nil;
        }

        block(key, prop);
      }

      return obj;
    },

    "to_a": function(obj, args) {
      var result = [];

      for (var i = 0, length = obj.length; i < length; i++) {
        result.push(obj[i]);
      }

      return result;
    }
  };

  // Const missing dispatcher
  Opal.cm = function(name) {
    return this.base.$const_missing(name);
  };

  // Arity count error dispatcher
  Opal.ac = function(actual, expected, object, meth) {
    var inspect = (object._isObject ? object._klass._name + '#' : object._name + '.') + meth;
    var msg = '[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')'
    throw Opal.ArgumentError.$new(msg);
  };

  /*
    Call a ruby method on a ruby object with some arguments:

      var my_array = [1, 2, 3, 4]
      Opal.send(my_array, 'length')     # => 4
      Opal.send(my_array, 'reverse!')   # => [4, 3, 2, 1]

    A missing method will be forwarded to the object via
    method_missing.

    The result of either call with be returned.

    @param [Object] recv the ruby object
    @param [String] mid ruby method to call
  */
  Opal.send = function(recv, mid) {
    var args = __slice.call(arguments, 2),
        func = recv['$' + mid];

    if (func) {
      return func.apply(recv, args);
    }

    return recv.$method_missing.apply(recv, [mid].concat(args));
  };

  // Initialization
  // --------------

  boot_defclass('BasicObject', BasicObject)
  boot_defclass('Object', Object, BasicObject);
  boot_defclass('Class', Class, Object);

  Class.prototype = Function.prototype;

  BasicObject._klass = Object._klass = Class._klass = Class;

  // Implementation of Class#===
  function module_eqq(object) {
    if (object == null) {
      return false;
    }

    var search = object._klass;

    while (search) {
      if (search === this) {
        return true;
      }

      search = search._super;
    }

    return false;
  }

  // Implementation of Class#to_s
  function module_to_s() {
    return this._name;
  }

  // Donator for all 'normal' classes and modules
  function __donate(defined, indirect) {
    var methods = this._methods, included_in = this.$included_in;

    // if (!indirect) {
      this._methods = methods.concat(defined);
    // }

    if (included_in) {
      for (var i = 0, length = included_in.length; i < length; i++) {
        var includee = included_in[i];
        var dest = includee.prototype;

        for (var j = 0, jj = defined.length; j < jj; j++) {
          var method = defined[j];
          dest[method] = this.prototype[method];
        }

        if (includee.$included_in) {
          includee._donate(defined, true);
        }
      }

    }
  }

  // Define a singleton method on a class
  function __defs(mid, body) {
    this._smethods.push(mid);
    this[mid] = body;

    var inherited = this._inherited;
    if (inherited.length) {
      for (var i = 0, length = inherited.length, subclass; i < length; i++) {
        subclass = inherited[i];
        if (!subclass[mid]) {
          subclass._defs(mid, body);
        }
      }
    }
  }

  // Defines methods onto Object (which are then donated to bridged classes)
  Object._defn = function (mid, body) {
    this.prototype[mid] = body;
    this._donate([mid]);
  };

  var bridged_classes = Object.$included_in = [];

  Opal.base = Object;
  BasicObject._scope = Object._scope = Opal;
  Opal.Module = Opal.Class;
  Opal.Kernel = Object;

  var class_const_alloc = function(){};
  var class_const_scope = new TopScope();
  class_const_scope.alloc = class_const_alloc;
  Class._scope = class_const_scope;

  Object.prototype.toString = function() {
    return this.$to_s();
  };

  Opal.top = new Object;

  Opal.klass(Object, Object, 'NilClass', NilClass)
  var nil = Opal.nil = new NilClass;
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };

  Opal.breaker  = new Error('unexpected break');
}).call(this);
<commit_msg>Native#each handler should enumerate like an array for array like objects<commit_after>(function(undefined) {
  // The Opal object that is exposed globally
  var Opal = this.Opal = {};

  // Very root class
  function BasicObject(){}

  // Core Object class
  function Object(){}

  // Class' class
  function Class(){}

  // the class of nil
  function NilClass(){}

  // TopScope is used for inheriting constants from the top scope
  var TopScope = function(){};

  // Opal just acts as the top scope
  TopScope.prototype = Opal;

  // To inherit scopes
  Opal.alloc  = TopScope;

  // This is a useful reference to global object inside ruby files
  Opal.global = this;

  // Minify common function calls
  var __hasOwn = Opal.hasOwnProperty;
  var __slice  = Opal.slice = Array.prototype.slice;

  // Generates unique id for every ruby object
  var unique_id = 0;

  // Return next unique id
  Opal.uid = function() {
    return unique_id++;
  };

  // Table holds all class variables
  Opal.cvars = {};

  // Globals table
  Opal.gvars = {};

  Opal.klass = function(base, superklass, id, constructor) {
    var klass;
    if (base._isObject) {
      base = base._klass;
    }

    if (superklass === null) {
      superklass = Object;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      if (!superklass._methods) {
        var bridged = superklass;
        superklass  = Object;
        klass       = bridge_class(bridged);
      }
      else {
        klass = boot_class(superklass, constructor);
      }

      klass._name = (base === Object ? id : base._name + '::' + id);

      var const_alloc   = function() {};
      var const_scope   = const_alloc.prototype = new base._scope.alloc();
      klass._scope      = const_scope;
      const_scope.base  = klass;
      const_scope.alloc = const_alloc;

      base[id] = base._scope[id] = klass;

      if (superklass.$inherited) {
        superklass.$inherited(klass);
      }
    }

    return klass;
  };

  // Define new module (or return existing module)
  Opal.module = function(base, id, constructor) {
    var klass;
    if (base._isObject) {
      base = base._klass;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      klass = boot_class(Class, constructor);
      klass._name = (base === Object ? id : base._name + '::' + id);

      klass.$included_in = [];

      var const_alloc   = function() {};
      var const_scope   = const_alloc.prototype = new base._scope.alloc();
      klass._scope      = const_scope;
      const_scope.alloc = const_alloc;

      base[id] = base._scope[id]    = klass;
    }

    return klass;
  }

  // Utility function to raise a "no block given" error
  var no_block_given = function() {
    throw new Error('no block given');
  };

  // Boot a base class (makes instances).
  var boot_defclass = function(id, constructor, superklass) {
    if (superklass) {
      var ctor           = function() {};
          ctor.prototype = superklass.prototype;

      constructor.prototype = new ctor();
    }

    var prototype = constructor.prototype;

    prototype.constructor = constructor;
    prototype._isObject   = true;
    prototype._klass      = constructor;

    constructor._inherited    = [];
    constructor._included_in  = [];
    constructor._isClass      = true;
    constructor._name         = id;
    constructor._super        = superklass;
    constructor._methods      = [];
    constructor._smethods     = [];
    constructor._isObject     = false;

    constructor._donate = __donate;
    constructor._defs = __defs;

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    Opal[id] = constructor;

    return constructor;
  };

  // Create generic class with given superclass.
  var boot_class = Opal.boot = function(superklass, constructor) {
    var ctor = function() {};
        ctor.prototype = superklass.prototype;

    constructor.prototype = new ctor();
    var prototype = constructor.prototype;

    prototype._klass      = constructor;
    prototype.constructor = constructor;

    constructor._inherited    = [];
    constructor._included_in  = [];
    constructor._isClass      = true;
    constructor._super        = superklass;
    constructor._methods      = [];
    constructor._isObject     = false;
    constructor._klass        = Class;
    constructor._donate       = __donate
    constructor._defs = __defs;

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    constructor['$[]'] = undefined;
    constructor['$call'] = undefined;

    var smethods;

    smethods = superklass._smethods.slice();

    constructor._smethods = smethods;
    for (var i = 0, length = smethods.length; i < length; i++) {
      var m = smethods[i];
      constructor[m] = superklass[m];
    }

    superklass._inherited.push(constructor);

    return constructor;
  };

  var bridge_class = function(constructor) {
    constructor.prototype._klass = constructor;

    constructor._inherited    = [];
    constructor._included_in  = [];
    constructor._isClass      = true;
    constructor._super        = Object;
    constructor._klass        = Class;
    constructor._methods      = [];
    constructor._smethods     = [];
    constructor._isObject     = false;

    constructor._donate = function(){};
    constructor._defs = __defs;

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    var smethods = constructor._smethods = Class._methods.slice();
    for (var i = 0, length = smethods.length; i < length; i++) {
      var m = smethods[i];
      constructor[m] = Object[m];
    }

    bridged_classes.push(constructor);

    var table = Object.prototype, methods = Object._methods;

    for (var i = 0, length = methods.length; i < length; i++) {
      var m = methods[i];
      constructor.prototype[m] = table[m];
    }

    constructor._smethods.push('$allocate');

    return constructor;
  };

  Opal.puts = function(a) { console.log(a); };

  // Method missing dispatcher
  Opal.mm = function(mid) {
    var dispatcher = function() {
      var args = __slice.call(arguments);

      if (this.$method_missing) {
        this.$method_missing._p = dispatcher._p;
        return this.$method_missing.apply(this, [mid].concat(args));
      }
      else {
        return native_send(this, mid, args);
      }
    };

    return dispatcher;
  };

  // send a method to a native object
  var native_send = function(obj, mid, args) {
    var prop, block = native_send._p;
    native_send._p = null;

    if (prop = native_methods[mid]) {
      return prop(obj, args, block);
    }

    prop = obj[mid];

    if (typeof(prop) === "function") {
      prop = prop.apply(obj, args.$to_native());
    }
    else if (mid.charAt(mid.length - 1) === "=") {
      prop = mid.slice(0, mid.length - 1);
      return obj[prop] = args[0];
    }

    if (prop != null) {
      return prop;
    }

    return nil;
  };

  var native_methods = {
    "==": function(obj, args) {
      return obj === args[0];
    },

    "[]": function(obj, args) {
      var prop = obj[args[0]];

      if (prop != null) {
        return prop;
      }

      return nil;
    },

    "respond_to?": function(obj, args) {
      return obj[args[0]] != null;
    },

    "each": function(obj, args, block) {
      var prop;

      if (obj.length === +obj.length) {
        for (var i = 0, len = obj.length; i < len; i++) {
          prop = obj[i];

          if (prop == null) {
            prop = nil;
          }

          block(prop);
        }
      }
      else {
        for (var key in obj) {
          prop = obj[key];

          if (prop == null) {
            prop = nil;
          }

          block(key, prop);
        }
      }

      return obj;
    },

    "to_a": function(obj, args) {
      var result = [];

      for (var i = 0, length = obj.length; i < length; i++) {
        result.push(obj[i]);
      }

      return result;
    }
  };

  // Const missing dispatcher
  Opal.cm = function(name) {
    return this.base.$const_missing(name);
  };

  // Arity count error dispatcher
  Opal.ac = function(actual, expected, object, meth) {
    var inspect = (object._isObject ? object._klass._name + '#' : object._name + '.') + meth;
    var msg = '[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')'
    throw Opal.ArgumentError.$new(msg);
  };

  /*
    Call a ruby method on a ruby object with some arguments:

      var my_array = [1, 2, 3, 4]
      Opal.send(my_array, 'length')     # => 4
      Opal.send(my_array, 'reverse!')   # => [4, 3, 2, 1]

    A missing method will be forwarded to the object via
    method_missing.

    The result of either call with be returned.

    @param [Object] recv the ruby object
    @param [String] mid ruby method to call
  */
  Opal.send = function(recv, mid) {
    var args = __slice.call(arguments, 2),
        func = recv['$' + mid];

    if (func) {
      return func.apply(recv, args);
    }

    return recv.$method_missing.apply(recv, [mid].concat(args));
  };

  // Initialization
  // --------------

  boot_defclass('BasicObject', BasicObject)
  boot_defclass('Object', Object, BasicObject);
  boot_defclass('Class', Class, Object);

  Class.prototype = Function.prototype;

  BasicObject._klass = Object._klass = Class._klass = Class;

  // Implementation of Class#===
  function module_eqq(object) {
    if (object == null) {
      return false;
    }

    var search = object._klass;

    while (search) {
      if (search === this) {
        return true;
      }

      search = search._super;
    }

    return false;
  }

  // Implementation of Class#to_s
  function module_to_s() {
    return this._name;
  }

  // Donator for all 'normal' classes and modules
  function __donate(defined, indirect) {
    var methods = this._methods, included_in = this.$included_in;

    // if (!indirect) {
      this._methods = methods.concat(defined);
    // }

    if (included_in) {
      for (var i = 0, length = included_in.length; i < length; i++) {
        var includee = included_in[i];
        var dest = includee.prototype;

        for (var j = 0, jj = defined.length; j < jj; j++) {
          var method = defined[j];
          dest[method] = this.prototype[method];
        }

        if (includee.$included_in) {
          includee._donate(defined, true);
        }
      }

    }
  }

  // Define a singleton method on a class
  function __defs(mid, body) {
    this._smethods.push(mid);
    this[mid] = body;

    var inherited = this._inherited;
    if (inherited.length) {
      for (var i = 0, length = inherited.length, subclass; i < length; i++) {
        subclass = inherited[i];
        if (!subclass[mid]) {
          subclass._defs(mid, body);
        }
      }
    }
  }

  // Defines methods onto Object (which are then donated to bridged classes)
  Object._defn = function (mid, body) {
    this.prototype[mid] = body;
    this._donate([mid]);
  };

  var bridged_classes = Object.$included_in = [];

  Opal.base = Object;
  BasicObject._scope = Object._scope = Opal;
  Opal.Module = Opal.Class;
  Opal.Kernel = Object;

  var class_const_alloc = function(){};
  var class_const_scope = new TopScope();
  class_const_scope.alloc = class_const_alloc;
  Class._scope = class_const_scope;

  Object.prototype.toString = function() {
    return this.$to_s();
  };

  Opal.top = new Object;

  Opal.klass(Object, Object, 'NilClass', NilClass)
  var nil = Opal.nil = new NilClass;
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };

  Opal.breaker  = new Error('unexpected break');
}).call(this);
<|endoftext|>


<commit_before>// adopted from: ilog <https://github.com/teambition/ilog>
// Copyright (c) 2015 Teambition (License: MIT)

'use strict'

const format = require('util').format
const jlog   = require('../util/jcolorz')
const ccase  = require('../string/sentenceCase')
const map    = require('../array/map')
const slice  = require('../array/slice')
const nano   = require('../time/nano')

const levels = [
  'FATAL',    // level 0
  'CRITICAL', // level 1
  'ERROR',    // level 2
  'WARNING',  // level 3
  'ALERT',    // level 4
  'NOTICE',   // level 5
  'INFO',     // level 6
  'DEBUG'     // level 7
]

const clrs = {
  black   : 30,
  gray    : 90,
  grey    : 90,
  red     : 31,
  green   : 32,
  yellow  : 33,
  blue    : 34,
  magenta : 35,
  cyan    : 36,
  white   : 37
}

// Original version
function ilog () {
  if (arguments.length) {
    ilog._stdout.write(ilog._assembleLog(format.apply(null, arguments)))
  }
}

// Own version: meant for raw string output to log
ilog.log = function () {
  // don't penalize a single string/template being passed as a param
  arguments.length > 1
    ? ilog._stdout.write(ilog._assembleLog(slice(arguments).join(' ')))
    : ilog._stdout.write(ilog._assembleLog(arguments[0]))
}

// options for display, preserving the original functionality by reversing values.
ilog.display = {
  colors: true,
  dates: false,
  jlog: true
}

// ilog.level === -1 turns off all levels
// ilog.level === -2 turns on debug logging only
// ilog.level === -3 turns on debug and trace logging
// ilog.level === -4 adds notice and info logging
ilog.level = 7
ilog.levels = levels.slice()

// ilog.fatal, ilog.critical, ilog.error, ilog.warning, ilog.alert
map(levels.slice(0, 5), (level, index) => {
  ilog[level.toLowerCase()] = function (error, stack) {
    if (error != null && index <= ilog.level) {
      // allow the ability to pass debugging messages as strings
      if (typeof error === 'string') error = {message: error}
      if (stack) error.stack = ilog._errorify(stack)

      error.name = ccase(level)

      let color = ilog.display.colors ? ilog._color(level, 'red') : level
      let label = ilog.display.dates ? ilog._label(new Date()) : ilog._label()

      error = ilog.display.colors
        ? ilog._errorify(error)
        : ilog._stringify(ilog._errorify(error))

      let type = function (obj) {
        return typeof obj === 'string'
          ? obj
          : obj.message
      }

      ilog._stderr.write(ilog._assembleLog(type(error), color, label))
      if (ilog.display.colors && ilog.display.jlog) jlog(error)
    }
  }
})

// ilog.notice, ilog.info
map(levels.slice(5, 7), (level, index) => {
  index += 5
  ilog[level.toLowerCase()] = function (message) {
    if (message != null && (index <= ilog.level || ilog.level <= -4)) {
      message = ilog._stringify(message)

      let color = ilog.display.colors ? ilog._color(level, 'grey') : level
      let label = ilog.display.dates ? ilog._label(new Date()) : ilog._label()

      ilog._stdout.write(ilog._assembleLog(message, color, label))
    }
  }
})

ilog.debug = function () {
  if (arguments.length && (ilog.level >= 7 || ilog.level <= -2)) {
    let messages

    if (arguments.length === 1) {
      messages = ilog._stringify(arguments[0])
    }

    else if (arguments.length === 2
      && typeof arguments[1] === 'object'
      && 'name' in arguments[1]
      && 'message' in arguments[1]
    ) {
      messages = arguments[0]
      var stack = {
        name: 'Debug',
        message: arguments[0],
        stack: ilog._errorify(arguments[1])
      }
    }

    else messages = format.apply(null, arguments)

    let color = ilog.display.colors
      ? ilog._color('DEBUG', 'blue')
      : 'DEBUG'

    let label = ilog.display.dates
      ? ilog._label(new Date())
      : ilog._label()

    ilog._stdout.write(ilog._assembleLog(messages, color, label))
    if (ilog.display.colors && ilog.display.jlog && stack) jlog(stack)
  }
}

// trace logging [level 8]
ilog.trace = function () {
  if (arguments.length && (ilog.level >= 8 || ilog.level <= -3)) {
    // contruct components
    let messages = format.apply(null, arguments)
    let color = ilog.display.colors ? ilog._color('LOGR', 'yellow') : 'LOGR'
    let label = ilog.display.dates ? ilog._label(new Date()) : ilog._label()

    // compose message
    let assemble = ilog._assembleLog(messages, color, label)

    // log message
    ilog._stdout.write(assemble)
  }
}

ilog.assert = function (expression, label) {
  let result = !!expression
  let stack = {
    name: 'Assert',
    message: label,
    actual: result,
    expected: true
  }

  if (result) ilog.debug('Assertion Passed', stack)
  else ilog.error('Assertion Failed', stack)
}

ilog.auto = function (error) {
  if (error instanceof Error) return ilog.error(error)
  let args = slice(arguments, +(error == null))
  if (args.length === 1) ilog.info(args[0])
  else if (args.length > 1) ilog.debug.apply(null, args)
}

// expose json-colorz
ilog.jlog = function () {
  if (ilog.display.jlog) {
    map(slice(arguments), (arg) => {
      jlog(arg)
    })
  }
}

// implement base start and stop times
// adopted from debug-logger
ilog.timeTables = {}

ilog.strt = function time (label) {
  if (Array.isArray(label)) {
    map(label, (lab) => {
      ilog.timeTables[lab] = process.hrtime()
    })
  }

  else {
    ilog.timeTables[label] = process.hrtime()
  }
}

ilog.stop = function timeEnd (label) {
  var diff = process.hrtime(ilog.timeTables[label])
  var diffMs = nano(diff, 'ms', 3)
  ilog.log(`${label} took: ${ilog._color(diffMs, 'grey')} ms`)
}

ilog._stdout = process.stdout
ilog._stderr = process.stderr
ilog._procname = process.argv[1].split('/').pop()
ilog._pointer = {
  tick       : '✔',
  check      : '√',
  cross      : '✖',
  star       : '★',
  bullet     : '*',
  info       : 'i',
  info2      : 'ℹ',
  warning    : '‼',
  warning2   : '⚠',
  clip       : '❯',
  single     : '›',
  double     : '»',
  arrowUp    : '↑',
  arrowDown  : '↓',
  arrowLeft  : '←',
  arrowRight : '→',
  radioOn    : '◉',
  radioOff   : '◯'
}

ilog._color = function (label, color) {
  return `\u001b[${clrs[color]}m${label}\u001b[39m`
}

ilog._label = function (label) {
  return `${ilog._procname} ${ilog._pointer.double}`
}

ilog._assembleLog = function (log, level, label) {
  if (level) log = `${level} ${log}`
  if (label) log = `${label} ${log}\n`
  else log = `${ilog._label()} ${log}\n`

  return log
}

ilog._stringify = function (obj) {
  try {
    return JSON.stringify(obj)
  } catch (e) {
    return format(obj)
  }
}

ilog._errorify = function (error) {
  return new Errorify(error)
}

function Errorify (error) {
  this.name = error.name || 'Error'
  this.message = error.message || format(error)

  if (error.code) this.code = error.code
  if (error.errno) this.errno = error.errno
  if (error.status) this.status = error.status
  if (error.syscall) this.syscall = error.syscall
  if (!Array.isArray(error)) {
    Object.keys(error).map((key) => {
      if (!this[key]) this[key] = error[key]
    })
  }
  if (error.stack) this.stack = error.stack
}

module.exports = ilog
<commit_msg>update debug/ilog -- add description message for json-colorz output<commit_after>// adopted from: ilog <https://github.com/teambition/ilog>
// Copyright (c) 2015 Teambition (License: MIT)

'use strict'

const format = require('util').format
const jlog   = require('../util/jcolorz')
const ccase  = require('../string/sentenceCase')
const map    = require('../array/map')
const slice  = require('../array/slice')
const nano   = require('../time/nano')

const levels = [
  'FATAL',    // level 0
  'CRITICAL', // level 1
  'ERROR',    // level 2
  'WARNING',  // level 3
  'ALERT',    // level 4
  'NOTICE',   // level 5
  'INFO',     // level 6
  'DEBUG'     // level 7
]

const clrs = {
  black   : 30,
  gray    : 90,
  grey    : 90,
  red     : 31,
  green   : 32,
  yellow  : 33,
  blue    : 34,
  magenta : 35,
  cyan    : 36,
  white   : 37
}

// Original version
function ilog () {
  if (arguments.length) {
    ilog._stdout.write(ilog._assembleLog(format.apply(null, arguments)))
  }
}

// Own version: meant for raw string output to log
ilog.log = function () {
  // don't penalize a single string/template being passed as a param
  arguments.length > 1
    ? ilog._stdout.write(ilog._assembleLog(slice(arguments).join(' ')))
    : ilog._stdout.write(ilog._assembleLog(arguments[0]))
}

// options for display, preserving the original functionality by reversing values.
ilog.display = {
  colors: true,
  dates: false,
  jlog: true
}

// ilog.level === -1 turns off all levels
// ilog.level === -2 turns on debug logging only
// ilog.level === -3 turns on debug and trace logging
// ilog.level === -4 adds notice and info logging
ilog.level = 7
ilog.levels = levels.slice()

// ilog.fatal, ilog.critical, ilog.error, ilog.warning, ilog.alert
map(levels.slice(0, 5), (level, index) => {
  ilog[level.toLowerCase()] = function (error, stack) {
    if (error != null && index <= ilog.level) {
      // allow the ability to pass debugging messages as strings
      if (typeof error === 'string') error = {message: error}
      if (stack) error.stack = ilog._errorify(stack)

      error.name = ccase(level)

      let color = ilog.display.colors ? ilog._color(level, 'red') : level
      let label = ilog.display.dates ? ilog._label(new Date()) : ilog._label()

      error = ilog.display.colors
        ? ilog._errorify(error)
        : ilog._stringify(ilog._errorify(error))

      let type = function (obj) {
        return typeof obj === 'string'
          ? obj
          : obj.message
      }

      ilog._stderr.write(ilog._assembleLog(type(error), color, label))
      if (ilog.display.colors && ilog.display.jlog) jlog(error)
    }
  }
})

// ilog.notice, ilog.info
map(levels.slice(5, 7), (level, index) => {
  index += 5
  ilog[level.toLowerCase()] = function (message) {
    if (message != null && (index <= ilog.level || ilog.level <= -4)) {
      message = ilog._stringify(message)

      let color = ilog.display.colors ? ilog._color(level, 'grey') : level
      let label = ilog.display.dates ? ilog._label(new Date()) : ilog._label()

      ilog._stdout.write(ilog._assembleLog(message, color, label))
    }
  }
})

ilog.debug = function () {
  if (arguments.length && (ilog.level >= 7 || ilog.level <= -2)) {
    let messages

    if (arguments.length === 1) {
      messages = ilog._stringify(arguments[0])
    }

    else if (arguments.length === 2
      && typeof arguments[1] === 'object'
      && 'name' in arguments[1]
      && 'message' in arguments[1]
    ) {
      messages = arguments[0]
      var stack = {
        name: 'Debug',
        message: arguments[0],
        stack: ilog._errorify(arguments[1])
      }
    }

    else messages = format.apply(null, arguments)

    let color = ilog.display.colors
      ? ilog._color('DEBUG', 'blue')
      : 'DEBUG'

    let label = ilog.display.dates
      ? ilog._label(new Date())
      : ilog._label()

    ilog._stdout.write(ilog._assembleLog(messages, color, label))
    if (ilog.display.colors && ilog.display.jlog && stack) jlog(stack)
  }
}

// trace logging [level 8]
ilog.trace = function () {
  if (arguments.length && (ilog.level >= 8 || ilog.level <= -3)) {
    // contruct components
    let messages = format.apply(null, arguments)
    let color = ilog.display.colors ? ilog._color('LOGR', 'yellow') : 'LOGR'
    let label = ilog.display.dates ? ilog._label(new Date()) : ilog._label()

    // compose message
    let assemble = ilog._assembleLog(messages, color, label)

    // log message
    ilog._stdout.write(assemble)
  }
}

ilog.assert = function (expression, label) {
  let result = !!expression
  let stack = {
    name: 'Assert',
    message: label,
    actual: result,
    expected: true
  }

  if (result) ilog.debug('Assertion Passed', stack)
  else ilog.error('Assertion Failed', stack)
}

ilog.auto = function (error) {
  if (error instanceof Error) return ilog.error(error)
  let args = slice(arguments, +(error == null))
  if (args.length === 1) ilog.info(args[0])
  else if (args.length > 1) ilog.debug.apply(null, args)
}

// expose json-colorz
ilog.jlog = function (desc) {
  if (ilog.display.jlog) {
    ilog.log(desc)
    map(slice(arguments, 1), (arg) => {
      jlog(arg)
    })
  }
}

// implement base start and stop times
// adopted from debug-logger
ilog.timeTables = {}

ilog.strt = function time (label) {
  if (Array.isArray(label)) {
    map(label, (lab) => {
      ilog.timeTables[lab] = process.hrtime()
    })
  }

  else {
    ilog.timeTables[label] = process.hrtime()
  }
}

ilog.stop = function timeEnd (label) {
  var diff = process.hrtime(ilog.timeTables[label])
  var diffMs = nano(diff, 'ms', 3)
  ilog.log(`${label} took: ${ilog._color(diffMs, 'grey')} ms`)
}

ilog._stdout = process.stdout
ilog._stderr = process.stderr
ilog._procname = process.argv[1].split('/').pop()
ilog._pointer = {
  tick       : '✔',
  check      : '√',
  cross      : '✖',
  star       : '★',
  bullet     : '*',
  info       : 'i',
  info2      : 'ℹ',
  warning    : '‼',
  warning2   : '⚠',
  clip       : '❯',
  single     : '›',
  double     : '»',
  arrowUp    : '↑',
  arrowDown  : '↓',
  arrowLeft  : '←',
  arrowRight : '→',
  radioOn    : '◉',
  radioOff   : '◯'
}

ilog._color = function (label, color) {
  return `\u001b[${clrs[color]}m${label}\u001b[39m`
}

ilog._label = function (label) {
  return `${ilog._procname} ${ilog._pointer.double}`
}

ilog._assembleLog = function (log, level, label) {
  if (level) log = `${level} ${log}`
  if (label) log = `${label} ${log}\n`
  else log = `${ilog._label()} ${log}\n`

  return log
}

ilog._stringify = function (obj) {
  try {
    return JSON.stringify(obj)
  } catch (e) {
    return format(obj)
  }
}

ilog._errorify = function (error) {
  return new Errorify(error)
}

function Errorify (error) {
  this.name = error.name || 'Error'
  this.message = error.message || format(error)

  if (error.code) this.code = error.code
  if (error.errno) this.errno = error.errno
  if (error.status) this.status = error.status
  if (error.syscall) this.syscall = error.syscall
  if (!Array.isArray(error)) {
    Object.keys(error).map((key) => {
      if (!this[key]) this[key] = error[key]
    })
  }
  if (error.stack) this.stack = error.stack
}

module.exports = ilog
<|endoftext|>


<commit_before>function Reader ($div, images) {
  this.$div = $div;
  this.$container = this.$div.find('.img-container');
  this.$img = this.$container.find('img');
  this.$zoom = this.$div.find('.zoom');
  this.$save = this.$div.find('.save');
  this.$print = this.$div.find('.print');
  this.$prev = this.$div.find('.prev');
  this.$next = this.$div.find('.next');
  this.$spinner = this.$div.find('.spinner-container');

  this.images = images;
  this.current = 0;
  this.zoomed = false;
  this.dragged = false;
  this.zoomX = 0;
  this.zoomY = 0;
  this.currentSize = 'small';
  this.moving = false;

  this.$img.off().click(this.toggleZoom.bind(this)
  ).mousedown(this.drag.bind(this)
  ).mousemove(this.move.bind(this)
  ).mouseout(this.undrag.bind(this)
  ).focusout(this.undrag.bind(this));

  this.$zoom.off().click(this.toggleZoom.bind(this));
  this.$save.off().click(this.save.bind(this));
  this.$print.off().click(this.print.bind(this));

  this.$prev.off().click(this.previous.bind(this));
  this.$next.off().click(this.next.bind(this));
  $(document).keydown(this.keydown.bind(this));

  this.changeImage(0);
}

Reader.prototype.toggleZoom = function (e) {
  e.preventDefault();
  if (this.zoomed) {
    this.unzoom();
  } else {
    this.zoom(e);
  }
};

Reader.prototype.zoom = function (e) {
  var previousWidth = this.$img.width(), previousHeight = this.$img.height();
  this.currentSize = 'medium';
  this.changeImage(0, function () {
    this.zoomed = true;
    this.$container.addClass('zoomed').scrollLeft(
      (e.offsetX * this.$img.width() / previousWidth)
      - this.$container.width() / 2).scrollTop(
      (e.offsetY * this.$img.height() / previousHeight)
      - this.$container.height() / 2);
    this.$zoom.find('.fa').removeClass('fa-search-plus').addClass('fa-search-minus');
  }.bind(this));
};

Reader.prototype.unzoom = function () {
  if (this.dragged) {
    this.undrag();
    if (this.moving) {
      this.moving = false;
      return;
    }
  }
  this.zoomed = false;
  this.$container.removeClass('zoomed');
  this.currentSize = 'small';
  this.$zoom.find('.fa').removeClass('fa-search-minus').addClass('fa-search-plus');
};

Reader.prototype.save = function () {
  var src = this.images[this.current]['original'];
  this.$save.attr('href', src).attr('download', src.replace(/^.*[\\\/]/, ''));
};

Reader.prototype.print = function (e) {
  e.preventDefault();
  var popup = window.open();
  popup.document.write(
    ''
    + ''
    + ''
    + ''
  );
};

Reader.prototype.wait = function () {
  this.$spinner.removeClass('hidden');
};

Reader.prototype.unwait = function () {
  this.$spinner.addClass('hidden');
};

Reader.prototype.updateControls = function () {
  if (this.current == 0) {
    this.$prev.addClass('invisible');
  } else {
    this.$prev.removeClass('invisible');
  }
  if (this.current == (this.images.length - 1)) {
    this.$next.addClass('invisible');
  } else {
    this.$next.removeClass('invisible');
  }
};

Reader.prototype.changeImage = function (inc, loadHandler) {
  var current = this.current;
  current += inc;
  if (current < 0 || current >= this.images.length ) {
    return;
  }
  this.current = current;

  var completeLoadHandler = function () {
    this.unwait();
    if (typeof loadHandler != 'undefined') {
      loadHandler();
    }
    this.$img.unbind('load');
  }.bind(this);

  this.wait();
  var src = this.images[current][this.currentSize];
  if (this.$img.attr('src') != src) {
    this.$img.attr('src', src).load(completeLoadHandler);
  } else {
    completeLoadHandler();
  }
  this.updateControls();
};

Reader.prototype.previous = function (e) {
  e.preventDefault();
  this.changeImage(-1);
};

Reader.prototype.next = function (e) {
  e.preventDefault();
  this.changeImage(1);
};

Reader.prototype.drag = function (e) {
  e.preventDefault();
  if (this.zoomed) {
    this.dragged = true;
    this.zoomX = this.$container.scrollLeft() + e.pageX;
    this.zoomY = this.$container.scrollTop() + e.pageY;
    this.$img.addClass('dragged');
  }
};

Reader.prototype.undrag = function () {
  this.dragged = false;
  this.$img.removeClass('dragged');
};

Reader.prototype.move = function (e) {
  if (this.dragged) {
    this.moving = true;
    this.$container.scrollLeft(
      this.zoomX - e.pageX).scrollTop(
      this.zoomY - e.pageY);
  }
};

Reader.prototype.keydown = function (e) {
  if (!this.$div.is(':visible')) {
    return;
  }

  if (e.keyCode == 37) {
    this.previous(e);
  } else if (e.keyCode == 39) {
    this.next(e);
  }
};
<commit_msg>Corrige un problème de compatibilité avec Firefox.<commit_after>function Reader ($div, images) {
  this.$div = $div;
  this.$container = this.$div.find('.img-container');
  this.$img = this.$container.find('img');
  this.$zoom = this.$div.find('.zoom');
  this.$save = this.$div.find('.save');
  this.$print = this.$div.find('.print');
  this.$prev = this.$div.find('.prev');
  this.$next = this.$div.find('.next');
  this.$spinner = this.$div.find('.spinner-container');

  this.images = images;
  this.current = 0;
  this.zoomed = false;
  this.dragged = false;
  this.zoomX = 0;
  this.zoomY = 0;
  this.currentSize = 'small';
  this.moving = false;

  this.$img.off().click(this.toggleZoom.bind(this)
  ).mousedown(this.drag.bind(this)
  ).mousemove(this.move.bind(this)
  ).mouseout(this.undrag.bind(this)
  ).focusout(this.undrag.bind(this));

  this.$zoom.off().click(this.toggleZoom.bind(this));
  this.$save.off().click(this.save.bind(this));
  this.$print.off().click(this.print.bind(this));

  this.$prev.off().click(this.previous.bind(this));
  this.$next.off().click(this.next.bind(this));
  $(document).keydown(this.keydown.bind(this));

  this.changeImage(0);
}

Reader.prototype.toggleZoom = function (e) {
  e.preventDefault();
  if (this.zoomed) {
    this.unzoom();
  } else {
    this.zoom(e);
  }
};

Reader.prototype.zoom = function (e) {
  var previousWidth = this.$img.width(), previousHeight = this.$img.height();
  this.currentSize = 'medium';
  this.changeImage(0, function () {
    this.zoomed = true;
    this.$container.addClass('zoomed').scrollLeft(
      (e.originalEvent.layerX * this.$img.width() / previousWidth)
      - this.$container.width() / 2).scrollTop(
      (e.originalEvent.layerY * this.$img.height() / previousHeight)
      - this.$container.height() / 2);
    this.$zoom.find('.fa').removeClass('fa-search-plus').addClass('fa-search-minus');
  }.bind(this));
};

Reader.prototype.unzoom = function () {
  if (this.dragged) {
    this.undrag();
    if (this.moving) {
      this.moving = false;
      return;
    }
  }
  this.zoomed = false;
  this.$container.removeClass('zoomed');
  this.currentSize = 'small';
  this.$zoom.find('.fa').removeClass('fa-search-minus').addClass('fa-search-plus');
};

Reader.prototype.save = function () {
  var src = this.images[this.current]['original'];
  this.$save.attr('href', src).attr('download', src.replace(/^.*[\\\/]/, ''));
};

Reader.prototype.print = function (e) {
  e.preventDefault();
  var popup = window.open();
  popup.document.write(
    ''
    + ''
    + ''
    + ''
  );
};

Reader.prototype.wait = function () {
  this.$spinner.removeClass('hidden');
};

Reader.prototype.unwait = function () {
  this.$spinner.addClass('hidden');
};

Reader.prototype.updateControls = function () {
  if (this.current == 0) {
    this.$prev.addClass('invisible');
  } else {
    this.$prev.removeClass('invisible');
  }
  if (this.current == (this.images.length - 1)) {
    this.$next.addClass('invisible');
  } else {
    this.$next.removeClass('invisible');
  }
};

Reader.prototype.changeImage = function (inc, loadHandler) {
  var current = this.current;
  current += inc;
  if (current < 0 || current >= this.images.length ) {
    return;
  }
  this.current = current;

  var completeLoadHandler = function () {
    this.unwait();
    if (typeof loadHandler != 'undefined') {
      loadHandler();
    }
    this.$img.unbind('load');
  }.bind(this);

  this.wait();
  var src = this.images[current][this.currentSize];
  if (this.$img.attr('src') != src) {
    this.$img.attr('src', src).load(completeLoadHandler);
  } else {
    completeLoadHandler();
  }
  this.updateControls();
};

Reader.prototype.previous = function (e) {
  e.preventDefault();
  this.changeImage(-1);
};

Reader.prototype.next = function (e) {
  e.preventDefault();
  this.changeImage(1);
};

Reader.prototype.drag = function (e) {
  e.preventDefault();
  if (this.zoomed) {
    this.dragged = true;
    this.zoomX = this.$container.scrollLeft() + e.pageX;
    this.zoomY = this.$container.scrollTop() + e.pageY;
    this.$img.addClass('dragged');
  }
};

Reader.prototype.undrag = function () {
  this.dragged = false;
  this.$img.removeClass('dragged');
};

Reader.prototype.move = function (e) {
  if (this.dragged) {
    this.moving = true;
    this.$container.scrollLeft(
      this.zoomX - e.pageX).scrollTop(
      this.zoomY - e.pageY);
  }
};

Reader.prototype.keydown = function (e) {
  if (!this.$div.is(':visible')) {
    return;
  }

  if (e.keyCode == 37) {
    this.previous(e);
  } else if (e.keyCode == 39) {
    this.next(e);
  }
};
<|endoftext|>


<commit_before>import {registerListenerInfo} from './register-listener-info.js'
import camelToKebab from './camel-to-kebab.js'
import {register as cc} from './register-and-init.js'
import isFunction from './is-function.js'
import trigger from './event-trigger.js'

/**
 * The decorator for registering event listener info to the method.
 * @param {string} event The event name
 * @param {string} at The selector
 */
cc.on = (event, {at} = {}) => {
  /**
   * The decorator for registering event listener info to the method.
   * @param {string} event The event name
   * @param {string} selector The selector for listening.
   */
  const atDecorator = selector => (target, key) => {
    registerListenerInfo(target.constructor, key, event, selector)
  }

  const onDecorator = atDecorator(at)
  onDecorator.at = atDecorator

  return onDecorator
}

/**
 * `@emit(event)` decorator.
 * This decorator adds the event emission at the beginning of the method.
 * @param {string} event The event name
 */
cc.emit = event => {
  const emitDecorator = (target, key, descriptor) => {
    const method = descriptor.value

    descriptor.value = function () {
      trigger(this.el, event, arguments[0])

      return method.apply(this, arguments)
    }
  }

  /**
   * `@emit(event).last` decorator.
   * This adds the emission of the event at the end of the method.
   * @param {string} event The event name
   */
  emitDecorator.last = (target, key, descriptor) => {
    cc.emit.last(event)(target, key, descriptor)
  }

  return emitDecorator
}

cc.emit.last = event => (target, key, descriptor) => {
  const method = descriptor.value

  descriptor.value = function () {
    const result = method.apply(this, arguments)

    const emit = x => trigger(this.el, event, x)

    if (result && result.then) {
      result.then(emit)
    } else {
      emit(result)
    }

    return result
  }
}

/**
 * Replaces the getter with the function which accesses the class-component of the given name.
 * @param {string} name The class component name
 * @param {string} [selector] The selector to access class component dom. Optional. Default is '.[name]'.
 * @param {object} target The prototype of the target class
 * @param {string} key The name of the property
 * @param {object} descriptor The property descriptor
 */
const wireByNameAndSelector = (name, selector) => (target, key, descriptor) => {
  selector = selector || '.' + name

  descriptor.get = function () {
    const matched = this.elem.filter(selector).add(selector, this.elem)

    if (matched[1]) { // meaning matched.length > 1
      console.warn(`There are ${matched.length} matches for the given wired getter selector: ${selector}`)
    }

    return matched.cc.get(name)
  }
}

/**
 * Wires the class component of the name of the key to the property of the same name.
 */
cc.wire = (target, key, descriptor) => {
  if (!descriptor) {
    // If the descriptor is not given, then suppose this is called as @wire(componentName, selector) and therefore
    // we need to return the following expression (it works as another decorator).
    return wireByNameAndSelector(target, key)
  }

  wireByNameAndSelector(camelToKebab(key))(target, key, descriptor)
}

/**
 * The decorator for class component registration.
 *
 * if `name` is function, then use it as class itself and the component name is kebabized version of its name.
 * @param {String|Function} name The class name or the implementation class itself
 * @return {Function|undefined} The decorator if the class name is given, undefined if the implementation class is given
 */
cc.component = name => isFunction(name) ? cc(camelToKebab(name.name), name) : Cls => cc(name, Cls)
<commit_msg>:hammer: refactor(flow): use flow in src/decorators<commit_after>// @flow

import { registerListenerInfo } from './register-listener-info.js'
import camelToKebab from './camel-to-kebab.js'
import { register as cc } from './register-and-init.js'
import trigger from './event-trigger.js'

/**
 * The decorator for registering event listener info to the method.
 * @param event The event name
 * @param at The selector
 */
(cc: any).on = (event: string, { at }: { at: string } = {}) => {
  /**
   * The decorator for registering event listener info to the method.
   * @param {string} event The event name
   * @param {string} selector The selector for listening.
   */
  const atDecorator = selector => (target, key) => {
    registerListenerInfo(target.constructor, key, event, selector)
  }

  const onDecorator = atDecorator(at)
  onDecorator.at = atDecorator

  return onDecorator
}

/**
 * `@emit(event)` decorator.
 * This decorator adds the event emission at the beginning of the method.
 * @param {string} event The event name
 */
(cc: any).emit = (event: string) => {
  const emitDecorator = (target, key, descriptor) => {
    const method = descriptor.value

    descriptor.value = function () {
      trigger(this.el, event, arguments[0])

      return method.apply(this, arguments)
    }
  }

  return emitDecorator
}

(cc: any).emit.last = (event: string) => (target: Object, key: string, descriptor: Object) => {
  const method = descriptor.value

  descriptor.value = function () {
    const result = method.apply(this, arguments)

    const emit = x => trigger(this.el, event, x)

    if (result && result.then) {
      result.then(emit)
    } else {
      emit(result)
    }

    return result
  }
}

/**
 * Replaces the getter with the function which accesses the class-component of the given name.
 * @param {string} name The class component name
 * @param {string} [selector] The selector to access class component dom. Optional. Default is '.[name]'.
 * @param {object} target The prototype of the target class
 * @param {string} key The name of the property
 * @param {object} descriptor The property descriptor
 */
const wireByNameAndSelector = (name: string, selector?: string) => (target: Object, key: string, descriptor: Object) => {
  selector = selector || '.' + name

  descriptor.get = function () {
    return this.$el.filter(selector).add(selector, this.el).cc.get(name)
  }
}

/**
 * Wires the class component of the name of the key to the property of the same name.
 */
(cc: any).wire = (target: Object, key: string, descriptor: Object) => {
  if (typeof target === 'string') {
    // If target is a tring, then we suppose this is called as @wire(componentName, selector) and therefore
    // we need to return the following expression (it works as another decorator).
    return wireByNameAndSelector(target, key)
  }

  wireByNameAndSelector(camelToKebab(key))(target, key, descriptor)
}

/**
 * The decorator for class component registration.
 *
 * if `name` is function, then use it as class itself and the component name is kebabized version of its name.
 * @param name The class name or the implementation class itself
 * @return The decorator if the class name is given, undefined if the implementation class is given
 */
(cc: any).component = (name: string | Function): ?Function => {
  if (typeof name !== 'function') {
    return Cls => cc((name: any), Cls)
  }

  return cc(camelToKebab(name.name), name)
}
<|endoftext|>


<commit_before>const fs = require('fs');

const dirExists = (directory) => {
  return new Promise((resolve, reject) => {
    fs.stat(directory, function(err, stats) {
      if (err) {
        if (err.errno === 34) {
          // Directory does not exist.
          resolve(false);
        } else {
          // Some other error occurred.
          reject(err);
        }
      } else {
        // Directory exists.
        resolve(true);
      }
    });
  });
};

module.exports = dirExists;
<commit_msg>Use err.code ENOENT to check for existence<commit_after>const fs = require('fs');

const dirExists = (directory) => {
  return new Promise((resolve, reject) => {
    fs.stat(directory, function(err, stats) {
      if (err) {
        if (err.code === 'ENOENT') {
          // Directory does not exist.
          resolve(false);
        } else {
          // Some other error occurred.
          reject(err);
        }
      } else {
        // Directory exists.
        resolve(true);
      }
    });
  });
};

module.exports = dirExists;
<|endoftext|>


<commit_before>import $ from 'jquery'

import { selectionchange } from './feature-detection'
import * as clipboard from './clipboard'
import eventable from './eventable'
import SelectionWatcher from './selection-watcher'
import * as config from './config'
import Keyboard from './keyboard'

// This will be set to true once we detect the input event is working.
// Input event description on MDN:
// https://developer.mozilla.org/en-US/docs/Web/Reference/Events/input
var isInputEventSupported = false

/**
 * The Dispatcher module is responsible for dealing with events and their handlers.
 *
 * @module core
 * @submodule dispatcher
 */
export default class Dispatcher {

  constructor (editable) {
    const win = editable.win
    eventable(this, editable)
    this.supportsInputEvent = false
    this.$document = $(win.document)
    this.config = editable.config
    this.editable = editable
    this.editableSelector = editable.editableSelector
    this.selectionWatcher = new SelectionWatcher(this, win)
    this.keyboard = new Keyboard(this.selectionWatcher)
    this.setup()
  }

  /**
  * Sets up all events that Editable.JS is catching.
  *
  * @method setup
  */
  setup () {
    // setup all events listeners and keyboard handlers
    this.setupKeyboardEvents()
    this.setupEventListeners()
  }

  unload () {
    this.off()
    this.$document.off('.editable')
  }

  suspend () {
    if (this.suspended) return
    this.suspended = true
    this.$document.off('.editable')
  }

  continue () {
    if (!this.suspended) return
    this.suspended = false
    this.setupEventListeners()
  }

  setupEventListeners () {
    this.setupElementListeners()
    this.setupKeydownListener()

    if (selectionchange) {
      this.setupSelectionChangeListeners()
    } else {
      this.setupSelectionChangeFallbackListeners()
    }
  }

  /**
  * Sets up events that are triggered on modifying an element.
  *
  * @method setupElementListeners
  */
  setupElementListeners () {
    const self = this
    const selector = this.editableSelector

    this.$document
      .on('focus.editable', selector, function (event) {
        if (this.getAttribute(config.pastingAttribute)) return
        self.selectionWatcher.syncSelection()
        self.notify('focus', this)
      })

      .on('blur.editable', selector, function (event) {
        if (this.getAttribute(config.pastingAttribute)) return
        self.notify('blur', this)
      })

      .on('copy.editable', selector, function (event) {
        const selection = self.selectionWatcher.getFreshSelection()
        if (selection.isSelection) {
          self.notify('clipboard', this, 'copy', selection)
        }
      })

      .on('cut.editable', selector, function (event) {
        const selection = self.selectionWatcher.getFreshSelection()
        if (selection.isSelection) {
          self.notify('clipboard', this, 'cut', selection)
          self.triggerChangeEvent(this)
        }
      })

      .on('paste.editable', selector, function (event) {
        const element = this

        function afterPaste (blocks, cursor) {
          if (blocks.length) {
            self.notify('paste', element, blocks, cursor)

            // The input event does not fire when we process the content manually
            // and insert it via script
            self.notify('change', element)
          } else {
            cursor.setVisibleSelection()
          }
        }

        const cursor = self.selectionWatcher.getFreshSelection()
        clipboard.paste(this, cursor, afterPaste)
      })

      .on('input.editable', selector, function (event) {
        if (isInputEventSupported) {
          self.notify('change', this)
        } else {
          // Most likely the event was already handled manually by
          // triggerChangeEvent so the first time we just switch the
          // isInputEventSupported flag without notifiying the change event.
          isInputEventSupported = true
        }
      })

      .on('formatEditable.editable', selector, function (event) {
        self.notify('change', this)
      })
  }

  /**
  * Trigger a change event
  *
  * This should be done in these cases:
  * - typing a letter
  * - delete (backspace and delete keys)
  * - cut
  * - paste
  * - copy and paste (not easily possible manually as far as I know)
  *
  * Preferrably this is done using the input event. But the input event is not
  * supported on all browsers for contenteditable elements.
  * To make things worse it is not detectable either. So instead of detecting
  * we set 'isInputEventSupported' when the input event fires the first time.
  */
  triggerChangeEvent (target) {
    if (isInputEventSupported) return
    this.notify('change', target)
  }

  dispatchSwitchEvent (event, element, direction) {
    if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return

    const cursor = this.selectionWatcher.getSelection()
    if (!cursor || cursor.isSelection) return
    // Detect if the browser moved the cursor in the next tick.
    // If the cursor stays at its position, fire the switch event.
    setTimeout(() => {
      var newCursor = this.selectionWatcher.forceCursor()
      if (newCursor.equals(cursor)) {
        event.preventDefault()
        event.stopPropagation()
        this.notify('switch', element, direction, newCursor)
      }
    }, 0)
  }

  /**
  * Sets up listener for keydown event which forwards events to
  * the Keyboard instance.
  *
  * @method setupKeydownListener
  */
  setupKeydownListener () {
    const self = this

    this.$document.on('keydown.editable', this.editableSelector, function (event) {
      const notifyCharacterEvent = !isInputEventSupported
      self.keyboard.dispatchKeyEvent(event, this, notifyCharacterEvent)
    })
  }

  /**
  * Sets up handlers for the keyboard events.
  * Keyboard definitions are in {{#crossLink "Keyboard"}}{{/crossLink}}.
  *
  * @method setupKeyboardEvents
  */
  setupKeyboardEvents () {
    const self = this

    this.keyboard
      .on('left up', function (event) {
        self.dispatchSwitchEvent(event, this, 'before')
      })

      .on('right down', function (event) {
        self.dispatchSwitchEvent(event, this, 'after')
      })

      .on('tab shiftTab esc', () => {})

      .on('backspace', function (event) {
        const range = self.selectionWatcher.getFreshRange()
        if (!range.isCursor) return self.triggerChangeEvent(this)

        const cursor = range.getCursor()
        if (!cursor.isAtBeginning()) return self.triggerChangeEvent(this)

        event.preventDefault()
        event.stopPropagation()
        self.notify('merge', this, 'before', cursor)
      })

      .on('delete', function (event) {
        const range = self.selectionWatcher.getFreshRange()
        if (!range.isCursor) return self.triggerChangeEvent(this)

        const cursor = range.getCursor()
        if (!cursor.isAtTextEnd()) return self.triggerChangeEvent(this)

        event.preventDefault()
        event.stopPropagation()
        self.notify('merge', this, 'after', cursor)
      })

      .on('enter', function (event) {
        event.preventDefault()
        event.stopPropagation()
        const range = self.selectionWatcher.getFreshRange()
        const cursor = range.forceCursor()

        if (cursor.isAtTextEnd()) {
          self.notify('insert', this, 'after', cursor)
        } else if (cursor.isAtBeginning()) {
          self.notify('insert', this, 'before', cursor)
        } else {
          self.notify('split', this, cursor.before(), cursor.after(), cursor)
        }
      })

      .on('shiftEnter', function (event) {
        event.preventDefault()
        event.stopPropagation()
        const cursor = self.selectionWatcher.forceCursor()
        self.notify('newline', this, cursor)
      })

      .on('character', function (event) {
        self.notify('change', this)
      })
  }

  /**
  * Sets up events that are triggered on a selection change.
  *
  * @method setupSelectionChangeListeners
  * @param {HTMLElement} $document: The document element.
  * @param {Function} notifier: The callback to be triggered when the event is caught.
  */
  setupSelectionChangeListeners () {
    let selectionDirty = false
    let suppressSelectionChanges = false
    const $document = this.$document
    const selectionWatcher = this.selectionWatcher

    // fires on mousemove (thats probably a bit too much)
    // catches changes like 'select all' from context menu
    $document.on('selectionchange.editable', (event) => {
      if (suppressSelectionChanges) {
        selectionDirty = true
      } else {
        selectionWatcher.selectionChanged()
      }
    })

    // listen for selection changes by mouse so we can
    // suppress the selectionchange event and only fire the
    // change event on mouseup
    $document.on('mousedown.editable', this.editableSelector, (event) => {
      if (this.config.mouseMoveSelectionChanges === false) {
        suppressSelectionChanges = true

        // Without this timeout the previous selection is active
        // until the mouseup event (no. not good).
        setTimeout($.proxy(selectionWatcher, 'selectionChanged'), 0)
      }

      $document.on('mouseup.editableSelection', (event) => {
        $document.off('.editableSelection')
        suppressSelectionChanges = false

        if (selectionDirty) {
          selectionDirty = false
          selectionWatcher.selectionChanged()
        }
      })
    })
  }

  /**
  * Fallback solution to support selection change events on browsers that don't
  * support selectionChange.
  *
  * @method setupSelectionChangeFallbackListeners
  */
  setupSelectionChangeFallbackListeners () {
    const $document = this.$document
    const selectionWatcher = this.selectionWatcher

    // listen for selection changes by mouse
    $document.on('mouseup.editable', (event) => {
      // In Opera when clicking outside of a block
      // it does not update the selection as it should
      // without the timeout
      setTimeout($.proxy(selectionWatcher, 'selectionChanged'), 0)
    })

    // listen for selection changes by keys
    $document.on('keyup.editable', this.editableSelector, (event) => {
      // when pressing Command + Shift + Left for example the keyup is only triggered
      // after at least two keys are released. Strange. The culprit seems to be the
      // Command key. Do we need a workaround?
      selectionWatcher.selectionChanged()
    })
  }
}
<commit_msg>fix(keyboard): trigger switch event again<commit_after>import $ from 'jquery'

import { selectionchange } from './feature-detection'
import * as clipboard from './clipboard'
import eventable from './eventable'
import SelectionWatcher from './selection-watcher'
import * as config from './config'
import Keyboard from './keyboard'

// This will be set to true once we detect the input event is working.
// Input event description on MDN:
// https://developer.mozilla.org/en-US/docs/Web/Reference/Events/input
var isInputEventSupported = false

/**
 * The Dispatcher module is responsible for dealing with events and their handlers.
 *
 * @module core
 * @submodule dispatcher
 */
export default class Dispatcher {

  constructor (editable) {
    const win = editable.win
    eventable(this, editable)
    this.supportsInputEvent = false
    this.$document = $(win.document)
    this.config = editable.config
    this.editable = editable
    this.editableSelector = editable.editableSelector
    this.selectionWatcher = new SelectionWatcher(this, win)
    this.keyboard = new Keyboard(this.selectionWatcher)
    this.setup()
  }

  /**
  * Sets up all events that Editable.JS is catching.
  *
  * @method setup
  */
  setup () {
    // setup all events listeners and keyboard handlers
    this.setupKeyboardEvents()
    this.setupEventListeners()
  }

  unload () {
    this.off()
    this.$document.off('.editable')
  }

  suspend () {
    if (this.suspended) return
    this.suspended = true
    this.$document.off('.editable')
  }

  continue () {
    if (!this.suspended) return
    this.suspended = false
    this.setupEventListeners()
  }

  setupEventListeners () {
    this.setupElementListeners()
    this.setupKeydownListener()

    if (selectionchange) {
      this.setupSelectionChangeListeners()
    } else {
      this.setupSelectionChangeFallbackListeners()
    }
  }

  /**
  * Sets up events that are triggered on modifying an element.
  *
  * @method setupElementListeners
  */
  setupElementListeners () {
    const self = this
    const selector = this.editableSelector

    this.$document
      .on('focus.editable', selector, function (event) {
        if (this.getAttribute(config.pastingAttribute)) return
        self.selectionWatcher.syncSelection()
        self.notify('focus', this)
      })

      .on('blur.editable', selector, function (event) {
        if (this.getAttribute(config.pastingAttribute)) return
        self.notify('blur', this)
      })

      .on('copy.editable', selector, function (event) {
        const selection = self.selectionWatcher.getFreshSelection()
        if (selection.isSelection) {
          self.notify('clipboard', this, 'copy', selection)
        }
      })

      .on('cut.editable', selector, function (event) {
        const selection = self.selectionWatcher.getFreshSelection()
        if (selection.isSelection) {
          self.notify('clipboard', this, 'cut', selection)
          self.triggerChangeEvent(this)
        }
      })

      .on('paste.editable', selector, function (event) {
        const element = this

        function afterPaste (blocks, cursor) {
          if (blocks.length) {
            self.notify('paste', element, blocks, cursor)

            // The input event does not fire when we process the content manually
            // and insert it via script
            self.notify('change', element)
          } else {
            cursor.setVisibleSelection()
          }
        }

        const cursor = self.selectionWatcher.getFreshSelection()
        clipboard.paste(this, cursor, afterPaste)
      })

      .on('input.editable', selector, function (event) {
        if (isInputEventSupported) {
          self.notify('change', this)
        } else {
          // Most likely the event was already handled manually by
          // triggerChangeEvent so the first time we just switch the
          // isInputEventSupported flag without notifiying the change event.
          isInputEventSupported = true
        }
      })

      .on('formatEditable.editable', selector, function (event) {
        self.notify('change', this)
      })
  }

  /**
  * Trigger a change event
  *
  * This should be done in these cases:
  * - typing a letter
  * - delete (backspace and delete keys)
  * - cut
  * - paste
  * - copy and paste (not easily possible manually as far as I know)
  *
  * Preferrably this is done using the input event. But the input event is not
  * supported on all browsers for contenteditable elements.
  * To make things worse it is not detectable either. So instead of detecting
  * we set 'isInputEventSupported' when the input event fires the first time.
  */
  triggerChangeEvent (target) {
    if (isInputEventSupported) return
    this.notify('change', target)
  }

  dispatchSwitchEvent (event, element, direction) {
    if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return

    const cursor = this.selectionWatcher.getSelection()
    if (!cursor || cursor.isSelection) return
    // Detect if the browser moved the cursor in the next tick.
    // If the cursor stays at its position, fire the switch event.
    setTimeout(() => {
      var newCursor = this.selectionWatcher.forceCursor()
      if (newCursor.equals(cursor)) {
        this.notify('switch', element, direction, newCursor)
      }
    })
  }

  /**
  * Sets up listener for keydown event which forwards events to
  * the Keyboard instance.
  *
  * @method setupKeydownListener
  */
  setupKeydownListener () {
    const self = this

    this.$document.on('keydown.editable', this.editableSelector, function (event) {
      const notifyCharacterEvent = !isInputEventSupported
      self.keyboard.dispatchKeyEvent(event, this, notifyCharacterEvent)
    })
  }

  /**
  * Sets up handlers for the keyboard events.
  * Keyboard definitions are in {{#crossLink "Keyboard"}}{{/crossLink}}.
  *
  * @method setupKeyboardEvents
  */
  setupKeyboardEvents () {
    const self = this

    this.keyboard
      .on('up', function (event) {
        self.dispatchSwitchEvent(event, this, 'before')
      })

      .on('left', function (event) {
        self.dispatchSwitchEvent(event, this, 'before')
      })

      .on('right', function (event) {
        self.dispatchSwitchEvent(event, this, 'after')
      })

      .on('down', function (event) {
        self.dispatchSwitchEvent(event, this, 'after')
      })

      .on('backspace', function (event) {
        const range = self.selectionWatcher.getFreshRange()
        if (!range.isCursor) return self.triggerChangeEvent(this)

        const cursor = range.getCursor()
        if (!cursor.isAtBeginning()) return self.triggerChangeEvent(this)

        event.preventDefault()
        event.stopPropagation()
        self.notify('merge', this, 'before', cursor)
      })

      .on('delete', function (event) {
        const range = self.selectionWatcher.getFreshRange()
        if (!range.isCursor) return self.triggerChangeEvent(this)

        const cursor = range.getCursor()
        if (!cursor.isAtTextEnd()) return self.triggerChangeEvent(this)

        event.preventDefault()
        event.stopPropagation()
        self.notify('merge', this, 'after', cursor)
      })

      .on('enter', function (event) {
        event.preventDefault()
        event.stopPropagation()
        const range = self.selectionWatcher.getFreshRange()
        const cursor = range.forceCursor()

        if (cursor.isAtTextEnd()) {
          self.notify('insert', this, 'after', cursor)
        } else if (cursor.isAtBeginning()) {
          self.notify('insert', this, 'before', cursor)
        } else {
          self.notify('split', this, cursor.before(), cursor.after(), cursor)
        }
      })

      .on('shiftEnter', function (event) {
        event.preventDefault()
        event.stopPropagation()
        const cursor = self.selectionWatcher.forceCursor()
        self.notify('newline', this, cursor)
      })

      .on('character', function (event) {
        self.notify('change', this)
      })
  }

  /**
  * Sets up events that are triggered on a selection change.
  *
  * @method setupSelectionChangeListeners
  * @param {HTMLElement} $document: The document element.
  * @param {Function} notifier: The callback to be triggered when the event is caught.
  */
  setupSelectionChangeListeners () {
    let selectionDirty = false
    let suppressSelectionChanges = false
    const $document = this.$document
    const selectionWatcher = this.selectionWatcher

    // fires on mousemove (thats probably a bit too much)
    // catches changes like 'select all' from context menu
    $document.on('selectionchange.editable', (event) => {
      if (suppressSelectionChanges) {
        selectionDirty = true
      } else {
        selectionWatcher.selectionChanged()
      }
    })

    // listen for selection changes by mouse so we can
    // suppress the selectionchange event and only fire the
    // change event on mouseup
    $document.on('mousedown.editable', this.editableSelector, (event) => {
      if (this.config.mouseMoveSelectionChanges === false) {
        suppressSelectionChanges = true

        // Without this timeout the previous selection is active
        // until the mouseup event (no. not good).
        setTimeout($.proxy(selectionWatcher, 'selectionChanged'), 0)
      }

      $document.on('mouseup.editableSelection', (event) => {
        $document.off('.editableSelection')
        suppressSelectionChanges = false

        if (selectionDirty) {
          selectionDirty = false
          selectionWatcher.selectionChanged()
        }
      })
    })
  }

  /**
  * Fallback solution to support selection change events on browsers that don't
  * support selectionChange.
  *
  * @method setupSelectionChangeFallbackListeners
  */
  setupSelectionChangeFallbackListeners () {
    const $document = this.$document
    const selectionWatcher = this.selectionWatcher

    // listen for selection changes by mouse
    $document.on('mouseup.editable', (event) => {
      // In Opera when clicking outside of a block
      // it does not update the selection as it should
      // without the timeout
      setTimeout($.proxy(selectionWatcher, 'selectionChanged'), 0)
    })

    // listen for selection changes by keys
    $document.on('keyup.editable', this.editableSelector, (event) => {
      // when pressing Command + Shift + Left for example the keyup is only triggered
      // after at least two keys are released. Strange. The culprit seems to be the
      // Command key. Do we need a workaround?
      selectionWatcher.selectionChanged()
    })
  }
}
<|endoftext|>


<commit_before>define(function (require) {

    var Text;

    Text = function (parentMC,resourceManager,charId,ObjectId,placeAfter,transform,bounds) {

        var instance = this,
            parentEl = parentMC.el;

        this.create = function () {
            var j,
                k,
                transformArray,
                transformMat;

            instance.el = parentMC.el.g();
            instance.id = ObjectId;
            instance.el.attr({'class': 'text', 'token': instance.id});

            instance.children = [];
            instance.isMask = false;
            instance.isMasked = false;
            instance.mask = null;
            instance.maskTill = null;

            //console.log(resourceManager.m_data.DOMDocument.Text);

            for (j = 0; j < resourceManager.m_data.DOMDocument.Text.length; j++)
            {
                if (resourceManager.m_data.DOMDocument.Text[j].charid == charId)
                {
                    instance.addText(resourceManager.m_data.DOMDocument.Text[j]);
                }
            }

            transformArray = transform.split(",");
			transformMat = new Snap.Matrix(transformArray[0],transformArray[1],transformArray[2],transformArray[3],transformArray[4],transformArray[5]);
			instance.el.transform(transformMat);

            if (placeAfter && parseInt(placeAfter) !== 0) {
                afterMC = parentMC.getChildById(parseInt(placeAfter));
                afterMC.el.before(instance.el);
            } else {
                parentEl.add(instance.el);
            }
        };

        this.addText = function (data) {
            //console.log(data);

            var text,
                fontSize,
                fontName,
                fontColor,
                textAlign,
                textAnchor,
                textBounds;

            if (bounds) {
                textBounds = bounds.split(',');
            } else {
                textBounds = [0, 0, 200, 100];
            }

            console.log(textBounds);

            textAlign = data.paras[0].alignment;
            fontSize = data.paras[0].textRun[0].style.fontSize;
            fontName = data.paras[0].textRun[0].style.fontName;
            fontColor = data.paras[0].textRun[0].style.fontColor;
            letterSpacing = data.paras[0].textRun[0].style.letterSpacing;

            if (textAlign == 'left') {
                textAnchor = 'start';
            } else if (textAlign == 'center') {
                textAnchor = 'middle';
            } else if (textAlign == 'right') {
                textAnchor = 'end';
            }

            text = instance.el.text(0, 0, data.txt);
            text.attr({
                'text-anchor': textAnchor,
                'alignment-baseline': 'baseline',
                'font-family': fontName,
                'font-size': fontSize,
                'letter-spacing': letterSpacing,
                'fill': fontColor
            });

            bbox = text.getBBox();

            y = parseFloat(textBounds[1]) + (parseFloat(textBounds[3]) / 2);

            text.attr({
                //'y': (bbox.height / 2) - parseFloat(textBounds[1])
                'y': y
            });

            console.log((bbox.height / 2), parseFloat(textBounds[1]), (bbox.height / 2) - parseFloat(textBounds[1]));
        };

        this.create();
    };

	return Text;
});

/*
CreateText: function (root, s,resourceManager,charId,ObjectId,placeAfter,transform)
		{
			var textContainer = s.g();
			textContainer.attr({token: parseInt(ObjectId)});

			for(var b =0;b<resourceManager.m_data.DOMDocument.Text.length;b++)
			{
				if(resourceManager.m_data.DOMDocument.Text[b].charid == charId)
				{
					var displayString = resourceManager.m_data.DOMDocument.Text[b].txt;
					var txt = displayString.replace(/\\r/g,"\r");
					var fontFamily = resourceManager.m_data.DOMDocument.Text[b].paras[0].textRun[0].style.fontName;
					var fontStyle = resourceManager.m_data.DOMDocument.Text[b].paras[0].textRun[0].style.fontStyle;
					var fontSize = resourceManager.m_data.DOMDocument.Text[b].paras[0].textRun[0].style.fontSize;
					var fontColor = resourceManager.m_data.DOMDocument.Text[b].paras[0].textRun[0].style.fontColor;
					var textOutput = s.text(0, 0, txt);
					textOutput.attr({
						fill: fontColor,
						fontFamily: fontFamily,
						fontSize: fontSize,
						fontStyle: fontStyle
					});

					textContainer.add(textOutput);
				}
			}

			var transformArray = transform.split(",");
			var TransformMat = new Snap.Matrix(transformArray[0],transformArray[1],transformArray[2],transformArray[3],transformArray[4],transformArray[5]);
			textContainer.transform(TransformMat);

			if(s != undefined)
			{
				if(placeAfter != 0)
				{
					children = s.selectAll('[token="' + placeAfter + '"]');
					for (i = 0; i < children.length; i += 1) {
						if (children[i].parent().id == s.id) { //ensure child of current movie clip
							children[i].before(textContainer);
							break;
						}
					}
				}
				else
				{
					s.add(textContainer);
				}

			}
		}

	}
*/
<commit_msg>text inside textbox<commit_after>define(function (require) {

    var Text;

    Text = function (parentMC,resourceManager,charId,ObjectId,placeAfter,transform,bounds) {

        var instance = this,
            parentEl = parentMC.el;

        this.create = function () {
            var j,
                k,
                transformArray,
                transformMat;

            instance.el = parentMC.el.g();
            instance.id = ObjectId;
            instance.el.attr({'class': 'text', 'token': instance.id});

            instance.children = [];
            instance.isMask = false;
            instance.isMasked = false;
            instance.mask = null;
            instance.maskTill = null;

            for (j = 0; j < resourceManager.m_data.DOMDocument.Text.length; j++)
            {
                if (resourceManager.m_data.DOMDocument.Text[j].charid == charId)
                {
                    instance.addText(resourceManager.m_data.DOMDocument.Text[j]);
                }
            }

            transformArray = transform.split(",");
			transformMat = new Snap.Matrix(transformArray[0],transformArray[1],transformArray[2],transformArray[3],transformArray[4],transformArray[5]);
			instance.el.transform(transformMat);

            if (placeAfter && parseInt(placeAfter) !== 0) {
                afterMC = parentMC.getChildById(parseInt(placeAfter));
                afterMC.el.before(instance.el);
            } else {
                parentEl.add(instance.el);
            }
        };

        this.addText = function (data) {

            var text,
                bbox,
                textBox,
                textX,
                textY,
                fontSize,
                fontName,
                fontColor,
                textAlign,
                textAnchor,
                textIndent,
                textBounds;

            textBox = instance.el.g();

            if (bounds) {
                textBounds = bounds.split(',');
            } else {
                textBounds = [0, 0, 200, 100];
            }

            textAlign = data.paras[0].alignment;
            fontSize = data.paras[0].textRun[0].style.fontSize;
            fontName = data.paras[0].textRun[0].style.fontName;
            fontColor = data.paras[0].textRun[0].style.fontColor;
            letterSpacing = data.paras[0].textRun[0].style.letterSpacing;

            if (textAlign == 'left') {
                textAnchor = 'start';
            } else if (textAlign == 'center') {
                textAnchor = 'middle';
            } else if (textAlign == 'right') {
                textAnchor = 'end';
            }

            text = textBox.text(0, 0, data.txt);
            text.attr({
                'text-anchor': textAnchor,
                'alignment-baseline': 'baseline',
                'font-family': fontName,
                'font-size': fontSize,
                'letter-spacing': letterSpacing,
                'fill': fontColor
            });

            bbox = text.getBBox();
            textX = parseFloat(textBounds[0]) + (parseFloat(textBounds[2]) / 2) - bbox.cx;
            textY = parseFloat(textBounds[1]) + (parseFloat(textBounds[3]) / 2) - bbox.cy;

            textBox.transform('translate(' + textX + ',' + textY + ')');
        };

        this.create();
    };

	return Text;
});
<|endoftext|>


<commit_before>/**
 * @param {string} code
 */
module.exports.JSEvaluator = function(code){
		try {
			eval(code);
		} catch (SyntaxError) {
			//todo
		}
}

module.exports.PythonEvaluator = class{

	/**
	 * starts pythonEvaluator.py
	 */
	constructor(){
		this.PythonShell = require('python-shell');

		let rootPath = process.cwd();
		if(rootPath.endsWith("arepl-win32-x64")){
		  rootPath = rootPath + '/resources/app';
		}

		this.pythonEvalFilePath = rootPath + '/src/python/';

		// for non-windows OS it is best to use python3 instead of python
		// Mac and Ubuntu both have python being v2 by default
		// archlinux and freebsd both use v3 as default, but also provide python3 command
		this.pythonPath = process.platform != "win32" ? "python3" : "python";

		this.resultHandler = require("./pythonResultHandler");
		this.results = this.resultHandler.results;

		this.startPython();
	}

	/**
	 * @param {string} code
	 */
	execCode(code){
		this.pyshell.send(JSON.stringify(code));
	}

	/**
	 * @param {string} message
	 */
	sendStdin(message){
		this.pyshell.send(message);
	}

	/**
	 * kills python process and restarts.  Force-kills if necessary.
	 */
	restart(){

		var restarting = false;

		// register callback for restart
		// using childProcess callback instead of pyshell callback
		// (pyshell callback only happens when process exits voluntarily)
		this.pyshell.childProcess.on('exit',()=>{
			restarting = true;
			this.startPython();
		});

		// pyshell has 50 ms to die gracefully
		var dead = this.pyshell.childProcess.kill();
		if(!dead) console.info("pyshell refused to die")

		setTimeout(()=>{
			if(!dead && !restarting){
				// murder the process with extreme prejudice
				dead = this.pyshell.childProcess.kill('SIGKILL');
				if(!dead){
					console.error("the python process simply cannot be killed!")
				}
			}
		}, 50);
	}

	startPython(){
		console.log("Starting Python...")
		this.pyshell = new this.PythonShell('pythonEvaluator.py', {
			scriptPath: this.pythonEvalFilePath,
			pythonPath: this.pythonPath,
		});
		this.pyshell.on('message', message => {
			console.debug(message);
			this.resultHandler.handleResult(message);
		});
	}
}<commit_msg>fixed incorrect type hint<commit_after>/**
 * @param {string} code
 */
module.exports.JSEvaluator = function(code){
		try {
			eval(code);
		} catch (SyntaxError) {
			//todo
		}
}

module.exports.PythonEvaluator = class{

	/**
	 * starts pythonEvaluator.py
	 */
	constructor(){
		this.PythonShell = require('python-shell');

		let rootPath = process.cwd();
		if(rootPath.endsWith("arepl-win32-x64")){
		  rootPath = rootPath + '/resources/app';
		}

		this.pythonEvalFilePath = rootPath + '/src/python/';

		// for non-windows OS it is best to use python3 instead of python
		// Mac and Ubuntu both have python being v2 by default
		// archlinux and freebsd both use v3 as default, but also provide python3 command
		this.pythonPath = process.platform != "win32" ? "python3" : "python";

		this.resultHandler = require("./pythonResultHandler");
		this.results = this.resultHandler.results;

		this.startPython();
	}

	/**
	 * @param {{evalCode:string}} code
	 */
	execCode(code){
		this.pyshell.send(JSON.stringify(code));
	}

	/**
	 * @param {string} message
	 */
	sendStdin(message){
		this.pyshell.send(message);
	}

	/**
	 * kills python process and restarts.  Force-kills if necessary.
	 */
	restart(){

		var restarting = false;

		// register callback for restart
		// using childProcess callback instead of pyshell callback
		// (pyshell callback only happens when process exits voluntarily)
		this.pyshell.childProcess.on('exit',()=>{
			restarting = true;
			this.startPython();
		});

		// pyshell has 50 ms to die gracefully
		var dead = this.pyshell.childProcess.kill();
		if(!dead) console.info("pyshell refused to die")

		setTimeout(()=>{
			if(!dead && !restarting){
				// murder the process with extreme prejudice
				dead = this.pyshell.childProcess.kill('SIGKILL');
				if(!dead){
					console.error("the python process simply cannot be killed!")
				}
			}
		}, 50);
	}

	startPython(){
		console.log("Starting Python...")
		this.pyshell = new this.PythonShell('pythonEvaluator.py', {
			scriptPath: this.pythonEvalFilePath,
			pythonPath: this.pythonPath,
		});
		this.pyshell.on('message', message => {
			console.debug(message);
			this.resultHandler.handleResult(message);
		});
	}
}<|endoftext|>


<commit_before>/**
 * module  event/live
 * migrate from mootools 1.4.1
 */
KM.define(function(K){

function quickParse(selector) {
	var quick = REGEX_MATCH_SIMPLE_SELECTOR.exec(selector);
	if ( quick ) {
		//   0  1    2   3
		// [ _, tag, id, class ]
		quick[1] = (quick[1] || '').toLowerCase();
		quick[3] = quick[3] && new RegExp( '(?:^|\\s)' + quick[3] + '(?:\\s|$)' );
	}
	return quick;
};

function quickMatch(elem, m){
	var attrs = elem.attributes || {};
	return (
		(!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
		(!m[2] || (attrs.id || {}).value === m[2]) &&
		(!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
	);
};

function selectorEngineMatch(element){
	return SELECTOR.match(element, _match);
};

function getStorage(element, key){
	var storage = element.data(key);

	if(!storage){
		storage = {};
		element.data(key, storage);
	}

	return storage;
};

function getSpecialEventConfiguration(type, host){
		// @type {Object} special delegate configurations for a certain type
	var special_delegate = special[type] || {},

		// @type {Object} special event configuration declared by Neuron core
		special_event = Events[type] || {};

	K.mix(host, {
		base		: special_delegate.base || special_event.base || type,
		listen		: special_delegate.listen,
		condition	: special_event.condition,
		capture		: special_delegate.capture
	});

	return host;
};

/**
 * @this {DOMElement}
 * @param {}
 */
function dispatch(event, type){
	var self = this,
		element = $(self),
		storage = getStorage(element, DATA_KEY),
		config = storage[type];

	if (event.button && type === 'click' || !config || !config.length){
		return;
	}

	event.base = event.type;
	event.type = type;

	var matcher,
		cur,
		i, len, cfg,
		condition = config.condition;

	for(cur = event.target; cur && cur !== self; cur = cur.parentNode){
		for(i = 0, len = config.length; i < len; i ++ ){
			cfg = config[i];

			if(
				// check if the element matches the selector
				// if the selector is simple selector, we use quickMatch
				// otherwise, use CSS Selector Engine instead
				(cfg.quick ? quickMatch(cur, cfg.quick) : SELECTOR.match(cur, cfg.selector) ) &&

				(!condition || condition.call(cur, event))
			){
				cfg.fn.call(cur, event);
			}
		}
	}
};

var

DATA_KEY = '_nr-delegate',

// from jQuery
REGEX_MATCH_SIMPLE_SELECTOR = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,

DOM = K.DOM,

SELECTOR = DOM.SELECTOR,

Events = DOM.Events,

is_eventListener_supported = !!window.addEventListener,

special = {
	mouseenter: {
		base: 'mouseover'
	},

	mouseleave: {
		base: 'mouseout'
	},

	// ref: Focus Event Types
	// http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-focusevent
	focus: {
		base: 'focus' + (is_eventListener_supported ? '' : 'in'),

		// ref:
		// useCapture (addEventListener)
		// http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
		capture: true
	},

	blur: {
		base: is_eventListener_supported ? 'blur' : 'focusout',
		capture: true
	}
};

var delegate = {

	on: function(element, type, selector, fn){

		// @type {KM.DOM}
		element = $(element);

		var storage = getStorage(element, DATA_KEY),
			config = storage[type];

		if (!config){

			storage[type] = config = [];
			getSpecialEventConfiguration(type, config);

			config.handle = function(event){
				// @this
				dispatch.call(this, event, type);
			};

			// delegate a certain event type only once
			element.on(config.base, config.handle, config.capture);
		}

		config.push({
			selector: selector,
			fn: fn,
			quick: quickParse(selector)
		});

		// free
		element = config = null;
	},

	off: function(element, type, selector, fn){
		// @type {KM.DOM}
		element = $(element);

		var storage = getStorage(element, DATA_KEY),
			config = storage[type],
			i = 0,
			len,
			cfg;

		if(!config){
			return;
		}

		for(len = config.length; i < len; i ++){
			cfg = config[i];

			if(!cfg || cfg.selector === selector && cfg.fn === fn){
				config.splice(i, 1);
			}
		}

		if(!config.length){
			element.off(config.base, config.handle);
		}
	}

};

return delegate;

});
<commit_msg>event/live: add annotations<commit_after>/**
 * module  event/live
 * migrate from mootools 1.4.1
 */
KM.define(function(K){

/**
 * @param {string} selector
 * @return {Array} parsed selector
 */
function quickParse(selector) {
	var quick = REGEX_MATCH_SIMPLE_SELECTOR.exec(selector);
	if ( quick ) {
		//   0  1    2   3
		// [ _, tag, id, class ]
		quick[1] = (quick[1] || '').toLowerCase();
		quick[3] = quick[3] && new RegExp( '(?:^|\\s)' + quick[3] + '(?:\\s|$)' );
	}
	return quick;
};

/**
 * the match method of CSS Selector Engine is inefficient
 * on most conditions, namely when the selector discribed with tagName, className or id,
 * we could match the selector very fast

 * @param {DOMElement} elem
 * @param {Array} m return value of quickParse
 * @return {boolean}
 */
function quickMatch(elem, m){
	var attrs = elem.attributes || {};
	return (
		(!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
		(!m[2] || (attrs.id || {}).value === m[2]) &&
		(!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
	);
};

function selectorEngineMatch(element){
	return SELECTOR.match(element, _match);
};

function getStorage(element, key){
	var storage = element.data(key);

	if(!storage){
		storage = {};
		element.data(key, storage);
	}

	return storage;
};

function getSpecialEventConfiguration(type, host){
		// @type {Object} special delegate configurations for a certain type
	var special_delegate = special[type] || {},

		// @type {Object} special event configuration declared by Neuron core
		special_event = Events[type] || {};

	K.mix(host, {
		base		: special_delegate.base || special_event.base || type,
		listen		: special_delegate.listen,
		condition	: special_event.condition,
		capture		: special_delegate.capture
	});

	return host;
};

/**
 * @this {DOMElement}
 * @param {}
 */
function dispatch(event, type){
	var self = this,
		element = $(self),
		storage = getStorage(element, DATA_KEY),
		config = storage[type];

	if (event.button && type === 'click' || !config || !config.length){
		return;
	}

	event.base = event.type;
	event.type = type;

	var matcher,
		cur,
		i, len, cfg,
		condition = config.condition;

	for(cur = event.target; cur && cur !== self; cur = cur.parentNode){
		for(i = 0, len = config.length; i < len; i ++ ){
			cfg = config[i];

			if(
				// check if the element matches the selector
				// if the selector is simple selector, we use quickMatch
				// otherwise, use CSS Selector Engine instead
				(cfg.quick ? quickMatch(cur, cfg.quick) : SELECTOR.match(cur, cfg.selector) ) &&

				(!condition || condition.call(cur, event))
			){
				cfg.fn.call(cur, event);
			}
		}
	}
};

var

DATA_KEY = '_nr-delegate',

// from jQuery
REGEX_MATCH_SIMPLE_SELECTOR = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,

DOM = K.DOM,

SELECTOR = DOM.SELECTOR,

Events = DOM.Events,

is_eventListener_supported = !!window.addEventListener,

special = {
	mouseenter: {
		base: 'mouseover'
	},

	mouseleave: {
		base: 'mouseout'
	},

	// ref: Focus Event Types
	// http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-focusevent
	focus: {
		base: 'focus' + (is_eventListener_supported ? '' : 'in'),

		// ref:
		// useCapture (addEventListener)
		// http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
		capture: true
	},

	blur: {
		base: is_eventListener_supported ? 'blur' : 'focusout',
		capture: true
	}
};

var delegate = {

	on: function(element, type, selector, fn){

		// @type {KM.DOM}
		element = $(element);

		var storage = getStorage(element, DATA_KEY),
			config = storage[type];

		if (!config){

			storage[type] = config = [];
			getSpecialEventConfiguration(type, config);

			config.handle = function(event){
				// @this
				dispatch.call(this, event, type);
			};

			// delegate a certain event type only once
			element.on(config.base, config.handle, config.capture);
		}

		config.push({
			selector: selector,
			fn: fn,
			quick: quickParse(selector)
		});

		// free
		element = config = null;
	},

	off: function(element, type, selector, fn){
		// @type {KM.DOM}
		element = $(element);

		var storage = getStorage(element, DATA_KEY),
			config = storage[type],
			i = 0,
			len,
			cfg;

		if(!config){
			return;
		}

		for(len = config.length; i < len; i ++){
			cfg = config[i];

			if(!cfg || cfg.selector === selector && cfg.fn === fn){
				config.splice(i, 1);
			}
		}

		if(!config.length){
			element.off(config.base, config.handle);
		}
	}

};

return delegate;

});
<|endoftext|>


<commit_before>$(document).ready(function(){
	$.urlParam = function(name){
	    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(decodeURIComponent(window.location.href));
	    if (results==null){
	       return null;
	    }
	    else{
	       return results[1] || 0;
	    }
	}
	/*
	 * Defaults to Active Page
	 * Can be Manually Called if Page is a Subset of the current page (e.g. view.php)
	 */
	function setActiveOption(e){
		var page;
		if(typeof(e) === "undefined"){
			pageInfo = $(location).attr("href").split('/');
			page = pageInfo.slice(-1)[0];
			folder = (pageInfo.pop() == '') ? pageInfo[pageInfo.length - 1] : pageInfo.pop();
			page = folder + "-" + page.replace(".php", "");
		}else
			page = e;
		$("#sidenav_" + page).addClass("active");
	}
	setActiveOption();
});<commit_msg>Fix jQuery for selecting active tab<commit_after>$(document).ready(function(){
	$.urlParam = function(name){
	    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(decodeURIComponent(window.location.href));
	    if (results==null){
	       return null;
	    }
	    else{
	       return results[1] || 0;
	    }
	}
	function getPageName(url) {
	    var index = url.lastIndexOf("/") + 1;
	    var filenameWithExtension = url.substr(index);
	    var filename = filenameWithExtension.split(".")[0];
	    return filename;
	}
	/*
	 * Defaults to Active Page
	 * Can be Manually Called if Page is a Subset of the current page (e.g. view.php)
	 */
	function setActiveOption(e){
		var page;
		var currentURL = $(location).attr("href");
		if(typeof(e) === "undefined"){
			page = getPageName(currentURL);
			pageInfo = currentURL.split('/');
			folder = (pageInfo.pop() == '') ? pageInfo[pageInfo.length - 1] : pageInfo.pop();
			page = folder + "-" + page;
		}else
			page = e;
		$("#sidenav_" + page).addClass("active");
	}
	setActiveOption();
});<|endoftext|>