<commit_before>cls.ReplService = function(view, data)
{
  if (cls.ReplService.instance)
  {
    return cls.ReplService.instance;
  }
  cls.ReplService.instance = this;

  this._on_consolelog = function(msg)
  {
    var rt_id = msg[0];
    var type = msg[1];
    /**
     * This value indicates which function was called:
     *
     * 1 - console.log
     * 2 - console.debug
     * 3 - console.info
     * 4 - console.warn
     * 5 - console.error
     * 6 - console.assert
     * 7 - console.dir
     * 8 - console.dirxml
     * 9 - console.group
     * 10 - console.groupCollapsed
     * 11 - console.groupEnded
     * 12 - console.count
     */

    switch(type)
    {
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
        this._handle_log(msg, rt_id);
        break;
      case 7:
        this._handle_dir(msg, rt_id);
        break;
      case 8:
        this._handle_dirxml(msg, rt_id);
        break;
      case 9:
        this._handle_group(msg);
        break;
      case 10:
        this._handle_group(msg, "collapsed");
        break;
      case 11:
        this._handle_groupend(msg);
        break;
    }
  };

  this._on_consoletime = function(msg)
  {
    const TITLE = 1;
    this._data.add_output_str("Started: " + msg[TITLE]);
  };

  this._on_consoletimeend = function(msg)
  {
    const TITLE = 1, DURATION = 2;
    var dur = msg[DURATION];
    var ms = Math.round(dur / 1000);
    this._data.add_output_str(msg[TITLE] + ": " + ms + "ms (" + dur + "µsec)" );
  };

  this._on_consoleprofile = function(msg)
  {
    this._data.add_output_str("console.profile called. Profiling is not yet supported.");
  };

  this._on_consoleprofileend = function(msg)
  {
    this._data.add_output_str("console.profileEnd called. Profiling is not yet supported.");
  };

  this._on_consoletrace = function(data)
  {
    var message = new cls.EcmascriptDebugger["6.0"].ConsoleTraceInfo(data);

    for (var n=0, frame; frame = message.frameList[n]; n++)
    {
      var script = window.runtimes.getScript(frame.scriptID);
      if (!script) { continue; };
      frame.script_type = script.script_type;
      frame.uri = script.uri;
    }

    this._data.add_output_trace(message);
  };

  this._handle_log = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST]);
    this._data.add_output_valuelist(rt_id, values);
  };

  this._handle_group = function(msg, collapsed)
  {
    this._data.add_output_groupstart({name: msg[2][0][0], collapsed: Boolean(collapsed)});
  };

  this._handle_groupend = function(msg)
  {
    this._data.add_output_groupend();
  };

  this._parse_value = function(value, rt_id)
  {
      var ret = {
        type: value[0] === null ? "object" : "native"
      };

      if (ret.type == "object") {
        var object = value[1];
        ret.obj_id = object[0];
        ret.type = object[2];
        ret.name = object[4] || object[5];
        ret.rt_id = rt_id;
      }
      else
      {
        ret.value = value[0];
      }
      return ret;
  };

  this._parse_value_list = function(valuelist, rt_id)
  {
    var pv = this._parse_value;
    var fun = function(v) { return pv(v, rt_id); }; // partial invocation wrapping rt_id
    return valuelist.map(fun);
  };

  this._handle_dirxml = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iele(rt_id, e.obj_id, e.name);
    }
  };

  this._handle_dir = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iobj(rt_id, e.obj_id, e.name);
    }
  };

  this._on_eval_done = function(status, msg, rt_id, thread_id, frame_id)
  {
    const STATUS = 0, TYPE = 1;

    if (msg[STATUS] == "unhandled-exception")
    {
      this._handle_exception(msg, rt_id);
    }
    else if (msg[TYPE] == "object")
    {
      this._handle_object(msg, rt_id);
    }
    else
    {
      this._handle_native(msg);
    }
  };

  this._on_element_selected = function(msg)
  {
    this._prev_selected = this._cur_selected;
    this._cur_selected = msg.obj_id;
  };

  this._handle_exception = function(msg, rt_id)
  {
    const VALUE = 2;
    this._get_exception_info(rt_id, msg[3][0]);
  };

  this._handle_object = function(msg, rt_id)
  {
    const TYPE = 1, OBJVALUE = 3;
    const OBJID = 0, CLASS = 4; FUNCTION = 5;

    var obj = msg[OBJVALUE];
    this._data.add_output_pobj(rt_id, obj[OBJID], obj[FUNCTION] || obj[CLASS]);
  };

  this._handle_native = function(msg)
  {
    const VALUE = 2;
    const TYPE = 1;
    var type = msg[TYPE];
    var val = msg[VALUE];

    switch(type)
    {
      case "null":
      case "undefined":
        val = type;
        break;
      case "string":
        val = '"' + val + '"';
        break;
    }

    this._data.add_output_str(val);
  };

  this._get_exception_info = function(rt, obj)
  {
    var tag = this._tagman.set_callback(this, this._on_get_exception_info.bind(this));
    this._service.requestExamineObjects(tag, [rt, [obj], 0, 0, 1]);
  };

  this._on_get_exception_info = function(status, msg)
  {
    var props = {};
    var propslist = msg[0][0][0][0][1];
    for (var n=0, e; e=propslist[n]; n++)
    {
      props[e[0]] = e[2];
    }

    this._data.add_output_exception(props.message, props.stacktrace);
  };

  this.handle_input = function(input)
  {
    this._data.add_input(input);
    this._evaluate_input(input);
  }.bind(this);

  this._evaluate_input = function(input)
  {
    var rt_id = runtimes.getSelectedRuntimeId();
    var thread = window.stop_at.getThreadId();
    var frame = window.stop_at.getSelectedFrameIndex();
    if (frame == -1)
    {
      thread = 0;
      frame = 0;
    }

    var cooked = this._transformer.transform(input);
    var tag = this._tagman.set_callback(this, this._on_eval_done.bind(this), [rt_id, thread, frame]);
    var magicvars = [];
    if (this._cur_selected) {
      magicvars.push(["$0", this._cur_selected]);
    }
    if (this._prev_selected) {
      magicvars.push(["$1", this._prev_selected]);
    }
    this._service.requestEval(tag, [rt_id, thread, frame, cooked, magicvars]);
  };

  this.init = function(view, data)
  {
    this._view = view;
    this._data = data;
    this._cur_selected = null;
    this._prev_selected = null;
    this._transformer = new cls.HostCommandTransformer();
    this._tagman = window.tagManager; //TagManager.getInstance(); <- fixme: use singleton
    this._service = window.services['ecmascript-debugger'];
    this._service.addListener("consolelog", this._on_consolelog.bind(this));
    this._service.addListener("consoletime", this._on_consoletime.bind(this));
    this._service.addListener("consoletimeend", this._on_consoletimeend.bind(this));
    this._service.addListener("consoleprofile", this._on_consoleprofile.bind(this));
    this._service.addListener("consoleprofileend", this._on_consoleprofileend.bind(this));
    this._service.addListener("consoletrace", this._on_consoletrace.bind(this));
    window.messages.addListener("element-selected", this._on_element_selected.bind(this));
  };

  this.init(view, data);
};
<commit_msg>Deal with syntax error better<commit_after>cls.ReplService = function(view, data)
{
  if (cls.ReplService.instance)
  {
    return cls.ReplService.instance;
  }
  cls.ReplService.instance = this;

  this._on_consolelog = function(msg)
  {
    var rt_id = msg[0];
    var type = msg[1];
    /**
     * This value indicates which function was called:
     *
     * 1 - console.log
     * 2 - console.debug
     * 3 - console.info
     * 4 - console.warn
     * 5 - console.error
     * 6 - console.assert
     * 7 - console.dir
     * 8 - console.dirxml
     * 9 - console.group
     * 10 - console.groupCollapsed
     * 11 - console.groupEnded
     * 12 - console.count
     */

    switch(type)
    {
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
        this._handle_log(msg, rt_id);
        break;
      case 7:
        this._handle_dir(msg, rt_id);
        break;
      case 8:
        this._handle_dirxml(msg, rt_id);
        break;
      case 9:
        this._handle_group(msg);
        break;
      case 10:
        this._handle_group(msg, "collapsed");
        break;
      case 11:
        this._handle_groupend(msg);
        break;
    }
  };

  this._on_consoletime = function(msg)
  {
    const TITLE = 1;
    this._data.add_output_str("Started: " + msg[TITLE]);
  };

  this._on_consoletimeend = function(msg)
  {
    const TITLE = 1, DURATION = 2;
    var dur = msg[DURATION];
    var ms = Math.round(dur / 1000);
    this._data.add_output_str(msg[TITLE] + ": " + ms + "ms (" + dur + "µsec)" );
  };

  this._on_consoleprofile = function(msg)
  {
    this._data.add_output_str("console.profile called. Profiling is not yet supported.");
  };

  this._on_consoleprofileend = function(msg)
  {
    this._data.add_output_str("console.profileEnd called. Profiling is not yet supported.");
  };

  this._on_consoletrace = function(data)
  {
    var message = new cls.EcmascriptDebugger["6.0"].ConsoleTraceInfo(data);

    for (var n=0, frame; frame = message.frameList[n]; n++)
    {
      var script = window.runtimes.getScript(frame.scriptID);
      if (!script) { continue; };
      frame.script_type = script.script_type;
      frame.uri = script.uri;
    }

    this._data.add_output_trace(message);
  };

  this._handle_log = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST]);
    this._data.add_output_valuelist(rt_id, values);
  };

  this._handle_group = function(msg, collapsed)
  {
    this._data.add_output_groupstart({name: msg[2][0][0], collapsed: Boolean(collapsed)});
  };

  this._handle_groupend = function(msg)
  {
    this._data.add_output_groupend();
  };

  this._parse_value = function(value, rt_id)
  {
      var ret = {
        type: value[0] === null ? "object" : "native"
      };

      if (ret.type == "object") {
        var object = value[1];
        ret.obj_id = object[0];
        ret.type = object[2];
        ret.name = object[4] || object[5];
        ret.rt_id = rt_id;
      }
      else
      {
        ret.value = value[0];
      }
      return ret;
  };

  this._parse_value_list = function(valuelist, rt_id)
  {
    var pv = this._parse_value;
    var fun = function(v) { return pv(v, rt_id); }; // partial invocation wrapping rt_id
    return valuelist.map(fun);
  };

  this._handle_dirxml = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iele(rt_id, e.obj_id, e.name);
    }
  };

  this._handle_dir = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iobj(rt_id, e.obj_id, e.name);
    }
  };

  this._on_eval_done = function(status, msg, rt_id, thread_id, frame_id)
  {
    const STATUS = 0, TYPE = 1;

    if (status == 4)
    {
      this._handle_raw(msg[0]);
    }
    else if (msg[STATUS] == "unhandled-exception")
    {
      this._handle_exception(msg, rt_id);
    }
    else if (msg[TYPE] == "object")
    {
      this._handle_object(msg, rt_id);
    }
    else
    {
      this._handle_native(msg);
    }
  };

  this._on_element_selected = function(msg)
  {
    this._prev_selected = this._cur_selected;
    this._cur_selected = msg.obj_id;
  };

  this._handle_exception = function(msg, rt_id)
  {
    const VALUE = 2;
    this._get_exception_info(rt_id, msg[3][0]);
  };

  this._handle_object = function(msg, rt_id)
  {
    const TYPE = 1, OBJVALUE = 3;
    const OBJID = 0, CLASS = 4; FUNCTION = 5;

    var obj = msg[OBJVALUE];
    this._data.add_output_pobj(rt_id, obj[OBJID], obj[FUNCTION] || obj[CLASS]);
  };

  this._handle_native = function(msg)
  {
    const VALUE = 2;
    const TYPE = 1;
    var type = msg[TYPE];
    var val = msg[VALUE];

    switch(type)
    {
      case "null":
      case "undefined":
        val = type;
        break;
      case "string":
        val = '"' + val + '"';
        break;
    }

    this._data.add_output_str(val);
  };

  this._handle_raw = function(val)
  {
    this._data.add_output_str(val);
  };

  this._get_exception_info = function(rt, obj)
  {
    var tag = this._tagman.set_callback(this, this._on_get_exception_info.bind(this));
    this._service.requestExamineObjects(tag, [rt, [obj], 0, 0, 1]);
  };

  this._on_get_exception_info = function(status, msg)
  {
    var props = {};
    var propslist = msg[0][0][0][0][1];
    for (var n=0, e; e=propslist[n]; n++)
    {
      props[e[0]] = e[2];
    }

    this._data.add_output_exception(props.message, props.stacktrace);
  };

  this.handle_input = function(input)
  {
    this._data.add_input(input);
    this._evaluate_input(input);
  }.bind(this);

  this._evaluate_input = function(input)
  {
    var rt_id = runtimes.getSelectedRuntimeId();
    var thread = window.stop_at.getThreadId();
    var frame = window.stop_at.getSelectedFrameIndex();
    if (frame == -1)
    {
      thread = 0;
      frame = 0;
    }

    var cooked = this._transformer.transform(input);
    var tag = this._tagman.set_callback(this, this._on_eval_done.bind(this), [rt_id, thread, frame]);
    var magicvars = [];
    if (this._cur_selected) {
      magicvars.push(["$0", this._cur_selected]);
    }
    if (this._prev_selected) {
      magicvars.push(["$1", this._prev_selected]);
    }
    this._service.requestEval(tag, [rt_id, thread, frame, cooked, magicvars]);
  };

  this.init = function(view, data)
  {
    this._view = view;
    this._data = data;
    this._cur_selected = null;
    this._prev_selected = null;
    this._transformer = new cls.HostCommandTransformer();
    this._tagman = window.tagManager; //TagManager.getInstance(); <- fixme: use singleton
    this._service = window.services['ecmascript-debugger'];
    this._service.addListener("consolelog", this._on_consolelog.bind(this));
    this._service.addListener("consoletime", this._on_consoletime.bind(this));
    this._service.addListener("consoletimeend", this._on_consoletimeend.bind(this));
    this._service.addListener("consoleprofile", this._on_consoleprofile.bind(this));
    this._service.addListener("consoleprofileend", this._on_consoleprofileend.bind(this));
    this._service.addListener("consoletrace", this._on_consoletrace.bind(this));
    window.messages.addListener("element-selected", this._on_element_selected.bind(this));
  };

  this.init(view, data);
};
<|endoftext|>


<commit_before>import test from 'ava'
import { getTexts, addLanguages } from './../lib/getTranslations'

test('addLanguages(): should return a empty objets if languages is a empty array', t => {
  let languages = []
  let result = addLanguages(languages)
  t.deepEqual({}, result)
})

test('addLanguages(): should return a objet with two properties', t => {
  let languages = ['es', 'en']
  let result = addLanguages(languages)
  t.is(Object.keys(result).length, 2)
})

test('addLanguages(): should return a object with "es" and "de" properties', t => {
  let languages = ['de', 'es']
  let result = addLanguages(languages)
  t.deepEqual({ es: "", "de": "" }, result)
})

test('getTexts(): should return a empty object if texts array is empty', t => {
  let texts = []
  let result = getTexts(texts, [])
  t.deepEqual(result, {})
})

test('getTexts(): should return a object with two properties', t => {
  let texts = [
    '<Translate>Jack Sparrow is the best!</Translate>',
    '<Translate>Where is my compass?</Translate>'
  ]
  let languages = ['es', 'en']
  let result = getTexts(texts, languages)
  t.is(Object.keys(result).length, 2)
})

test('getTexts(): should return a object with translations', t => {
  let texts = [
    '<Translate>Jack Sparrow is the best!</Translate>',
    '<Translate>Where is my compass?</Translate>'
  ]
  let result = getTexts(texts, [])
  t.deepEqual({
    'Jack Sparrow is the best!': {},
    'Where is my compass?': {}
  }, result)
})
<commit_msg>Tests<commit_after>import test from 'ava'
import { getTexts, addLanguages } from './../lib/getTranslations'

test('addLanguages(): should return a empty objets if languages is a empty array', t => {
  let languages = []
  let result = addLanguages(languages)
  t.deepEqual({}, result)
})

test('addLanguages(): should return a objet with two properties', t => {
  let languages = ['es', 'en']
  let result = addLanguages(languages)
  t.is(Object.keys(result).length, 2)
})

test('addLanguages(): should return a object with "es" and "de" properties', t => {
  let languages = ['de', 'es']
  let result = addLanguages(languages)
  t.deepEqual({ es: "", "de": "" }, result)
})

test('getTexts(): should return a empty object if texts array is empty', t => {
  let texts = []
  let result = getTexts(texts, [])
  t.deepEqual(result, {})
})

test('getTexts(): should return a object with two properties', t => {
  let texts = [
    '<Translate>Jack Sparrow is the best!</Translate>',
    '<Translate>Where is my compass?</Translate>'
  ]
  let languages = ['es', 'en']
  let result = getTexts(texts, languages)
  t.is(Object.keys(result).length, 2)
})

test('getTexts(): should return a object with equals translations', t => {
  let texts = [
    '<Translate>Jack Sparrow is the best!</Translate>',
    '<Translate>Where is my compass?</Translate>'
  ]
  let result = getTexts(texts, [])
  t.deepEqual({
    'Jack Sparrow is the best!': {},
    'Where is my compass?': {}
  }, result)
})
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    errorHandler = require('./errors.server.controller'),
    Article = mongoose.model('Article'),
    _ = require('lodash');

/**
 * Create a article
 */
exports.update = function (req, res) {
    console.log(req.body);
    var today_start = new Date();
    today_start.setHours(0, 0, 0, 0);
    var today_end = new Date();
    today_end.setHours(23, 59, 59, 999);

    Article.update({
        'date': {
            '$gte': today_start,
            '$lt': today_end
        },
        'user': req.user
    }, {
        $set: {
            text: req.body.text,
            date: today_start
        }
    }, {
        upsert: true
    }, function () {});

    Article.find({
        'date': {
            '$gte': today_start,
            '$lt': today_end
        },
        'user': req.user
    }, function (err, articles) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(articles[0]);
        }
    });

};

/**
 * Show the current article
 */
exports.read = function (req, res) {

    var today_start = new Date();
    today_start.setHours(0, 0, 0, 0);
    var today_end = new Date();
    today_end.setHours(23, 59, 59, 999);

    Article.find({
        'date': {
            '$gte': today_start,
            '$lt': today_end
        },
        user: req.user._id
    }, function (err, articles) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            console.log(articles);
            res.json(articles[0]);
        }
    });

};

/**
 * Article middleware
 */
exports.articleByID = function (req, res, next, id) {
    Article.findById(id).populate('user', 'displayName').exec(function (err, article) {
        if (err) return next(err);
        if (!article) return next(new Error('Failed to load article ' + id));
        req.article = article;
        next();
    });
};

/**
 * Article authorization middleware
 */
exports.hasAuthorization = function (req, res, next) {
    if (req.article.user.id !== req.user.id) {
        return res.status(403).send({
            message: 'User is not authorized'
        });
    }
    next();
};<commit_msg>little comments<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    errorHandler = require('./errors.server.controller'),
    Article = mongoose.model('Article'),
    _ = require('lodash');

/**
 * Create a article
 */
exports.update = function (req, res) {
    console.log(req.body);
    var today_start = new Date();
    today_start.setHours(0, 0, 0, 0);
    var today_end = new Date();
    today_end.setHours(23, 59, 59, 999);

    Article.update({
        'date': {
            '$gte': today_start,
            '$lt': today_end
        },
        'user': req.user
    }, {
        $set: {
            text: req.body.text,
            date: today_start
        }
    }, {
        upsert: true
    }, function () {});

    Article.find({
        'date': {
            '$gte': today_start,
            '$lt': today_end
        },
        'user': req.user
    }, function (err, articles) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(articles[0]);
        }
    });

};

/**
 * Show the current article
 */
exports.read = function (req, res) {

    //
//    db.articles.find()({
//        _id: {
//            $lt: new ObjectId(Math.floor((new Date()).getTime() / 1000).toString(16) + '0000000000000000')
//        }
//    })

    var today_start = new Date();
    today_start.setHours(0, 0, 0, 0);
    var today_end = new Date();
    today_end.setHours(23, 59, 59, 999);

    Article.find({
        'date': {
            '$gte': today_start,
            '$lt': today_end
        },
        user: req.user._id
    }, function (err, articles) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            console.log(articles);
            res.json(articles[0]);
        }
    });

};

/**
 * Article middleware
 */
exports.articleByID = function (req, res, next, id) {
    Article.findById(id).populate('user', 'displayName').exec(function (err, article) {
        if (err) return next(err);
        if (!article) return next(new Error('Failed to load article ' + id));
        req.article = article;
        next();
    });
};

/**
 * Article authorization middleware
 */
exports.hasAuthorization = function (req, res, next) {
    if (req.article.user.id !== req.user.id) {
        return res.status(403).send({
            message: 'User is not authorized'
        });
    }
    next();
};<|endoftext|>


<commit_before>cls.ReplService = function(view, data)
{
  if (cls.ReplService.instance)
  {
    return cls.ReplService.instance;
  }
  cls.ReplService.instance = this;

  this._on_consolelog = function(msg)
  {
    var rt_id = msg[0];
    var type = msg[1];
    /**
     * This value indicates which function was called:
     *
     * 1 - console.log
     * 2 - console.debug
     * 3 - console.info
     * 4 - console.warn
     * 5 - console.error
     * 6 - console.assert
     * 7 - console.dir
     * 8 - console.dirxml
     * 9 - console.group
     * 10 - console.groupCollapsed
     * 11 - console.groupEnded
     * 12 - console.count
     */

    switch(type)
    {
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
        this._handle_log(msg, rt_id);
        break;
      case 7:
        this._handle_dir(msg, rt_id);
        break;
      case 8:
        this._handle_dirxml(msg, rt_id);
        break;
      case 9:
        this._handle_group(msg);
        break;
      case 10:
        this._handle_group(msg, "collapsed");
        break;
      case 11:
        this._handle_groupend(msg);
        break;
    }
  };

  this._on_consoletime = function(msg)
  {
    const TITLE = 1;
    this._data.add_output_str("Started: " + msg[TITLE]);
  };

  this._on_consoletimeend = function(msg)
  {
    const TITLE = 1, DURATION = 2;
    var dur = msg[DURATION];
    var ms = Math.round(dur / 1000);
    this._data.add_output_str(msg[TITLE] + ": " + ms + "ms (" + dur + "µsec)" );
  };

  this._on_consoleprofile = function(msg)
  {
    this._data.add_output_str("console.profile called. Profiling is not yet supported.");
  };

  this._on_consoleprofileend = function(msg)
  {
    this._data.add_output_str("console.profileEnd called. Profiling is not yet supported.");
  };

  this._on_consoletrace = function(data)
  {
    var message = new cls.EcmascriptDebugger["6.0"].ConsoleTraceInfo(data);

    for (var n=0, frame; frame = message.frameList[n]; n++)
    {
      var script = window.runtimes.getScript(frame.scriptID);
      if (!script) { continue; };
      frame.script_type = script.script_type;
      frame.uri = script.uri;
    }

    this._data.add_output_trace(message);
  };

  this._handle_log = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST]);
    this._data.add_output_valuelist(rt_id, values);
  };

  this._handle_group = function(msg, collapsed)
  {
    this._data.add_output_groupstart({name: msg[2][0][0], collapsed: Boolean(collapsed)});
  };

  this._handle_groupend = function(msg)
  {
    this._data.add_output_groupend();
  };

  this._parse_value = function(value, rt_id)
  {
      var ret = {
        type: value[0] === null ? "object" : "native"
      };

      if (ret.type == "object") {
        var object = value[1];
        ret.obj_id = object[0];
        ret.type = object[2];
        ret.name = object[4] || object[5];
        ret.rt_id = rt_id;
      }
      else
      {
        ret.value = value[0];
      }
      return ret;
  };

  this._parse_value_list = function(valuelist, rt_id)
  {
    var pv = this._parse_value;
    var fun = function(v) { return pv(v, rt_id); }; // partial invocation wrapping rt_id
    return valuelist.map(fun);
  };

  this._handle_dirxml = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iele(rt_id, e.obj_id, e.name);
    }
  };

  this._handle_dir = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iobj(rt_id, e.obj_id, e.name);
    }
  };

  this._on_eval_done = function(status, msg, rt_id, thread_id, frame_id)
  {
    const STATUS = 0, TYPE = 1;

    if (msg[STATUS] == "unhandled-exception")
    {
      this._handle_exception(msg, rt_id);
    }
    else if (msg[TYPE] == "object")
    {
      this._handle_object(msg, rt_id);
    }
    else
    {
      this._handle_native(msg);
    }
  };

  this._on_element_selected = function(msg)
  {
    this._prev_selected = this._cur_selected;
    this._cur_selected = msg.obj_id;
  };

  this._handle_exception = function(msg, rt_id)
  {
    const VALUE = 2;
    this._get_exception_info(rt_id, msg[3][0]);
  };

  this._handle_object = function(msg, rt_id)
  {
    const TYPE = 1, OBJVALUE = 3;
    const OBJID = 0, CLASS = 4; FUNCTION = 5;

    var obj = msg[OBJVALUE];
    this._data.add_output_pobj(rt_id, obj[OBJID], obj[FUNCTION] || obj[CLASS]);
  };

  this._handle_native = function(msg)
  {
    const VALUE = 2;
    const TYPE = 1;
    var type = msg[TYPE];
    var val = msg[VALUE];

    switch(type)
    {
      case "null":
      case "undefined":
        val = type;
        break;
      case "string":
        val = '"' + val + '"';
        break;
    }

    this._data.add_output_str(val);
  };

  this._get_exception_info = function(rt, obj)
  {
    var tag = this._tagman.set_callback(this, this._on_get_exception_info.bind(this));
    this._service.requestExamineObjects(tag, [rt, [obj], 0, 0, 1]);
  };

  this._on_get_exception_info = function(status, msg)
  {
    var props = {};
    var propslist = msg[0][0][0][0][1];
    for (var n=0, e; e=propslist[n]; n++)
    {
      props[e[0]] = e[2];
    }

    this._data.add_output_exception(props.message, props.stacktrace);
  };

  this.handle_input = function(input)
  {
    this._data.add_input(input);
    this._evaluate_input(input);
  }.bind(this);

  this._evaluate_input = function(input)
  {
    var rt_id = runtimes.getSelectedRuntimeId();
    var thread = window.stop_at.getThreadId();
    var frame = window.stop_at.getSelectedFrameIndex();
    if (frame == -1)
    {
      thread = 0;
      frame = 0;
    }

    var cooked = this._transformer.transform(input);
    var tag = this._tagman.set_callback(this, this._on_eval_done.bind(this), [rt_id, thread, frame]);
    this._service.requestEval(tag, [rt_id, thread, frame, cooked]);
  };

  this.init = function(view, data)
  {
    this._view = view;
    this._data = data;
    this._cur_selected = null;
    this._prev_selected = null;
    this._transformer = new cls.HostCommandTransformer();
    this._tagman = window.tagManager; //TagManager.getInstance(); <- fixme: use singleton
    this._service = window.services['ecmascript-debugger'];
    this._service.addListener("consolelog", this._on_consolelog.bind(this));
    this._service.addListener("consoletime", this._on_consoletime.bind(this));
    this._service.addListener("consoletimeend", this._on_consoletimeend.bind(this));
    this._service.addListener("consoleprofile", this._on_consoleprofile.bind(this));
    this._service.addListener("consoleprofileend", this._on_consoleprofileend.bind(this));
    this._service.addListener("consoletrace", this._on_consoletrace.bind(this));
    window.messages.addListener("element-selected", this._on_element_selected.bind(this));
  };

  this.init(view, data);
};
<commit_msg>Made bash and  work<commit_after>cls.ReplService = function(view, data)
{
  if (cls.ReplService.instance)
  {
    return cls.ReplService.instance;
  }
  cls.ReplService.instance = this;

  this._on_consolelog = function(msg)
  {
    var rt_id = msg[0];
    var type = msg[1];
    /**
     * This value indicates which function was called:
     *
     * 1 - console.log
     * 2 - console.debug
     * 3 - console.info
     * 4 - console.warn
     * 5 - console.error
     * 6 - console.assert
     * 7 - console.dir
     * 8 - console.dirxml
     * 9 - console.group
     * 10 - console.groupCollapsed
     * 11 - console.groupEnded
     * 12 - console.count
     */

    switch(type)
    {
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
        this._handle_log(msg, rt_id);
        break;
      case 7:
        this._handle_dir(msg, rt_id);
        break;
      case 8:
        this._handle_dirxml(msg, rt_id);
        break;
      case 9:
        this._handle_group(msg);
        break;
      case 10:
        this._handle_group(msg, "collapsed");
        break;
      case 11:
        this._handle_groupend(msg);
        break;
    }
  };

  this._on_consoletime = function(msg)
  {
    const TITLE = 1;
    this._data.add_output_str("Started: " + msg[TITLE]);
  };

  this._on_consoletimeend = function(msg)
  {
    const TITLE = 1, DURATION = 2;
    var dur = msg[DURATION];
    var ms = Math.round(dur / 1000);
    this._data.add_output_str(msg[TITLE] + ": " + ms + "ms (" + dur + "µsec)" );
  };

  this._on_consoleprofile = function(msg)
  {
    this._data.add_output_str("console.profile called. Profiling is not yet supported.");
  };

  this._on_consoleprofileend = function(msg)
  {
    this._data.add_output_str("console.profileEnd called. Profiling is not yet supported.");
  };

  this._on_consoletrace = function(data)
  {
    var message = new cls.EcmascriptDebugger["6.0"].ConsoleTraceInfo(data);

    for (var n=0, frame; frame = message.frameList[n]; n++)
    {
      var script = window.runtimes.getScript(frame.scriptID);
      if (!script) { continue; };
      frame.script_type = script.script_type;
      frame.uri = script.uri;
    }

    this._data.add_output_trace(message);
  };

  this._handle_log = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST]);
    this._data.add_output_valuelist(rt_id, values);
  };

  this._handle_group = function(msg, collapsed)
  {
    this._data.add_output_groupstart({name: msg[2][0][0], collapsed: Boolean(collapsed)});
  };

  this._handle_groupend = function(msg)
  {
    this._data.add_output_groupend();
  };

  this._parse_value = function(value, rt_id)
  {
      var ret = {
        type: value[0] === null ? "object" : "native"
      };

      if (ret.type == "object") {
        var object = value[1];
        ret.obj_id = object[0];
        ret.type = object[2];
        ret.name = object[4] || object[5];
        ret.rt_id = rt_id;
      }
      else
      {
        ret.value = value[0];
      }
      return ret;
  };

  this._parse_value_list = function(valuelist, rt_id)
  {
    var pv = this._parse_value;
    var fun = function(v) { return pv(v, rt_id); }; // partial invocation wrapping rt_id
    return valuelist.map(fun);
  };

  this._handle_dirxml = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iele(rt_id, e.obj_id, e.name);
    }
  };

  this._handle_dir = function(msg, rt_id)
  {
    const VALUELIST = 2;
    var values = this._parse_value_list(msg[VALUELIST], rt_id);
    for (var n=0, e; e=values[n]; n++)
    {
      this._data.add_output_iobj(rt_id, e.obj_id, e.name);
    }
  };

  this._on_eval_done = function(status, msg, rt_id, thread_id, frame_id)
  {
    const STATUS = 0, TYPE = 1;

    if (msg[STATUS] == "unhandled-exception")
    {
      this._handle_exception(msg, rt_id);
    }
    else if (msg[TYPE] == "object")
    {
      this._handle_object(msg, rt_id);
    }
    else
    {
      this._handle_native(msg);
    }
  };

  this._on_element_selected = function(msg)
  {
    this._prev_selected = this._cur_selected;
    this._cur_selected = msg.obj_id;
  };

  this._handle_exception = function(msg, rt_id)
  {
    const VALUE = 2;
    this._get_exception_info(rt_id, msg[3][0]);
  };

  this._handle_object = function(msg, rt_id)
  {
    const TYPE = 1, OBJVALUE = 3;
    const OBJID = 0, CLASS = 4; FUNCTION = 5;

    var obj = msg[OBJVALUE];
    this._data.add_output_pobj(rt_id, obj[OBJID], obj[FUNCTION] || obj[CLASS]);
  };

  this._handle_native = function(msg)
  {
    const VALUE = 2;
    const TYPE = 1;
    var type = msg[TYPE];
    var val = msg[VALUE];

    switch(type)
    {
      case "null":
      case "undefined":
        val = type;
        break;
      case "string":
        val = '"' + val + '"';
        break;
    }

    this._data.add_output_str(val);
  };

  this._get_exception_info = function(rt, obj)
  {
    var tag = this._tagman.set_callback(this, this._on_get_exception_info.bind(this));
    this._service.requestExamineObjects(tag, [rt, [obj], 0, 0, 1]);
  };

  this._on_get_exception_info = function(status, msg)
  {
    var props = {};
    var propslist = msg[0][0][0][0][1];
    for (var n=0, e; e=propslist[n]; n++)
    {
      props[e[0]] = e[2];
    }

    this._data.add_output_exception(props.message, props.stacktrace);
  };

  this.handle_input = function(input)
  {
    this._data.add_input(input);
    this._evaluate_input(input);
  }.bind(this);

  this._evaluate_input = function(input)
  {
    var rt_id = runtimes.getSelectedRuntimeId();
    var thread = window.stop_at.getThreadId();
    var frame = window.stop_at.getSelectedFrameIndex();
    if (frame == -1)
    {
      thread = 0;
      frame = 0;
    }

    var cooked = this._transformer.transform(input);
    var tag = this._tagman.set_callback(this, this._on_eval_done.bind(this), [rt_id, thread, frame]);
    var magicvars = [];
    if (this._cur_selected) {
      magicvars.push(["$0", this._cur_selected]);
    }
    if (this._prev_selected) {
      magicvars.push(["$1", this._prev_selected]);
    }
    this._service.requestEval(tag, [rt_id, thread, frame, cooked, magicvars]);
  };

  this.init = function(view, data)
  {
    this._view = view;
    this._data = data;
    this._cur_selected = null;
    this._prev_selected = null;
    this._transformer = new cls.HostCommandTransformer();
    this._tagman = window.tagManager; //TagManager.getInstance(); <- fixme: use singleton
    this._service = window.services['ecmascript-debugger'];
    this._service.addListener("consolelog", this._on_consolelog.bind(this));
    this._service.addListener("consoletime", this._on_consoletime.bind(this));
    this._service.addListener("consoletimeend", this._on_consoletimeend.bind(this));
    this._service.addListener("consoleprofile", this._on_consoleprofile.bind(this));
    this._service.addListener("consoleprofileend", this._on_consoleprofileend.bind(this));
    this._service.addListener("consoletrace", this._on_consoletrace.bind(this));
    window.messages.addListener("element-selected", this._on_element_selected.bind(this));
  };

  this.init(view, data);
};
<|endoftext|>


<commit_before>import { createNewGroupModel, generateGroupName } from 'models/groupModel';
import should from 'should';
import assert from 'assert';

// describe('Array', function () {
//     describe('#BackendCreateNewGroupModelTests()', () => {
//         //Create a test group and verify its properties
//         var myId = 'Test Group ID';
//         var myDisplayName = 'Test Group Display Name';
//         var myDescription = 'This group is for unit tests';
//         var myAdmins = ['admin1', 'admin2'];
//         var myAdminsArray = [{ "id": "admin1", "type": "dns" }, { "id": "admin2", "type": "dns" }];

//         var mygroup = createNewGroupModel(myId, myDisplayName, myDescription, myAdmins);

//         it('New group should have an id', () => {
//             mygroup.data.should.have.property('id', myId);
//         });

//         it('New group should have a displayName', () => {
//             mygroup.data.should.have.property('displayName', myDisplayName);
//         });

//         it('New group should have a description', () => {
//             mygroup.data.should.have.property('description', myDescription);
//         });

//         it('New group should have an admins array', () => {
//             mygroup.data.should.have.property('admins', myAdminsArray);
//             mygroup.data.admins[0].should.have.property('id', myAdminsArray[0].id);
//             mygroup.data.admins[0].should.have.property('type', "dns");
//         });

//         it('New group admins arrary should have the right number of items', () => {
//             mygroup.data.should.have.property('admins').with.lengthOf(2);
//         });
//     });
// });
<commit_msg>remove broken test<commit_after>// import { createNewGroupModel, generateGroupName } from 'models/groupModel';
// import should from 'should';
// import assert from 'assert';

// describe('Array', function () {
//     describe('#BackendCreateNewGroupModelTests()', () => {
//         //Create a test group and verify its properties
//         var myId = 'Test Group ID';
//         var myDisplayName = 'Test Group Display Name';
//         var myDescription = 'This group is for unit tests';
//         var myAdmins = ['admin1', 'admin2'];
//         var myAdminsArray = [{ "id": "admin1", "type": "dns" }, { "id": "admin2", "type": "dns" }];

//         var mygroup = createNewGroupModel(myId, myDisplayName, myDescription, myAdmins);

//         it('New group should have an id', () => {
//             mygroup.data.should.have.property('id', myId);
//         });

//         it('New group should have a displayName', () => {
//             mygroup.data.should.have.property('displayName', myDisplayName);
//         });

//         it('New group should have a description', () => {
//             mygroup.data.should.have.property('description', myDescription);
//         });

//         it('New group should have an admins array', () => {
//             mygroup.data.should.have.property('admins', myAdminsArray);
//             mygroup.data.admins[0].should.have.property('id', myAdminsArray[0].id);
//             mygroup.data.admins[0].should.have.property('type', "dns");
//         });

//         it('New group admins arrary should have the right number of items', () => {
//             mygroup.data.should.have.property('admins').with.lengthOf(2);
//         });
//     });
// });
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import I18n from 'i18n!assignments_2_student_header_date_title'

import React from 'react'
import Heading from '@instructure/ui-elements/lib/components/Heading'
import Text from '@instructure/ui-elements/lib/components/Text'
import {bool} from 'prop-types'

import {StudentAssignmentShape} from '../assignmentData'
import FriendlyDatetime from '../../../shared/FriendlyDatetime'
import AvailabilityDates from '../../shared/AvailabilityDates'
import {TruncateText} from '@instructure/ui-elements'

function DateTitle(props) {
  const {assignment, isSticky} = props

  return (
    <React.Fragment>
      <Heading margin="0 small 0 0" level="h1" as="h2" data-test-id="title">
        {/* We put 100 here because using auto maxes out at one line and the input for the assignment name never exeeds 100 */}
        <TruncateText maxLines={isSticky ? 1 : 100} truncate="word" ellipsis="...">
          {assignment.name}
        </TruncateText>
      </Heading>
      {assignment.dueAt && (
        <Text size="large" data-test-id="due-date-display">
          <FriendlyDatetime
            data-test-id="due-date"
            prefix={I18n.t('Due:')}
            format={I18n.t('#date.formats.full_with_weekday')}
            dateTime={assignment.dueAt}
          />
        </Text>
      )}
      {!isSticky && (

          <Text size="small">
            <AvailabilityDates assignment={assignment} formatStyle="long" />
          </Text>

      )}
    </React.Fragment>
  )
}

DateTitle.propTypes = {
  assignment: StudentAssignmentShape,
  isSticky: bool.isRequired
}

export default React.memo(DateTitle)
<commit_msg>use break on character for header title to fix no show bug<commit_after>/*
 * Copyright (C) 2018 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import I18n from 'i18n!assignments_2_student_header_date_title'

import React from 'react'
import Heading from '@instructure/ui-elements/lib/components/Heading'
import Text from '@instructure/ui-elements/lib/components/Text'
import {bool} from 'prop-types'

import {StudentAssignmentShape} from '../assignmentData'
import FriendlyDatetime from '../../../shared/FriendlyDatetime'
import AvailabilityDates from '../../shared/AvailabilityDates'
import {TruncateText} from '@instructure/ui-elements'

function DateTitle(props) {
  const {assignment, isSticky} = props

  return (
    <React.Fragment>
      <Heading margin="0 small 0 0" level="h1" as="h2" data-test-id="title">
        {/* We put 100 here because using auto maxes out at one line and the input for the assignment name never exeeds 100 */}
        <TruncateText
          maxLines={isSticky ? 1 : 100}
          truncate={isSticky ? 'character' : 'word'}
          ellipsis="..."
        >
          {assignment.name}
        </TruncateText>
      </Heading>
      {assignment.dueAt && (
        <Text size="large" data-test-id="due-date-display">
          <FriendlyDatetime
            data-test-id="due-date"
            prefix={I18n.t('Due:')}
            format={I18n.t('#date.formats.full_with_weekday')}
            dateTime={assignment.dueAt}
          />
        </Text>
      )}
      {!isSticky && (

          <Text size="small">
            <AvailabilityDates assignment={assignment} formatStyle="long" />
          </Text>

      )}
    </React.Fragment>
  )
}

DateTitle.propTypes = {
  assignment: StudentAssignmentShape,
  isSticky: bool.isRequired
}

export default React.memo(DateTitle)
<|endoftext|>


<commit_before>if (typeof HexamemEngine === 'undefined'){
    HexamemEngine = function(){};
}

/**
 * Responsible for board interactions.
 * Attached to the playing board area.
 * If board components cannot be found, it throws an Error.
 *
 * @param {Number} size The expected size of the play area.
 * @version 0.3.1-20140401
 * @author Jason J.
 * @type HexamemEngine.prototype.PlayArea
 * @returns {HexamemEngine.prototype.PlayArea}
 * @throws {Error} If elements of the play area are not found.
 */
HexamemEngine.prototype.PlayArea = function(size){
    var BOARD_SIZE = size;
    /** @type Number The current flashing speed. Either 0, 1, 2, 3. 0 is slowest. */
    var FLASH_SPEED_INDEX_CLICK = 3;

    /** @type Element The underlay background/border of the game board. */
    var gameBorderUnderlay = document.getElementById('game-body-wrapper');
    if (!gameBorderUnderlay){
        throw new Error('Cannot find element with id: "game-body-wrapper"');
    }
    /** @type Element The middle button click area. */
    var middleButtonClickArea = document.getElementById('middle-button-area');
    /** @type Element The middle button display area. */
    var middleButtonDisplayArea = document.getElementById('middle-button');
    if (!middleButtonClickArea){
        throw new Error('Cannot find element with id: "middle-button-area"');
    }
    if (!middleButtonDisplayArea){
        throw new Error('Cannot find element with id: "middle-button"');
    }
    /** @type string The coords of the middle button to add and remove (and so enable/disable. */
    var middleButtonCoords = middleButtonClickArea.coords;
    middleButtonClickArea.removeAttribute('coords');

    /** @type Array|Function The list of functions for the middle button */
    var middleButtonFunctions = new Array();

    /** Replace STUB with number to get id. */
    var idClickAreaStub = 'button-area-STUB';
    /** Replace STUB with number to get id. */
    var idButtonDisplayStub = 'button-STUB-wrapper';

    /** @type Array|Element An aFLASH_SPEED_INDEX_CLICKrray of elements for the display area. */
    var buttonDisplayArea = new Array();
    /** @type Array|Element An array of elements for the clicking areas. */
    var buttonClickArea = new Array();

    /** @type Array|Function The list of functions to perform on click. */
    var flashButtonFunctions = new Array();

    /** @type Boolean whether or not the flash buttons are enabled. */
    var flashButtonsEnabled = true;

    /** @type Array|Number An array of numbers, indicated the position of a
     * button currently mid-click. */
    var flashButtonInPlay = new Array();

    /** @type Array|Number The flash interval between setting the animation and turning it off. */
    var flashInterval = [810, 610, 410, 210];
    /** @type Array|String The flash css for each speed. */
    var flashCssClass = ['flash-normal', 'flash-med-fast', 'flash-fast', 'flash-super-fast'];

    ////////////////////////////////////////////////////////////////////////////
    ////  End member initialization
    ////////////////////////////////////////////////////////////////////////////
    //set middle click listener.
    addAction(middleButtonClickArea, middleButtonActions);

    for (var index = 1; index <= BOARD_SIZE; index++  ){
        var clickArea = document.getElementById(idClickAreaStub.replace('STUB', index));
        var button = document.getElementById(idButtonDisplayStub.replace('STUB', index));

        if (!clickArea && !button){
            throw new Error('Cannot find item '+ index + '\'s clickable or display area.');
        } else if (!button){
            throw new Error('Cannot find item '+ index + '\'s display area.');
        } else if (!clickArea){
            throw new Error('Cannot find item '+ index + '\'s clickable area.');
        }
        buttonDisplayArea.push(button);
        buttonClickArea.push(clickArea);
        addAction(clickArea, (function(index){ //keep closure.
                                return function(){runActions(index);};
                            })(index) );
    }

    ////////////////////////////////////////////////////////////////////////////
    //// private functions
    ////////////////////////////////////////////////////////////////////////////
    /** Adds action to element. Could be replaced with jQuery or lib.
     * @param {Element} element
     * @param {Function} action
     */
    function addAction(element, action){
        var onTouchAction = function(){
            /** Could add useragent check here.
             * OR we perform a simple cheat:  If touchstart can exist,
             * it will trigger before the click. Thus we remove the click before the click. */
            //Assume that if touchstart exists, so does removeEventListener.
            element.removeEventListener('click', action);
            //Remove the click action once and reset the touchstart to the action.
            element.removeEventListener('touchstart', onTouchAction);
            element.addEventListener('touchstart', action, false);
            action();
        };
        if (element.addEventListener){
            element.addEventListener('click', action, false);
            element.addEventListener('touchstart', onTouchAction, false);
        } else if (element.attachEvent) {
            element.attachEvent('onclick', action);
        } else {
            element.onclick = action;
            element.ontouchstart= onTouchAction;
        }
    }

    /** Adds action to element. Could be replaced with jQuery or lib.
     * @param {Element} element
     * @param {string} cssClass The class to add or remove.
     * @param {boolean} add (Optional). if true, it adds. If false, removes. Default true.
     */
    function addClass(element, cssClass, add){
        if ('undefined' === add){
            add = true;
        }
        var currentClass = element.className ? element.className  : '';
        var pattern = new RegExp('(^|\\s)'+cssClass+'(\\s|$)', 'ig');
        var removeClass = function(){
            while (pattern.test(currentClass)){
                element.className = currentClass.replace(pattern, ' ') ;
                currentClass = element.className;
            }
            currentClass = currentClass.replace(/([a-z0-9])\s+$/i, '$1');
        };
        if (add){
            if(pattern.test(currentClass)){
                element.className = currentClass+' '+cssClass;
            } else {
                removeClass();
                element.className = currentClass+' '+cssClass;
            }
        } else {
            removeClass();
        }
    }

    /** Safety function used to limit clicks.
     * Sets that a flash button is currently in play or not.
     * @param {Number} position The button to set/remove from play.
     * @param {boolean} inplay Whether or not the button is play.
     */
    function setFlashButtonInPlay(position, inplay){
        if (inplay){
            flashButtonInPlay.push(position);
        } else {
            for(var index=0; index<flashButtonInPlay.length; index++){
                if (position === flashButtonInPlay[index]){
                    flashButtonInPlay.splice(index, 1);
                }
            }
        }
    }
    /** Safety function used to limit clicks.
     * @param {Number} position The button to check.
     * @return {booelan} true if in play, false otherwise.     */
    function isFlashButtionInPlay(position){
        for(var index=0; index<flashButtonInPlay.length; index++){
            if (position === flashButtonInPlay[index]){
               return true;
            }
        }
        return false;
    }
    /** Runs the list of middle button functions if enabled. */
    function middleButtonActions(){
        for (var index = 0; index < middleButtonFunctions.length; index++){
            middleButtonFunctions[index]();
        }
    }

    /**
     * Rans the list of actions for the flash buttons at the position give.
     * @param {number} position The position of the button to run actions.
     */
    function runActions(position){
        if (flashButtonsEnabled){
            if (isFlashButtionInPlay(position)){
                //we cannot allow multiple clicks during animation.
                return;
            }
            setFlashButtonInPlay(position,true);
            for(var index = 0, SIZE = flashButtonFunctions.length; index < SIZE; index++){
                flashButtonFunctions[index](position);
            }
            _flashPosition(position, FLASH_SPEED_INDEX_CLICK);

            setTimeout(
                function(){
                    setFlashButtonInPlay(position, false);
                },flashInterval[FLASH_SPEED_INDEX_CLICK]+100); //extra buffer time.
        }
    }

     /** Flashes the button at the given position using the given css class and interval.
     * @param {Number} index The 0-index of the button in the buttonDisplayArea array.
     * @param {string} cssClass The class to add or remove.
     * Invalid values are set to 0.
     * @param {string} cssClass The class to add or remove.
     * @param {Number} flashInterval The time to reset the class after.
     * @throws {Error} If the position is out of bounds. */
    function _setFlashButtonClass(index, cssClass, flashInterval){
        if (index < 0 || index >= buttonDisplayArea.length){
            throw new Error('Out of index bounds!');
        }
         //add animation class
        addClass(buttonDisplayArea[index], cssClass, true);
        //undo animation class, eventually.
        setTimeout(
                function(){
                    addClass(buttonDisplayArea[index], cssClass, false);
                },flashInterval);
    }

    /** Flashes the button at the given position.
     * @param {Number} position The position of the button in the circle.
     * @param {Number} speedIndex a value from 0,1,2,3 that denotes speed.
     * Invalid values are set to 0.
     * @throws {Error} If the position is out of bounds. */
    function _flashPosition(position, speedIndex){
        var index = position -1; //offset by 1.
        speedIndex = (speedIndex < 0 || speedIndex >= flashCssClass.length) ? 0 : speedIndex;
        _setFlashButtonClass(
                index,
                flashCssClass[speedIndex],
                flashInterval[speedIndex]);
    }

    /** Flashes the button at the given position for a loong burst.
     * @param {Number} position The position of the button in the circle.  */
    function _longFlashPosition(position){
        var LONG_FLASH_CLASS = 'flash-super-slow';
        var LONG_FLASH_INTERVAL= '4800';
        var index = position -1; //offset by 1.
        _setFlashButtonClass(
                index,
                LONG_FLASH_CLASS,
                LONG_FLASH_INTERVAL);
    }
    ////////////////////////////////////////////////////////////////////////////
    //// Public functions
    ////////////////////////////////////////////////////////////////////////////
    /** Adds a listener for the middle button.
     * @param {Function} action The function to perform.
     * @throws {Error} If action is not a function.
     */
    this.setMiddleButtonListener = function(action){
        if (typeof action === 'function'){
            middleButtonFunctions.push(action);
        } else {
            throw new Error('"'+action+'" is not a function!');
        }
    };
    /** Adds a listener for the flash buttons.
     * @param {Function} action The function to perform, takes in one parameter:
     * the 1-indexed position of the button pressed.
     * @throws {Error} If action is not a function.
     */
    this.setFlashButtonListener = function(action){
        if (typeof action === 'function'){
            flashButtonFunctions.push(action);
        } else {
            throw new Error('"'+action+'" is not a function!');
        }
    };
    /** Flashes the relevant position
     * @param {Number} position The position to flash.
     * These go in a clockwise order beginning at 1.
     * @param {Number} speedIndex a value from 0,1,2,3 where larger indices
     * denote speed.  Invalid values are set to 0.
     * Speeds are: 800, 600, 400, 200ms, respectively.
     * @throws {Error} If the position is out of bounds. */
    this.flashPosition = function(position, speedIndex){
       _flashPosition(position,speedIndex);
    };

    /** Flashes the button at the given position for a loong burst.
     * @param {Number} position The position of the button in the circle.  */
    this.longFlashPosition = function(position){
        _longFlashPosition(position);
    };

    /** @return {Number} The size of the board. */
    this.getSize =  function(){ return BOARD_SIZE; };

    /** Enables or disables flash buttons.
     * @param {Boolean} enable if eval'd as true, enables buttons.
     * Othewist false.     */
    this.enableFlashButtons = function(enable){
        flashButtonsEnabled = enable ? true : false;
    };

    /** Flashes the game board red + shakes it for negative feedback. */
    this.negativeFeedback = function(){
        var cssClass = 'wrong-background-fade';
        var flashInterval = 4000;
        //add animation class
        addClass(gameBorderUnderlay, cssClass, true);
        //undo animation class, eventually.
        setTimeout(
                function(){
                   addClass(gameBorderUnderlay, cssClass, false);
                },flashInterval);
    };

    /** Flashes the game board green for positive feedback. */
    this.positiveFeedback = function(){
        var cssClass = 'correct-background-fade';
        var flashInterval = 3000;
        //add animation class
        addClass(gameBorderUnderlay, cssClass, true);
        //undo animation class, eventually.
        setTimeout(
                function(){
                    addClass(gameBorderUnderlay, cssClass, false);
                },flashInterval);
    };
    /**
     * Sets the middle button's inner text and, optionally, mode.
     * @param {String} innerText The text to set in the middle button
     * @param {Number} mode The button mode to set.
     * 0 for inactive. 1 for active positive. 2 for active negative.
     * Default is 0. Invalid values are assumed 0.
     */
    this.setMiddleButton = function(innerText, mode){
        middleButtonDisplayArea.innerHTML = innerText;
        switch (mode){
            case 1:
                middleButtonDisplayArea.className = 'active';
                middleButtonClickArea.coords = middleButtonCoords;
                break;
            case 2:
                middleButtonDisplayArea.className = 'active bad';
                middleButtonClickArea.coords = middleButtonCoords;
                break;
            case 0:
            default:
             middleButtonDisplayArea.className = 'inactive';
             if (!middleButtonCoords){
                middleButtonCoords = middleButtonClickArea.coords;
             }
             middleButtonClickArea.removeAttribute('coords');
        }
    };
};

<commit_msg>[Mod]: Mild reordering of the event function<commit_after>if (typeof HexamemEngine === 'undefined'){
    HexamemEngine = function(){};
}

/**
 * Responsible for board interactions.
 * Attached to the playing board area.
 * If board components cannot be found, it throws an Error.
 *
 * @param {Number} size The expected size of the play area.
 * @version 0.3.2-20140403
 * @author Jason J.
 * @type HexamemEngine.prototype.PlayArea
 * @returns {HexamemEngine.prototype.PlayArea}
 * @throws {Error} If elements of the play area are not found.
 */
HexamemEngine.prototype.PlayArea = function(size){
    var BOARD_SIZE = size;
    /** @type Number The current flashing speed. Either 0, 1, 2, 3. 0 is slowest. */
    var FLASH_SPEED_INDEX_CLICK = 3;

    /** @type Element The underlay background/border of the game board. */
    var gameBorderUnderlay = document.getElementById('game-body-wrapper');
    if (!gameBorderUnderlay){
        throw new Error('Cannot find element with id: "game-body-wrapper"');
    }
    /** @type Element The middle button click area. */
    var middleButtonClickArea = document.getElementById('middle-button-area');
    /** @type Element The middle button display area. */
    var middleButtonDisplayArea = document.getElementById('middle-button');
    if (!middleButtonClickArea){
        throw new Error('Cannot find element with id: "middle-button-area"');
    }
    if (!middleButtonDisplayArea){
        throw new Error('Cannot find element with id: "middle-button"');
    }
    /** @type string The coords of the middle button to add and remove (and so enable/disable. */
    var middleButtonCoords = middleButtonClickArea.coords;
    middleButtonClickArea.removeAttribute('coords');

    /** @type Array|Function The list of functions for the middle button */
    var middleButtonFunctions = new Array();

    /** Replace STUB with number to get id. */
    var idClickAreaStub = 'button-area-STUB';
    /** Replace STUB with number to get id. */
    var idButtonDisplayStub = 'button-STUB-wrapper';

    /** @type Array|Element An aFLASH_SPEED_INDEX_CLICKrray of elements for the display area. */
    var buttonDisplayArea = new Array();
    /** @type Array|Element An array of elements for the clicking areas. */
    var buttonClickArea = new Array();

    /** @type Array|Function The list of functions to perform on click. */
    var flashButtonFunctions = new Array();

    /** @type Boolean whether or not the flash buttons are enabled. */
    var flashButtonsEnabled = true;

    /** @type Array|Number An array of numbers, indicated the position of a
     * button currently mid-click. */
    var flashButtonInPlay = new Array();

    /** @type Array|Number The flash interval between setting the animation and turning it off. */
    var flashInterval = [810, 610, 410, 210];
    /** @type Array|String The flash css for each speed. */
    var flashCssClass = ['flash-normal', 'flash-med-fast', 'flash-fast', 'flash-super-fast'];

    ////////////////////////////////////////////////////////////////////////////
    ////  End member initialization
    ////////////////////////////////////////////////////////////////////////////
    //set middle click listener.
    addAction(middleButtonClickArea, middleButtonActions);

    for (var index = 1; index <= BOARD_SIZE; index++  ){
        var clickArea = document.getElementById(idClickAreaStub.replace('STUB', index));
        var button = document.getElementById(idButtonDisplayStub.replace('STUB', index));

        if (!clickArea && !button){
            throw new Error('Cannot find item '+ index + '\'s clickable or display area.');
        } else if (!button){
            throw new Error('Cannot find item '+ index + '\'s display area.');
        } else if (!clickArea){
            throw new Error('Cannot find item '+ index + '\'s clickable area.');
        }
        buttonDisplayArea.push(button);
        buttonClickArea.push(clickArea);
        addAction(clickArea, (function(index){ //keep closure.
                                return function(){runActions(index);};
                            })(index) );
    }

    ////////////////////////////////////////////////////////////////////////////
    //// private functions
    ////////////////////////////////////////////////////////////////////////////
    /** Adds action to element. Could be replaced with jQuery or lib.
     * @param {Element} element
     * @param {Function} action
     */
    function addAction(element, action){
        var onTouchAction = function(){
            action();
            element.addEventListener('touchstart', action, false);
            /** Could add useragent check here.
             * OR we perform a simple cheat:  If touchstart can exist,
             * it will trigger before the click. Thus we remove the click before the click. */
            //Assume that if touchstart exists, so does removeEventListener.
            element.removeEventListener('click', action);
            //Remove the click action once and reset the touchstart to the action.
            element.removeEventListener('touchstart', onTouchAction);
        };
        if (element.addEventListener){
            element.addEventListener('click', action, false);
            element.addEventListener('touchstart', onTouchAction, false);
        } else if (element.attachEvent) {
            element.attachEvent('onclick', action);
        } else {
            element.onclick = action;
            element.ontouchstart= onTouchAction;
        }
    }

    /** Adds action to element. Could be replaced with jQuery or lib.
     * @param {Element} element
     * @param {string} cssClass The class to add or remove.
     * @param {boolean} add (Optional). if true, it adds. If false, removes. Default true.
     */
    function addClass(element, cssClass, add){
        if ('undefined' === add){
            add = true;
        }
        var currentClass = element.className ? element.className  : '';
        var pattern = new RegExp('(^|\\s)'+cssClass+'(\\s|$)', 'ig');
        var removeClass = function(){
            while (pattern.test(currentClass)){
                element.className = currentClass.replace(pattern, ' ') ;
                currentClass = element.className;
            }
            currentClass = currentClass.replace(/([a-z0-9])\s+$/i, '$1');
        };
        if (add){
            if(pattern.test(currentClass)){
                element.className = currentClass+' '+cssClass;
            } else {
                removeClass();
                element.className = currentClass+' '+cssClass;
            }
        } else {
            removeClass();
        }
    }

    /** Safety function used to limit clicks.
     * Sets that a flash button is currently in play or not.
     * @param {Number} position The button to set/remove from play.
     * @param {boolean} inplay Whether or not the button is play.
     */
    function setFlashButtonInPlay(position, inplay){
        if (inplay){
            flashButtonInPlay.push(position);
        } else {
            for(var index=0; index<flashButtonInPlay.length; index++){
                if (position === flashButtonInPlay[index]){
                    flashButtonInPlay.splice(index, 1);
                }
            }
        }
    }
    /** Safety function used to limit clicks.
     * @param {Number} position The button to check.
     * @return {booelan} true if in play, false otherwise.     */
    function isFlashButtionInPlay(position){
        for(var index=0; index<flashButtonInPlay.length; index++){
            if (position === flashButtonInPlay[index]){
               return true;
            }
        }
        return false;
    }
    /** Runs the list of middle button functions if enabled. */
    function middleButtonActions(){
        for (var index = 0; index < middleButtonFunctions.length; index++){
            middleButtonFunctions[index]();
        }
    }

    /**
     * Rans the list of actions for the flash buttons at the position give.
     * @param {number} position The position of the button to run actions.
     */
    function runActions(position){
        if (flashButtonsEnabled){
            if (isFlashButtionInPlay(position)){
                //we cannot allow multiple clicks during animation.
                return;
            }
            setFlashButtonInPlay(position,true);
            for(var index = 0, SIZE = flashButtonFunctions.length; index < SIZE; index++){
                flashButtonFunctions[index](position);
            }
            _flashPosition(position, FLASH_SPEED_INDEX_CLICK);

            setTimeout(
                function(){
                    setFlashButtonInPlay(position, false);
                },flashInterval[FLASH_SPEED_INDEX_CLICK]+100); //extra buffer time.
        }
    }

     /** Flashes the button at the given position using the given css class and interval.
     * @param {Number} index The 0-index of the button in the buttonDisplayArea array.
     * @param {string} cssClass The class to add or remove.
     * Invalid values are set to 0.
     * @param {string} cssClass The class to add or remove.
     * @param {Number} flashInterval The time to reset the class after.
     * @throws {Error} If the position is out of bounds. */
    function _setFlashButtonClass(index, cssClass, flashInterval){
        if (index < 0 || index >= buttonDisplayArea.length){
            throw new Error('Out of index bounds!');
        }
         //add animation class
        addClass(buttonDisplayArea[index], cssClass, true);
        //undo animation class, eventually.
        setTimeout(
                function(){
                    addClass(buttonDisplayArea[index], cssClass, false);
                },flashInterval);
    }

    /** Flashes the button at the given position.
     * @param {Number} position The position of the button in the circle.
     * @param {Number} speedIndex a value from 0,1,2,3 that denotes speed.
     * Invalid values are set to 0.
     * @throws {Error} If the position is out of bounds. */
    function _flashPosition(position, speedIndex){
        var index = position -1; //offset by 1.
        speedIndex = (speedIndex < 0 || speedIndex >= flashCssClass.length) ? 0 : speedIndex;
        _setFlashButtonClass(
                index,
                flashCssClass[speedIndex],
                flashInterval[speedIndex]);
    }

    /** Flashes the button at the given position for a loong burst.
     * @param {Number} position The position of the button in the circle.  */
    function _longFlashPosition(position){
        var LONG_FLASH_CLASS = 'flash-super-slow';
        var LONG_FLASH_INTERVAL= '4800';
        var index = position -1; //offset by 1.
        _setFlashButtonClass(
                index,
                LONG_FLASH_CLASS,
                LONG_FLASH_INTERVAL);
    }
    ////////////////////////////////////////////////////////////////////////////
    //// Public functions
    ////////////////////////////////////////////////////////////////////////////
    /** Adds a listener for the middle button.
     * @param {Function} action The function to perform.
     * @throws {Error} If action is not a function.
     */
    this.setMiddleButtonListener = function(action){
        if (typeof action === 'function'){
            middleButtonFunctions.push(action);
        } else {
            throw new Error('"'+action+'" is not a function!');
        }
    };
    /** Adds a listener for the flash buttons.
     * @param {Function} action The function to perform, takes in one parameter:
     * the 1-indexed position of the button pressed.
     * @throws {Error} If action is not a function.
     */
    this.setFlashButtonListener = function(action){
        if (typeof action === 'function'){
            flashButtonFunctions.push(action);
        } else {
            throw new Error('"'+action+'" is not a function!');
        }
    };
    /** Flashes the relevant position
     * @param {Number} position The position to flash.
     * These go in a clockwise order beginning at 1.
     * @param {Number} speedIndex a value from 0,1,2,3 where larger indices
     * denote speed.  Invalid values are set to 0.
     * Speeds are: 800, 600, 400, 200ms, respectively.
     * @throws {Error} If the position is out of bounds. */
    this.flashPosition = function(position, speedIndex){
       _flashPosition(position,speedIndex);
    };

    /** Flashes the button at the given position for a loong burst.
     * @param {Number} position The position of the button in the circle.  */
    this.longFlashPosition = function(position){
        _longFlashPosition(position);
    };

    /** @return {Number} The size of the board. */
    this.getSize =  function(){ return BOARD_SIZE; };

    /** Enables or disables flash buttons.
     * @param {Boolean} enable if eval'd as true, enables buttons.
     * Othewist false.     */
    this.enableFlashButtons = function(enable){
        flashButtonsEnabled = enable ? true : false;
    };

    /** Flashes the game board red + shakes it for negative feedback. */
    this.negativeFeedback = function(){
        var cssClass = 'wrong-background-fade';
        var flashInterval = 4000;
        //add animation class
        addClass(gameBorderUnderlay, cssClass, true);
        //undo animation class, eventually.
        setTimeout(
                function(){
                   addClass(gameBorderUnderlay, cssClass, false);
                },flashInterval);
    };

    /** Flashes the game board green for positive feedback. */
    this.positiveFeedback = function(){
        var cssClass = 'correct-background-fade';
        var flashInterval = 3000;
        //add animation class
        addClass(gameBorderUnderlay, cssClass, true);
        //undo animation class, eventually.
        setTimeout(
                function(){
                    addClass(gameBorderUnderlay, cssClass, false);
                },flashInterval);
    };
    /**
     * Sets the middle button's inner text and, optionally, mode.
     * @param {String} innerText The text to set in the middle button
     * @param {Number} mode The button mode to set.
     * 0 for inactive. 1 for active positive. 2 for active negative.
     * Default is 0. Invalid values are assumed 0.
     */
    this.setMiddleButton = function(innerText, mode){
        middleButtonDisplayArea.innerHTML = innerText;
        switch (mode){
            case 1:
                middleButtonDisplayArea.className = 'active';
                middleButtonClickArea.coords = middleButtonCoords;
                break;
            case 2:
                middleButtonDisplayArea.className = 'active bad';
                middleButtonClickArea.coords = middleButtonCoords;
                break;
            case 0:
            default:
             middleButtonDisplayArea.className = 'inactive';
             if (!middleButtonCoords){
                middleButtonCoords = middleButtonClickArea.coords;
             }
             middleButtonClickArea.removeAttribute('coords');
        }
    };
};

<|endoftext|>


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

  angular
    .module('porttare.controllers')
    .controller('ProductController', ProductController);

  function ProductController(providerItem, CartService, $ionicPopup, $state,
                            $scope, WishlistsService, ModalService,
                            ErrorHandlerService, $ionicLoading, $auth) {
    var productVm = this;
    productVm.more = false;
    productVm.product = providerItem;
    productVm.runAction = runAction;
    productVm.closeModal = closeModal;
    productVm.item = {};
    productVm.item.provider_item_id = productVm.product.id; //jshint ignore:line
    productVm.item.cantidad = 1;
    productVm.wishlists = [];
    productVm.cartItem = CartService.findCartItem($auth.user.customer_order, productVm.product); //jshint ignore:line
    productVm.canAdd = getCanAdd();
    productVm.onWishlistSelect = onWishlistSelect;
    productVm.createNewWishlist = createNewWishlist;
    productVm.showNewWishlistInput = false;
    productVm.showNewWishlist = showNewWishlist;
    productVm.wishlistName = '';
    productVm.clearData = clearData;
    // jshint ignore:start
    productVm.counterOptions = {
      cantidad: productVm.item.cantidad,
      cartItem: productVm.cartItem,
      providerItem: productVm.product,
      priceCents: providerItem.precio_cents,
      currencyCode: providerItem.precio_currency,
      onChangeValue: function (data) {
        productVm.item.cantidad = data.itemsCount;
        productVm.canAdd = getCanAdd();
      }
    };
    // jshint ignore:end

    productVm.slickConfig = {
      arrows: false,
      dots: true
    };

    productVm.actions = {
      cart: {
        onActionSelect: addToCart
      },
      wishlist: {
        onActionSelect: addToWishlist
      },
      buyNow: {
        onActionSelect: buyNow
      }
    };

    function runAction(action) {
      if (action && action.onActionSelect) {
        action.onActionSelect();
      }
    }

    function addToCart() {
      CartService.addItem(productVm.item)
        .then(onAddSuccess, onError);
    }

    function getWishlists() {
      $ionicLoading.show({
        template: '{{::("globals.loading"|translate)}}'
      });
      productVm.wishlists = [];
      WishlistsService.getWishlists()
        .then(function success(res) {
          $ionicLoading.hide();
          productVm.wishlists = res.customer_wishlists; //jshint ignore:line
        }, ErrorHandlerService.handleCommonErrorGET);
    }

    function addToWishlist() {
      getWishlists();
      ModalService.showModal({
        parentScope: $scope,
        fromTemplateUrl: 'templates/product/add-to-wishlist.html'
      });
    }

    function showNewWishlist() {
      productVm.showNewWishlistInput = true;
    }

    function createNewWishlist() {
      $ionicLoading.show({
        template: '{{::("globals.loading"|translate)}}'
      });
      var wishlistData = {
        nombre: productVm.wishlistName
      };
      WishlistsService.createWishlist(wishlistData)
        .then(function success(res) {
          $ionicLoading.hide();
          clearData();
          productVm.wishlists.push(res.customer_wishlist); //jshint ignore:line
        }, function error(res) {
          $ionicLoading.hide();
          if (res && res.errors) {
            productVm.messages = res.errors;
          } else {
            var message = '{{::("globals.pleaseTryAgain"|translate)}}';
            $ionicPopup.alert({
              title: 'Error',
              template: message
            });
          }
        });
    }

    function clearData() {
      productVm.showNewWishlistInput = false;
      productVm.wishlistName = '';
    }

    function onAddSuccess(res) {
      var route = 'app.categories.provider';
      var params = {
        categoryId: $state.params.categoryId,
        providerId: $state.params.providerId
      };

      onSuccess(res, route, params);
    }

    function onSuccess(res, route, params) {
      if (res && res.customer_order) {//jshint ignore:line
        validateOrderCreated(res.customer_order);//jshint ignore:line
      }

      $state.go(route, params)
        .then(function () {
          $ionicPopup.alert({
            title: 'Alerta',
            template: '{{::("cart.successfullyAdded"|translate)}}'
          }).then(closeModal);
        });
    }

    function onError(response) {

      if(response.errors.cantidad[0]){
        productVm.messages = response.errors.cantidad.join();
      }

      $ionicPopup.alert({
        title: 'Error',
        template: '{{::("globals.pleaseTryAgain"|translate)}}'
      });
    }

    function closeModal() {
      ModalService.closeModal();
      clearData();
    }

    function onWishlistSelect(wlist) {
      var wishlist = angular.copy(wlist);
      var item = productVm.item.provider_item_id; //jshint ignore:line
      wishlist.provider_items_ids = filterItemsIds(wlist); //jshint ignore:line
      wishlist.provider_items_ids.push(item); //jshint ignore:line
      WishlistsService.updateWishlist(wishlist)
        .then(function success() {
          onAddSuccess();
        }, onError);
    }

    function buyNow() {
      CartService.addItem(productVm.item)
        .then(onBuyNowSuccess, onError);
    }

    function onBuyNowSuccess(res) {
      var route = 'app.cart.index';
      var params = null;
      onSuccess(res, route, params);
    }

    function validateOrderCreated(order) {
      if (!$auth.user.customer_order) { //jshint ignore:line
        $auth.user.customer_order = order//jshint ignore:line
      } else {
        $auth.user.customer_order = order//jshint ignore:line
        $scope.$emit('update-number');
      }
    }

    //jshint ignore:start
    function filterItemsIds(wlist) {
      var ids = [];
      if (wlist.provider_items) {
        angular.forEach(wlist.provider_items, function (item) {
          ids.push(item.id);
        });
      }
      return ids;
    }
    //jshint ignore:end

    function getCanAdd(){
      return CartService.canAddItem(productVm.cartItem, productVm.item.cantidad , productVm.product);
    }
  }
})();
<commit_msg>Update product-controller.js<commit_after>(function () {
  'use strict';

  angular
    .module('porttare.controllers')
    .controller('ProductController', ProductController);

  function ProductController(providerItem, CartService, $ionicPopup, $state,
                            $scope, WishlistsService, ModalService,
                            ErrorHandlerService, $ionicLoading, $auth) {
    var productVm = this;
    productVm.more = false;
    productVm.product = providerItem;
    productVm.runAction = runAction;
    productVm.closeModal = closeModal;
    productVm.item = {};
    productVm.item.provider_item_id = productVm.product.id; //jshint ignore:line
    productVm.item.cantidad = 1;
    productVm.wishlists = [];
    productVm.cartItem = CartService.findCartItem($auth.user.customer_order, productVm.product); //jshint ignore:line
    productVm.canAdd = getCanAdd();
    productVm.onWishlistSelect = onWishlistSelect;
    productVm.createNewWishlist = createNewWishlist;
    productVm.showNewWishlistInput = false;
    productVm.showNewWishlist = showNewWishlist;
    productVm.wishlistName = '';
    productVm.clearData = clearData;
    // jshint ignore:start
    productVm.counterOptions = {
      cantidad: productVm.item.cantidad,
      cartItem: productVm.cartItem,
      providerItem: productVm.product,
      priceCents: providerItem.precio_cents,
      currencyCode: providerItem.precio_currency,
      onChangeValue: function (data) {
        productVm.item.cantidad = data.itemsCount;
        productVm.canAdd = getCanAdd();
      }
    };
    // jshint ignore:end

    productVm.slickConfig = {
      arrows: false,
      dots: true
    };

    productVm.actions = {
      cart: {
        onActionSelect: addToCart
      },
      wishlist: {
        onActionSelect: addToWishlist
      },
      buyNow: {
        onActionSelect: buyNow
      }
    };

    function runAction(action) {
      if (action && action.onActionSelect) {
        action.onActionSelect();
      }
    }

    function addToCart() {
      CartService.addItem(productVm.item)
        .then(onAddSuccess, onError);
    }

    function getWishlists() {
      $ionicLoading.show({
        template: '{{::("globals.loading"|translate)}}'
      });
      productVm.wishlists = [];
      WishlistsService.getWishlists()
        .then(function success(res) {
          $ionicLoading.hide();
          productVm.wishlists = res.customer_wishlists; //jshint ignore:line
        }, ErrorHandlerService.handleCommonErrorGET);
    }

    function addToWishlist() {
      getWishlists();
      ModalService.showModal({
        parentScope: $scope,
        fromTemplateUrl: 'templates/product/add-to-wishlist.html'
      });
    }

    function showNewWishlist() {
      productVm.showNewWishlistInput = true;
    }

    function createNewWishlist() {
      $ionicLoading.show({
        template: '{{::("globals.loading"|translate)}}'
      });
      var wishlistData = {
        nombre: productVm.wishlistName
      };
      WishlistsService.createWishlist(wishlistData)
        .then(function success(res) {
          $ionicLoading.hide();
          clearData();
          productVm.wishlists.push(res.customer_wishlist); //jshint ignore:line
        }, function error(res) {
          $ionicLoading.hide();
          if (res && res.errors) {
            productVm.messages = res.errors;
          } else {
            var message = '{{::("globals.pleaseTryAgain"|translate)}}';
            $ionicPopup.alert({
              title: 'Error',
              template: message
            });
          }
        });
    }

    function clearData() {
      productVm.showNewWishlistInput = false;
      productVm.wishlistName = '';
    }

    function onAddSuccess(res) {
      var route = 'app.categories.provider';
      var params = {
        categoryId: $state.params.categoryId,
        providerId: $state.params.providerId
      };

      onSuccess(res, route, params);
    }

    function onSuccess(res, route, params) {
      if (res && res.customer_order) {//jshint ignore:line
        validateOrderCreated(res.customer_order);//jshint ignore:line
      }

      $state.go(route, params)
        .then(function () {
          $ionicPopup.alert({
            title: 'Alerta',
            template: '{{::("cart.successfullyAdded"|translate)}}'
          }).then(closeModal);
        });
    }

    function onError(response) {
      if(response.errors.cantidad){
        productVm.messages = response.errors.cantidad.join(', ');
      }
      $ionicPopup.alert({
        title: 'Error',
        template: '{{::("globals.pleaseTryAgain"|translate)}}'
      });
    }

    function closeModal() {
      ModalService.closeModal();
      clearData();
    }

    function onWishlistSelect(wlist) {
      var wishlist = angular.copy(wlist);
      var item = productVm.item.provider_item_id; //jshint ignore:line
      wishlist.provider_items_ids = filterItemsIds(wlist); //jshint ignore:line
      wishlist.provider_items_ids.push(item); //jshint ignore:line
      WishlistsService.updateWishlist(wishlist)
        .then(function success() {
          onAddSuccess();
        }, onError);
    }

    function buyNow() {
      CartService.addItem(productVm.item)
        .then(onBuyNowSuccess, onError);
    }

    function onBuyNowSuccess(res) {
      var route = 'app.cart.index';
      var params = null;
      onSuccess(res, route, params);
    }

    function validateOrderCreated(order) {
      if (!$auth.user.customer_order) { //jshint ignore:line
        $auth.user.customer_order = order//jshint ignore:line
      } else {
        $auth.user.customer_order = order//jshint ignore:line
        $scope.$emit('update-number');
      }
    }

    //jshint ignore:start
    function filterItemsIds(wlist) {
      var ids = [];
      if (wlist.provider_items) {
        angular.forEach(wlist.provider_items, function (item) {
          ids.push(item.id);
        });
      }
      return ids;
    }
    //jshint ignore:end

    function getCanAdd(){
      return CartService.canAddItem(productVm.cartItem, productVm.item.cantidad , productVm.product);
    }
  }
})();
<|endoftext|>


<commit_before>/*
 * This file belongs to Kreta.
 * The source code of application includes a LICENSE file
 * with all information about license.
 *
 * @author benatespina <benatespina@gmail.com>
 * @author gorkalaucirica <gorka.lauzirika@gmail.com>
 */

import {SelectorView} from '../../component/selector';
import {Issue} from '../../../models/issue';
import {User} from '../../../models/user';
import {Project} from '../../../models/project';
import {ProjectCollection} from '../../../collections/project';
import {IssueTypeCollection} from '../../../collections/issue-type';
import {IssuePriorityCollection} from '../../../collections/issue-priority';
import {NotificationService} from '../../../service/notification';
import {FormSerializerService} from '../../../service/form-serializer';

export class IssueNewView extends Backbone.Marionette.ItemView {
  constructor(options) {
    this.className = 'issue-new';
    this.template = _.template($('#issue-new-template').html());
    this.events = {
      'submit #issue-new': 'save'
    };

    this.ui = {
      project: 'select[name="project"]',
      assignee: 'select[name="assignee"]',
      priority: 'select[name="priority"]',
      type: 'select[name="type"]',
      issueDetails: '.issue-new-details'
    };

    super(options);

    if (this.model.isNew()) {
      this.projects = App.collection.project;
      this.listenTo(App.collection.project, 'reset', this.updateProjects);
    } else {
      this.model.on('sync', this.getCurrentProject, this);
      this.getCurrentProject(this.model);
    }

    this.issuePriorities = new IssuePriorityCollection();
    this.issueTypes = new IssueTypeCollection();

    this.listenTo(this.issueTypes, 'reset', this.updateSelectors);
    this.listenTo(this.issuePriorities, 'reset', this.updateSelectors);
  }

  onRender() {
    this.ui.issueDetails.hide();

    this.renderSelectors();
    this.updateProjects();

    setTimeout(() => {
      this.$project.select2("open");
    }, 1000);

    return this;
  }

  renderSelectors() {
    this.$assignee = new SelectorView(this.ui.assignee);
    this.$priority = new SelectorView(this.ui.priority);
    this.$type = new SelectorView(this.ui.type);
    this.$project = new SelectorView(this.ui.project, {
      onSelect: $.proxy(this.onProjectSelected, this),
      containerCss: 'project-new__project-selector'
    });
  }

  updateProjects() {
    this.projects = App.collection.project;
    this.$project.setSelectables(this.projects.models);
  }

  onProjectSelected(ev) {
    this.currentProject = this.projects.get($(ev.currentTarget).val());

    this.selectorsLeft = 2;
    this.$el.find('.issue-new-details').hide();

    var users = [];
    this.currentProject.get('participants').forEach((participant) => {
      users.push(new User(participant.user));
    });
    this.$assignee.setSelectables(users);

    this.issueTypes.setProject(this.currentProject.id).fetch({reset: true});
    this.issuePriorities.setProject(this.currentProject.id).fetch({reset: true});
  }

  getCurrentProject(issue) {
    if(typeof issue.get('_links') !== 'undefined') {
      $.get(issue.get('_links').project.href, (project) => {
        this.render();
        this.onProjectSelected(new Project(project));
      });
    }
  }

  updateSelectors() {
    this.$type.setSelectables(this.issueTypes.models);
    this.$priority.setSelectables(this.issuePriorities.models);

    this.selectorsLeft--;

    if (this.selectorsLeft === 0) {
      this.$el.find('.issue-new-details').show();
    }
  }

  save(ev) {
    ev.preventDefault();

    var $actions = $('.issue-new-actions');
    $actions.hide();

    this.model = FormSerializerService.serialize(
      $('#issue-new'), Issue
    );

    this.model.set('project', this.currentProject);

    this.model.save(null, {
      success: (model) => {
        App.router.base.navigate('/project/' + this.currentProject, true);
        App.controller.issue.showAction(model);
        NotificationService.showNotification({
          type: 'success',
          message: 'Issue created successfully'
        });
      }, error: function() {
        NotificationService.showNotification({
          type: 'error',
          message: 'Error while saving this issue'
        });
        $actions.show();
      }
    });
  }
}
<commit_msg>Fixed issues creating issues<commit_after>/*
 * This file belongs to Kreta.
 * The source code of application includes a LICENSE file
 * with all information about license.
 *
 * @author benatespina <benatespina@gmail.com>
 * @author gorkalaucirica <gorka.lauzirika@gmail.com>
 */

import {SelectorView} from '../../component/selector';
import {Issue} from '../../../models/issue';
import {User} from '../../../models/user';
import {Project} from '../../../models/project';
import {ProjectCollection} from '../../../collections/project';
import {IssueTypeCollection} from '../../../collections/issue-type';
import {IssuePriorityCollection} from '../../../collections/issue-priority';
import {NotificationService} from '../../../service/notification';
import {FormSerializerService} from '../../../service/form-serializer';

export class IssueNewView extends Backbone.Marionette.ItemView {
  constructor(options) {
    this.className = 'issue-new';
    this.template = _.template($('#issue-new-template').html());
    this.events = {
      'submit #issue-new': 'save'
    };

    this.ui = {
      project: 'select[name="project"]',
      assignee: 'select[name="assignee"]',
      priority: 'select[name="priority"]',
      type: 'select[name="type"]',
      issueDetails: '.issue-new-details'
    };

    super(options);

    if (this.model.isNew()) {
      this.projects = App.collection.project;
      this.listenTo(App.collection.project, 'reset', this.updateProjects);
    } else {
      this.model.on('sync', this.getCurrentProject, this);
      this.getCurrentProject(this.model);
    }

    this.issuePriorities = new IssuePriorityCollection();
    this.issueTypes = new IssueTypeCollection();

    this.listenTo(this.issueTypes, 'reset', this.updateSelectors);
    this.listenTo(this.issuePriorities, 'reset', this.updateSelectors);
  }

  onRender() {
    this.ui.issueDetails.hide();

    this.renderSelectors();
    this.updateProjects();

    setTimeout(() => {
      this.$project.select2("open");
    }, 1000);

    return this;
  }

  renderSelectors() {
    this.$assignee = new SelectorView(this.ui.assignee);
    this.$priority = new SelectorView(this.ui.priority);
    this.$type = new SelectorView(this.ui.type);
    this.$project = new SelectorView(this.ui.project, {
      onSelect: $.proxy(this.onProjectSelected, this),
      containerCss: 'project-new__project-selector'
    });
  }

  updateProjects() {
    this.projects = App.collection.project;
    this.$project.setSelectables(this.projects.models);
  }

  onProjectSelected(ev) {
    this.currentProject = this.projects.get($(ev.currentTarget).val());

    this.selectorsLeft = 2;
    this.$el.find('.issue-new-details').hide();

    var users = [];
    this.currentProject.get('participants').forEach((participant) => {
      users.push(new User(participant.user));
    });
    this.$assignee.setSelectables(users);

    this.issueTypes.setProject(this.currentProject.id).fetch({reset: true});
    this.issuePriorities.setProject(this.currentProject.id).fetch({reset: true});
  }

  getCurrentProject(issue) {
    if(typeof issue.get('_links') !== 'undefined') {
      $.get(issue.get('_links').project.href, (project) => {
        this.render();
        this.onProjectSelected(new Project(project));
      });
    }
  }

  updateSelectors() {
    this.$type.setSelectables(this.issueTypes.models);
    this.$priority.setSelectables(this.issuePriorities.models);

    this.selectorsLeft--;

    if (this.selectorsLeft === 0) {
      this.$el.find('.issue-new-details').show();
    }
  }

  save(ev) {
    ev.preventDefault();

    var $actions = $('.issue-new-actions');
    $actions.hide();

    this.model = FormSerializerService.serialize(
      $('#issue-new'), Issue
    );

    this.model.set('project', this.currentProject.id);

    this.model.save(null, {
      success: (model) => {
        App.router.base.navigate('/project/' + this.currentProject.id, true);
        App.controller.issue.showAction(model);
        NotificationService.showNotification({
          type: 'success',
          message: 'Issue created successfully'
        });
      }, error: function() {
        NotificationService.showNotification({
          type: 'error',
          message: 'Error while saving this issue'
        });
        $actions.show();
      }
    });
  }
}
<|endoftext|>


<commit_before>var ConfigBuilder = require('../builders/ConfigBuilder');

module.exports.register = function(Handlebars, options) {
    options = options || {};

    var helpers = {
        helper_config: function(key) {
            var config = new ConfigBuilder().build();
            return config.get(key);
        }
    };

    for (var helper in helpers) {
        if (helpers.hasOwnProperty(helper)) {
            Handlebars.registerHelper(helper, helpers[helper]);
        }
    }
}<commit_msg>Validate arguments passed from template to helper_config<commit_after>var ConfigBuilder = require('../builders/ConfigBuilder');

module.exports.register = function(Handlebars, options) {
    options = options || {};

    var helperName = 'helper_config';

    function validateArguments(arguments) {
        if (arguments.length < 2) {
            throw new ReferenceError(`${helperName}: config key must be passed from template; nothing was passed`);
        }
        if (arguments.length === 2 && typeof arguments[0] != 'string') {
            var argType = typeof arguments[0];
            throw new TypeError(`${helperName}: config key must be a string when passed from template; ${argType} was passed`);
        }
    }

    var helpers = {
        [helperName]: function(key, options) {
            validateArguments(arguments);

            var config = new ConfigBuilder({helperName: helperName}).build();
            return config.get(key);
        }
    };

    for (var helper in helpers) {
        if (helpers.hasOwnProperty(helper)) {
            Handlebars.registerHelper(helper, helpers[helper]);
        }
    }
}<|endoftext|>