<commit_before>var path = require('path');

module.exports = function (plop) {

    plop.addHelper('absPath', function (p) {
		return path.resolve(plop.getPlopfilePath(), p);
	});

    plop.addHelper('pathToBEM', function (plop_path, name) {
        if(plop_path[plop_path.length] != '/') plop_path += "/";
        var s = plop_path.split("/").join("__");
        s += plop.renderString("{{ dashCase name }}", { name: name });
        s = s.replace('src__web__components__', 'hig__');
        return s;
	});

    plop.addHelper('pathToInterface', function (plop_path, name) {
        var a = plop_path.split("/");
        var properCasedName = plop.renderString("{{ properCase name }}", { name: name });
        a.push(properCasedName);
        var new_a = [];
        a.forEach(function(element) {
            if(element != "src" && element != "web"){
                if(element == "components"){
                    new_a.push(element);
                }else{
                    var p = plop.renderString("{{ properCase element }}", { element: element });
                    new_a.push(p);
                    new_a.push("partials");
                }

            }
        }, this);

        new_a.pop(); // remove last "partials"

        var s = "['";
        s += new_a.join("']['");
        s += "']";

        return s;
	});

	plop.setGenerator('hig_skeleton', {
		description: 'skeleton HIG generator, generates HTML, SCSS and JS class files.',
		prompts: [{
            type: 'input',
            name: 'name',
            message: 'What\s the name of the component?',
            validate: function (value) {
                if ((/.+/).test(value)) { return true; }
                return 'name is required';
            }
        }, {
            type: 'directory',
            name: 'path',
            message: 'where would you like to put this component?',
            basePath: plop.getPlopfilePath()
        }],
		actions: [{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/tests/tests-{{ dashCase name }}.html',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.html',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/tests/gemini-{{ dashCase name }}.html',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.html',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.html',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.html',
            abortOnFail: true
        },{
            type: 'modify',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.html',
            pattern: /## replace css class here ##/gi,
			template: '{{ pathToBEM path name }}',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.scss',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.scss',
            abortOnFail: true
        },{
            type: 'modify',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.scss',
            pattern: /## replace css class here ##/gi,
			template: '{{ pathToBEM path name }}',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.js',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.js',
            abortOnFail: true
        },{
            type: 'modify',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.js',
            pattern: /## replace interface here ##/gi,
			template: '{{{ pathToInterface path name }}}',
            abortOnFail: true
        }]
	});
};<commit_msg>correction to template file name in plopfile.js<commit_after>var path = require('path');

module.exports = function (plop) {

    plop.addHelper('absPath', function (p) {
		return path.resolve(plop.getPlopfilePath(), p);
	});

    plop.addHelper('pathToBEM', function (plop_path, name) {
        if(plop_path[plop_path.length] != '/') plop_path += "/";
        var s = plop_path.split("/").join("__");
        s += plop.renderString("{{ dashCase name }}", { name: name });
        s = s.replace('src__web__components__', 'hig__');
        return s;
	});

    plop.addHelper('pathToInterface', function (plop_path, name) {
        var a = plop_path.split("/");
        var properCasedName = plop.renderString("{{ properCase name }}", { name: name });
        a.push(properCasedName);
        var new_a = [];
        a.forEach(function(element) {
            if(element != "src" && element != "web"){
                if(element == "components"){
                    new_a.push(element);
                }else{
                    var p = plop.renderString("{{ properCase element }}", { element: element });
                    new_a.push(p);
                    new_a.push("partials");
                }

            }
        }, this);

        new_a.pop(); // remove last "partials"

        var s = "['";
        s += new_a.join("']['");
        s += "']";

        return s;
	});

	plop.setGenerator('hig_skeleton', {
		description: 'skeleton HIG generator, generates HTML, SCSS and JS class files.',
		prompts: [{
            type: 'input',
            name: 'name',
            message: 'What\s the name of the component?',
            validate: function (value) {
                if ((/.+/).test(value)) { return true; }
                return 'name is required';
            }
        }, {
            type: 'directory',
            name: 'path',
            message: 'where would you like to put this component?',
            basePath: plop.getPlopfilePath()
        }],
		actions: [{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/tests/tests-{{ dashCase name }}.html',
            templateFile: 'src/web/helpers/skeletons/skeleton-tests-template.html',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/tests/gemini-{{ dashCase name }}.html',
            templateFile: 'src/web/helpers/skeletons/skeleton-gemini-template.html',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.html',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.html',
            abortOnFail: true
        },{
            type: 'modify',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.html',
            pattern: /## replace css class here ##/gi,
			template: '{{ pathToBEM path name }}',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.scss',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.scss',
            abortOnFail: true
        },{
            type: 'modify',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.scss',
            pattern: /## replace css class here ##/gi,
			template: '{{ pathToBEM path name }}',
            abortOnFail: true
        },{
            type: 'add',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.js',
            templateFile: 'src/web/helpers/skeletons/skeleton-template.js',
            abortOnFail: true
        },{
            type: 'modify',
            path: '{{absPath path}}/{{ dashCase name }}/{{ dashCase name }}.js',
            pattern: /## replace interface here ##/gi,
			template: '{{{ pathToInterface path name }}}',
            abortOnFail: true
        }]
	});
};<|endoftext|>


<commit_before>phoxy.render =
{
  DeferRender : function (ejs, data, rendered_callback, tag)
    {
      phoxy.Log(4, "phoxy.DeferRender", arguments);
      if (tag === undefined)
        tag = '<defer_render>';
      var canvas = phoxy._.render.PrepareCanvas(tag);
      var id = canvas.id;

      phoxy._.render.RenderReplace(id, ejs, data, rendered_callback);

      if (tag === null)
        return canvas;
      return canvas.html;
    }
  ,
};

phoxy._.render =
{
  PrepareCanvas : function(tag)
    {
      if (tag === undefined)
        tag = '<div>';
      var vanilla_tag = tag.substring(1, tag.length - 1);

      var id =  phoxy._.internal.GenerateUniqueID();
      var obj = document.createElement(vanilla_tag);
      obj.setAttribute('id', id);
      var div = obj.outerHTML;

      return { id: id, obj: obj, html: div };
    }
  ,
  AsyncRender_Strategy : function (target, ejs, data, rendered_callback, difference)
    { // AsyncRender strategy: for production
      phoxy._.render.Fancy(ejs, data, function async_strategy_birth(obj, ejs, data)
      {
        if (typeof obj === 'undefined')
        {
          phoxy.Log(3, 'phoxy.Reality', 'Design render skiped. (No design was choosed?)', document.getElementById(target));
          return; // And break dependencies execution
        }

        // Potential cascade memleak
        // Should clear listeners with callback
        phoxy._.time.Appeared(target, function async_strategy_wait_for_apperance()
        {
          difference.call(phoxy, target, obj.html, arguments);
          for (var k in obj.defer)
              obj.defer[k]();
        }, undefined, -1);

        obj.on_complete = function async_strategy_on_complete()
        {
          if (typeof(rendered_callback) !== 'undefined')
            rendered_callback.call(obj.across, ejs, data, obj.html);
        };
      }, true);
    }
  ,
  SyncRender_Strategy : function (target, ejs, data, rendered_callback, difference)
    { // SyncRender strategy: for debug/develop purposes
      phoxy._.time.Appeared(target, function sync_strategy_wait_for_apperance()
      {
        phoxy._.render.Fancy(ejs, data, function sync_strategy_birth(obj, ejs, data)
        {
          if (typeof obj === 'undefined')
          {
            phoxy.Log(3, 'phoxy.Reality', 'Design render skiped. (No design was choosed?)', document.getElementById(target));
            return; // And break dependencies execution
          }

          difference.call(phoxy, target, obj.html, arguments);

          obj.on_complete = function sync_strategy_on_complete()
          {
            if (typeof(rendered_callback) !== 'undefined')
              rendered_callback.call(obj.across, ejs, data, obj.html);
          };
        }, true);
      }, undefined, -1);
    }
  ,
  RenderStrategy : "Will be replaced by selected strategy after compilation."
  ,
  RenderInto : function (target, ejs, data, rendered_callback)
    {
      var args = Array.prototype.slice.call(arguments);
      args.push(function render_into_f(target, html)
      {
        document.getElementById(target).innerHTMl = html;
      });
      phoxy._.render.RenderStrategy.apply(this, args);
    }
  ,
  RenderReplace : function (target, ejs, data, rendered_callback)
    {
      var args = Array.prototype.slice.call(arguments);
      args.push(function render_replace_f(target, html)
      {
        var that = document.getElementById(target);
        that.insertAdjacentHTML("afterEnd", html);
        that.parentNode.removeChild(that);
      });
      phoxy._.render.RenderStrategy.apply(this, args);
    }
  ,
  Render : function (design, data, callback, is_phoxy_internal_call)
    {
      phoxy.Log(0, "phoxy.Render is OBSOLETE. Use phoxy.Fancy instead");
    }
  ,
  Fancy : function()
    {
      var args = arguments;
      for (var i = 0; i < 2; i++)
        if (Array.isArray(args[i]))
        {
          args[i] = phoxy.ConstructURL(args[i]);
          return phoxy._.render.Fancy.apply(this, args);
        }

      phoxy.Log(6, "phoxy.Fancy", arguments);

      var callback = args[2];
      if (typeof(callback) === 'undefined')
        callback = function (){};

      return new phoxy._.birth(args[0], args[1], callback, true);
    }
  ,
};

phoxy._.birth = function(will, spirit, callback, raw_output)
{
  this.will = will;
  this.spirit = spirit;
  this.birth_id = phoxy._.internal.GenerateUniqueID();
  console.time("phoxy.birth " + this.birth_id);
  this.callback = function birth_log_report()
  {
    console.groupCollapsed("phoxy.birth", will);
      console.log(spirit);
      for (var k in this.log)
        console.log.apply(console, this.log[k]);

    console.timeEnd("phoxy.birth " + this.birth_id);
    console.groupEnd();

    callback.apply(this, arguments);
  }
  this.raw_output = raw_output;
  this.log = [];

  return this.Decision(will, spirit, callback);
}

phoxy._.birth.prototype =
{
  Decision: function(will, spirit)
    {
      this.Log("Decision", arguments);
      if (typeof spirit === 'undefined')
        return this.Fortune(will);
      if (typeof spirit !== 'object')
        return this.Hope(will, spirit);
      return this.Fate(will, spirit);
    }
  ,
  Fortune: function(word)
    {
      this.Log("Fortune", arguments);
      if (typeof(word) === 'undefined')
        return this.Vision();
      else if (typeof(word) === 'string')
        return this.Prophecy(word);
      else if (typeof(word) !== 'object')
        return this.Presage(word);
      phoxy.Log(0, "birth.Fortune", word, "(Failed object recognize)");
    }
  ,
  Hope: function()
    {
      this.Log("Hope", arguments);
      var args = arguments;
      var idea = args[1];

      function DataLoadedCallback(data)
      {
        data = data || {};
        this.Decision(args[0], data, args[2], args[3]);
      }

      if (typeof(idea) === 'string')
        return this.Desire(idea, DataLoadedCallback);
      else if (typeof(idea) === 'function')
      {
        var data = this.Pray(args[1], DataLoadedCallback);
        if (typeof(data) === 'object')
          DataLoadedCallback(data);
      }
      else
        phoxy.Log(0, "birth.Hope", idea, "(Failed data receive)");
    }
  ,
  Fate: function(design, data)
    {
      this.Log("Fate", arguments);
      if (typeof(design) === 'undefined')
        return this.Vision(design, data);
      else if (typeof(design) === 'function')
        design = this.Mutation.apply(this, arguments);

      if (typeof(design) === 'string')
        return this.Conceive(design, data);
    }
  ,
  Vision: function(cb, design, data)
    {
      this.Log("Vision", arguments);
      return cb(design, data);
    }
  ,
  Prophecy: function(rpc)
    {
      this.Log("Prophecy", arguments);
      this.Plea(rpc, function on_rpc_design_received(obj)
      {
        this.Presage(obj);
      });
    }
  ,
  Presage: function(obj)
    {
      this.Log("Presage", arguments);

      // Maybe its wrong. Maybe i should ignore other params
      var design = obj.design;
      var data = obj.data || {};

      this.Boon(obj, function on_design_object_decoded()
      {
        this.Decision(design, data, this.callback);
      })
    }
  ,
  Pray: function(data_load_functor, DataLoadedCallback)
    {
      this.Log("Pray", arguments);
      return data_load_functor(DataLoadedCallback);
    }
  ,
  Mutation: function(design, data)
    {
      this.Log("Mutation", arguments);
      function DetermineAsync(design)
      {
        phoxy._.render.Fancy(design, data, args[2], args[3]);
      }

      return design(data, DetermineAsync);
    }
  ,
  Conceive: function(design, data)
    {
      this.Log("Conceive", arguments);
      var ejs_location = phoxy.Config()['ejs_dir'] + "/" + design;

      var that = this;
      function RenderCallback(html)
      {
        if (!that.raw_output)
          html = html.html;
        that.callback(html, design, data);
      }

      this.Render(ejs_location, data, RenderCallback);
    }
  ,
  Desire: function(rpc, DataLoadedCallback)
    {
      this.Log("Desire", arguments);
      this.Plea(rpc, function on_data_recieved(json)
      {
        DataLoadedCallback(json.data);
      });
    }
  ,
  Plea: function(url, cb)
    {
      this.Log("Plea", arguments);
      var that = this;
      phoxy.AJAX(url, function on_ajax_answer(obj)
      {
        that.Boon(obj, cb);
      });
    }
  ,
  Boon: function(answer, cb)
  {
    this.Log("Boon", arguments);
    var obj = EJS.IsolateContext(answer);

    // Those removed because we dont need to render anything
    delete obj.design;
    // Those ignored since it phoxy.Fancy.(low level rendering) Place to render already choosed
    delete obj.result;
    delete obj.replace;
    var that = this;
    phoxy.ApiAnswer(obj, function on_default_action_done()
    {
      cb.call(that, answer);
    });
  }
  ,
  Log: function()
    {
      this.log.push(arguments);
    }
  ,
  Render: function(design, data, cb)
  {
    var async = typeof cb === 'function';

    if (design.indexOf(".ejs") === -1)
        design += ".ejs";

    var ejs = new EJS({'url' : design}, async ? WhenReady : undefined);

    var that = this;
    function WhenReady()
    {
      function log()
      {
        that.Log.apply(that, arguments);
      }

      var obj = ejs.prepare(data);

      obj.on_complete = this.callback;
      obj.log = log;
      ejs.execute(obj);

      if (async)
        cb(obj);

      return obj;
    }

    if (!async)
      return WhenReady();
  }
}<commit_msg>For any birth method closure this<commit_after>phoxy.render =
{
  DeferRender : function (ejs, data, rendered_callback, tag)
    {
      phoxy.Log(4, "phoxy.DeferRender", arguments);
      if (tag === undefined)
        tag = '<defer_render>';
      var canvas = phoxy._.render.PrepareCanvas(tag);
      var id = canvas.id;

      phoxy._.render.RenderReplace(id, ejs, data, rendered_callback);

      if (tag === null)
        return canvas;
      return canvas.html;
    }
  ,
};

phoxy._.render =
{
  PrepareCanvas : function(tag)
    {
      if (tag === undefined)
        tag = '<div>';
      var vanilla_tag = tag.substring(1, tag.length - 1);

      var id =  phoxy._.internal.GenerateUniqueID();
      var obj = document.createElement(vanilla_tag);
      obj.setAttribute('id', id);
      var div = obj.outerHTML;

      return { id: id, obj: obj, html: div };
    }
  ,
  AsyncRender_Strategy : function (target, ejs, data, rendered_callback, difference)
    { // AsyncRender strategy: for production
      phoxy._.render.Fancy(ejs, data, function async_strategy_birth(obj, ejs, data)
      {
        if (typeof obj === 'undefined')
        {
          phoxy.Log(3, 'phoxy.Reality', 'Design render skiped. (No design was choosed?)', document.getElementById(target));
          return; // And break dependencies execution
        }

        // Potential cascade memleak
        // Should clear listeners with callback
        phoxy._.time.Appeared(target, function async_strategy_wait_for_apperance()
        {
          difference.call(phoxy, target, obj.html, arguments);
          for (var k in obj.defer)
              obj.defer[k]();
        }, undefined, -1);

        obj.on_complete = function async_strategy_on_complete()
        {
          if (typeof(rendered_callback) !== 'undefined')
            rendered_callback.call(obj.across, ejs, data, obj.html);
        };
      }, true);
    }
  ,
  SyncRender_Strategy : function (target, ejs, data, rendered_callback, difference)
    { // SyncRender strategy: for debug/develop purposes
      phoxy._.time.Appeared(target, function sync_strategy_wait_for_apperance()
      {
        phoxy._.render.Fancy(ejs, data, function sync_strategy_birth(obj, ejs, data)
        {
          if (typeof obj === 'undefined')
          {
            phoxy.Log(3, 'phoxy.Reality', 'Design render skiped. (No design was choosed?)', document.getElementById(target));
            return; // And break dependencies execution
          }

          difference.call(phoxy, target, obj.html, arguments);

          obj.on_complete = function sync_strategy_on_complete()
          {
            if (typeof(rendered_callback) !== 'undefined')
              rendered_callback.call(obj.across, ejs, data, obj.html);
          };
        }, true);
      }, undefined, -1);
    }
  ,
  RenderStrategy : "Will be replaced by selected strategy after compilation."
  ,
  RenderInto : function (target, ejs, data, rendered_callback)
    {
      var args = Array.prototype.slice.call(arguments);
      args.push(function render_into_f(target, html)
      {
        document.getElementById(target).innerHTMl = html;
      });
      phoxy._.render.RenderStrategy.apply(this, args);
    }
  ,
  RenderReplace : function (target, ejs, data, rendered_callback)
    {
      var args = Array.prototype.slice.call(arguments);
      args.push(function render_replace_f(target, html)
      {
        var that = document.getElementById(target);
        that.insertAdjacentHTML("afterEnd", html);
        that.parentNode.removeChild(that);
      });
      phoxy._.render.RenderStrategy.apply(this, args);
    }
  ,
  Render : function (design, data, callback, is_phoxy_internal_call)
    {
      phoxy.Log(0, "phoxy.Render is OBSOLETE. Use phoxy.Fancy instead");
    }
  ,
  Fancy : function()
    {
      var args = arguments;
      for (var i = 0; i < 2; i++)
        if (Array.isArray(args[i]))
        {
          args[i] = phoxy.ConstructURL(args[i]);
          return phoxy._.render.Fancy.apply(this, args);
        }

      phoxy.Log(6, "phoxy.Fancy", arguments);

      var callback = args[2];
      if (typeof(callback) === 'undefined')
        callback = function (){};

      return new phoxy._.birth(args[0], args[1], callback, true);
    }
  ,
};

phoxy._.birth = function(will, spirit, callback, raw_output)
{
  this.will = will;
  this.spirit = spirit;
  this.birth_id = phoxy._.internal.GenerateUniqueID();
  console.time("phoxy.birth " + this.birth_id);
  this.callback = function birth_log_report()
  {
    console.groupCollapsed("phoxy.birth", will);
      console.log(spirit);
      for (var k in this.log)
        console.log.apply(console, this.log[k]);

    console.timeEnd("phoxy.birth " + this.birth_id);
    console.groupEnd();

    callback.apply(this, arguments);
  }
  this.raw_output = raw_output;
  this.log = [];

  return this.Decision(will, spirit, callback);
}

phoxy._.birth.prototype =
{
  Decision: function(will, spirit)
    {
      this.Log("Decision", arguments);
      if (typeof spirit === 'undefined')
        return this.Fortune(will);
      if (typeof spirit !== 'object')
        return this.Hope(will, spirit);
      return this.Fate(will, spirit);
    }
  ,
  Fortune: function(word)
    {
      this.Log("Fortune", arguments);
      if (typeof(word) === 'undefined')
        return this.Vision();
      else if (typeof(word) === 'string')
        return this.Prophecy(word);
      else if (typeof(word) !== 'object')
        return this.Presage(word);
      phoxy.Log(0, "birth.Fortune", word, "(Failed object recognize)");
    }
  ,
  Hope: function()
    {
      this.Log("Hope", arguments);
      var args = arguments;
      var idea = args[1];

      var that = this;
      function DataLoadedCallback(data)
      {
        data = data || {};
        that.Decision(args[0], data, args[2], args[3]);
      }

      if (typeof(idea) === 'string')
        return this.Desire(idea, DataLoadedCallback);
      else if (typeof(idea) === 'function')
      {
        var data = this.Pray(args[1], DataLoadedCallback);
        if (typeof(data) === 'object')
          DataLoadedCallback(data);
      }
      else
        phoxy.Log(0, "birth.Hope", idea, "(Failed data receive)");
    }
  ,
  Fate: function(design, data)
    {
      this.Log("Fate", arguments);
      if (typeof(design) === 'undefined')
        return this.Vision(design, data);
      else if (typeof(design) === 'function')
        design = this.Mutation.apply(this, arguments);

      if (typeof(design) === 'string')
        return this.Conceive(design, data);
    }
  ,
  Vision: function(cb, design, data)
    {
      this.Log("Vision", arguments);
      return cb(design, data);
    }
  ,
  Prophecy: function(rpc)
    {
      this.Log("Prophecy", arguments);

      var that = this;
      this.Plea(rpc, function on_rpc_design_received(obj)
      {
        that.Presage(obj);
      });
    }
  ,
  Presage: function(obj)
    {
      this.Log("Presage", arguments);

      // Maybe its wrong. Maybe i should ignore other params
      var design = obj.design;
      var data = obj.data || {};

      var that = this;
      this.Boon(obj, function on_design_object_decoded()
      {
        that.Decision(design, data, that.callback);
      })
    }
  ,
  Pray: function(data_load_functor, DataLoadedCallback)
    {
      this.Log("Pray", arguments);
      return data_load_functor(DataLoadedCallback);
    }
  ,
  Mutation: function(design, data)
    {
      this.Log("Mutation", arguments);

      function DetermineAsync(design)
      {
        phoxy._.render.Fancy(design, data, args[2], args[3]);
      }

      return design(data, DetermineAsync);
    }
  ,
  Conceive: function(design, data)
    {
      this.Log("Conceive", arguments);
      var ejs_location = phoxy.Config()['ejs_dir'] + "/" + design;

      var that = this;
      function RenderCallback(html)
      {
        if (!that.raw_output)
          html = html.html;
        that.callback(html, design, data);
      }

      this.Render(ejs_location, data, RenderCallback);
    }
  ,
  Desire: function(rpc, DataLoadedCallback)
    {
      this.Log("Desire", arguments);
      this.Plea(rpc, function on_data_recieved(json)
      {
        DataLoadedCallback(json.data);
      });
    }
  ,
  Plea: function(url, cb)
    {
      this.Log("Plea", arguments);
      var that = this;
      phoxy.AJAX(url, function on_ajax_answer(obj)
      {
        that.Boon(obj, cb);
      });
    }
  ,
  Boon: function(answer, cb)
  {
    this.Log("Boon", arguments);
    var obj = EJS.IsolateContext(answer);

    // Those removed because we dont need to render anything
    delete obj.design;
    // Those ignored since it phoxy.Fancy.(low level rendering) Place to render already choosed
    delete obj.result;
    delete obj.replace;
    var that = this;
    phoxy.ApiAnswer(obj, function on_default_action_done()
    {
      cb.call(that, answer);
    });
  }
  ,
  Log: function()
    {
      this.log.push(arguments);
    }
  ,
  Render: function(design, data, cb)
  {
    var async = typeof cb === 'function';

    if (design.indexOf(".ejs") === -1)
        design += ".ejs";

    var ejs = new EJS({'url' : design}, async ? WhenReady : undefined);

    var that = this;
    function WhenReady()
    {
      function log()
      {
        that.Log.apply(that, arguments);
      }

      var obj = ejs.prepare(data);

      obj.on_complete = this.callback;
      obj.log = log;
      ejs.execute(obj);

      if (async)
        cb(obj);

      return obj;
    }

    if (!async)
      return WhenReady();
  }
}<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Footer from '../Footer/Footer'
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';

const CreateIdea = () => {
  return (

Share New Idea

Make a great impact! Start from sharing your idea!

Your Idea

Tell us about your idea

                    <form encType="multipart/form-data">

                        Your Idea's Title
                        <input type="text" className="form-control" required />

                        Featured Video (Youtube-Link)
                        <input type="text" className="form-control" required />

                        <input type="text" className="form-control" placeholder="Featured Image URL"/>

                        Upload Image
                        <input type="file" id="exampleInputFile" required/>

                        Category
                        <select className="form-control">
                          <option>Lalala</option>
                          <option>Lalala</option>
                          <option>Lalala</option>
                        </select>

                        Your Idea Detail
                        <Editor/>

                        <button type="button" className="btn btn-info">Submit</button>

                    </form>

  )
}

export default CreateIdea;
<commit_msg>the submit button<commit_after>import React, { Component } from 'react';
import Footer from '../Footer/Footer'
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';

const CreateIdea = () => {
  return (

Share New Idea

Make a great impact! Start from sharing your idea!

Your Idea

Tell us about your idea

                    <form encType="multipart/form-data">

                        Your Idea's Title
                        <input type="text" className="form-control" required />

                        Featured Video (Youtube-Link)
                        <input type="text" className="form-control" required />

                        <input type="text" className="form-control" placeholder="Featured Image URL"/>

                        Upload Image
                        <input type="file" id="exampleInputFile" required/>

                        Category
                        <select className="form-control">
                          <option>Lalala</option>
                          <option>Lalala</option>
                          <option>Lalala</option>
                        </select>

                        Your Idea Detail
                        <Editor/>

                        <button type="button" className="btn btn-info">Submit</button>

                    </form>

  )
}

export default CreateIdea;
<|endoftext|>


<commit_before>var user = require('../lib/user');

var follow = process.argv[2];

user.fromLogin(follow).then(function(user) {
  return [user, user.addFollowers(-1)];
}).spread(function(user, res) {
  console.log('Added', res.follows, 'followers to', user.login);
  process.exit(0);
});
<commit_msg>Add usage error<commit_after>var user = require('../lib/user');

var follow = process.argv[2];
if (!follow) {
  console.error('Usage: node scripts/follow <username>');
  process.exit(1);
}

user.fromLogin(follow).then(function(user) {
  return [user, user.addFollowers(-1)];
}).spread(function(user, res) {
  console.log('Added', res.follows, 'followers to', user.login);
  process.exit(0);
});
<|endoftext|>


<commit_before>/**
 * @file cmd.js
 *
 * @projectname Citation.js
 *
 * @author Lars Willighagen
 * @version 0.2.15
 * @license
 * Copyright (c) 2016 Lars Willighagen
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

var program = require( 'commander'       )
  , fs      = require( 'fs'              )
  , Cite    = require( '../index.js' )

console.debug = console.log

/*-------- Program ---------*/
program
  .version( '0.2.15' )
  .usage  ( '[options]' )

  .option ( '-i, --input <path>',
            'Input file')
  .option ( '-u, --url <url>',
            'Input url')
  .option ( '-t, --text <string>',
            'Input text')

  .option ( '-o, --output <path>',
            'Output file (omit file extension)')

  .option ( '-R, --output-non-real',
            'Do not output the file in its mime type, but as a string',
            false )
  .option ( '-f, --output-type <option>',
            'Output structure type: string, html, json',
            'json' )
  .option ( '-s, --output-style <option>',
            'Ouput scheme. A combination of --output-format json and --output-style citation-* is considered invalid. ' +
            'Options: csl (Citation Style Lanugage JSON), bibtex, citation-* (where * is any formatting style)',
            'csl' )
  .option ( '-l, --output-language <option>',
            'Output language. [RFC 5646](https://tools.ietf.org/html/rfc5646) codes',
            'en-US' )

  .parse  ( process.argv )

if ( !process.argv.slice(2).length )
  program.help()
/*--------------------------*/

/*-- Validating arguments --*/
if ( !( program.input || program.url || program.text ) ) {
  console.log( 'Please give argument input file, url or text' )
  process.exit( 1 ) }

if ( !program.output ) {
  console.log( 'Please give argument output' )
  process.exit( 1 ) }

if ( !fs.existsSync( program.input ) && program.input ) {
  console.log( 'Input file does not exist: ' + program.input )
  process.exit( 1 ) }
/*--------------------------*/

/*---------- Input ---------*/
var input

if ( program.input )
  input = fs.readFileSync( program.input, 'utf8' )
else if ( program.url || program.text )
  input = program.url || program.text
/*--------------------------*/

/*--------- Output ---------*/
var data = new Cite( input )
  , options = {
    format: 'string' ,
    type: program.outputType,
    style: program.outputStyle,
    lan: program.outputLanguage
  }
  , output = data.get( options )

if ( !program.outputNonReal && program.outputType === 'html' )
  output = '<!DOCTYPE html><meta charset="UTF-8">' + output + ''
/*--------------------------*/

/*-------- Extension -------*/
var extension

if ( program.outputStyle === 'bibtex' && program.outputType === 'string' )
  extension = '.bib'

else if ( program.outputNonReal )
  extension = '.txt'

else
  extension = ( '.' + {
    string: 'txt',
    html: 'html',
    json: 'json'
  }[ program.outputType ] )
/*--------------------------*/

fs.writeFileSync( program.output + extension, output )<commit_msg>Refixed #30<commit_after>#!/usr/bin/env node

/**
 * @file cmd.js
 *
 * @projectname Citation.js
 *
 * @author Lars Willighagen
 * @version 0.2.15
 * @license
 * Copyright (c) 2016 Lars Willighagen
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

var program = require( 'commander'       )
  , fs      = require( 'fs'              )
  , Cite    = require( '../index.js' )

console.debug = console.log

/*-------- Program ---------*/
program
  .version( '0.2.15' )
  .usage  ( '[options]' )

  .option ( '-i, --input <path>',
            'Input file')
  .option ( '-u, --url <url>',
            'Input url')
  .option ( '-t, --text <string>',
            'Input text')

  .option ( '-o, --output <path>',
            'Output file (omit file extension)')

  .option ( '-R, --output-non-real',
            'Do not output the file in its mime type, but as a string',
            false )
  .option ( '-f, --output-type <option>',
            'Output structure type: string, html, json',
            'json' )
  .option ( '-s, --output-style <option>',
            'Ouput scheme. A combination of --output-format json and --output-style citation-* is considered invalid. ' +
            'Options: csl (Citation Style Lanugage JSON), bibtex, citation-* (where * is any formatting style)',
            'csl' )
  .option ( '-l, --output-language <option>',
            'Output language. [RFC 5646](https://tools.ietf.org/html/rfc5646) codes',
            'en-US' )

  .parse  ( process.argv )

if ( !process.argv.slice(2).length )
  program.help()
/*--------------------------*/

/*-- Validating arguments --*/
if ( !( program.input || program.url || program.text ) ) {
  console.log( 'Please give argument input file, url or text' )
  process.exit( 1 ) }

if ( !program.output ) {
  console.log( 'Please give argument output' )
  process.exit( 1 ) }

if ( !fs.existsSync( program.input ) && program.input ) {
  console.log( 'Input file does not exist: ' + program.input )
  process.exit( 1 ) }
/*--------------------------*/

/*---------- Input ---------*/
var input

if ( program.input )
  input = fs.readFileSync( program.input, 'utf8' )
else if ( program.url || program.text )
  input = program.url || program.text
/*--------------------------*/

/*--------- Output ---------*/
var data = new Cite( input )
  , options = {
    format: 'string' ,
    type: program.outputType,
    style: program.outputStyle,
    lan: program.outputLanguage
  }
  , output = data.get( options )

if ( !program.outputNonReal && program.outputType === 'html' )
  output = '<!DOCTYPE html><meta charset="UTF-8">' + output + ''
/*--------------------------*/

/*-------- Extension -------*/
var extension

if ( program.outputStyle === 'bibtex' && program.outputType === 'string' )
  extension = '.bib'

else if ( program.outputNonReal )
  extension = '.txt'

else
  extension = ( '.' + {
    string: 'txt',
    html: 'html',
    json: 'json'
  }[ program.outputType ] )
/*--------------------------*/

fs.writeFileSync( program.output + extension, output )<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var collectParallel = require('collect-parallel/array');
var allocCluster = require('../lib/test-cluster.js');

allocCluster.test('find connections for service', {
    size: 10,
    dummySize: 5
}, function t(cluster, assert) {
    var apps = cluster.apps;
    var dummies = cluster.dummies;
    var entryNode = apps[0];

    setup();

    function setup() {
        assert.comment('-- setup');

        collectParallel(
            dummies,
            function registerEach(dummy, i, done) {
                cluster.sendRegister(dummy, {
                    serviceName: 'Dummy'
                }, done);
            },
            function finishRegister(_, results) {
                for (var i = 0; i < results.length; i++) {
                    var res = results[i];
                    assert.ifError(res.err, 'no unexpected error from register ' + i);
                }
                runTest();
            }
        );
    }

    function runTest() {
        assert.comment('-- runTest');

        pruneClusterPears(cluster, assert, runTestPruneDone);
    }

    function runTestPruneDone() {
        assert.comment('-- runTestPruneDone');

        cluster.checkExitPeers(assert, {
            serviceName: 'Dummy',
            hostPort: dummies[0].hostPort
        });

        entryNode.client.getConnections({
            serviceName: 'Dummy'
        }, onResults);
    }

    function onResults(err, resp) {
        assert.comment('-- onResults');

        if (err) {
            finish(err);
            return;
        }

        var exitHosts = entryNode.hostsFor('Dummy');

        var body = resp.body;
        assert.deepEqual(
            exitHosts.sort(),
            Object.keys(body).sort(),
            'got expected exit hosts back');

        Object.keys(body).forEach(function checkInstances(key) {
            if (body[key].err) {
                assert.ifError(body[key].err);
                return;
            }

            var exitInstances = body[key].instances;

            Object.keys(exitInstances).forEach(function checkInst(key2) {
                var exitInstance = exitInstances[key2];

                var isConnected = exitInstance.connected.out ||
                    exitInstance.connected.in;

                assert.equal(isConnected, true,
                    'exit instance is connected');
            });
        });

        finish(null);
    }

    function finish(err) {
        assert.comment('-- finish');
        assert.ifError(err);

        assert.end();
    }
});

function pruneClusterPears(cluster, assert, callback) {
    collectParallel(
        cluster.apps,
        function pruneEach(app, i, done) {
            var serviceProxy = app.clients.serviceProxy;
            serviceProxy.peerPruner.run(done);
        },
        function finish(_, results) {
            for (var i = 0; i < results.length; i++) {
                var res = results[i];
                assert.ifError(res.err, 'no error from pruning app ' + i);
            }
            callback();
        }
    );
}
<commit_msg>test/connections/happy-path: refactor the all connected check<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var collectParallel = require('collect-parallel/array');
var allocCluster = require('../lib/test-cluster.js');

allocCluster.test('find connections for service', {
    size: 10,
    dummySize: 5
}, function t(cluster, assert) {
    var apps = cluster.apps;
    var dummies = cluster.dummies;
    var entryNode = apps[0];

    setup();

    function setup() {
        assert.comment('-- setup');

        collectParallel(
            dummies,
            function registerEach(dummy, i, done) {
                cluster.sendRegister(dummy, {
                    serviceName: 'Dummy'
                }, done);
            },
            function finishRegister(_, results) {
                for (var i = 0; i < results.length; i++) {
                    var res = results[i];
                    assert.ifError(res.err, 'no unexpected error from register ' + i);
                }
                runTest();
            }
        );
    }

    function runTest() {
        assert.comment('-- runTest');

        pruneClusterPears(cluster, assert, runTestPruneDone);
    }

    function runTestPruneDone() {
        assert.comment('-- runTestPruneDone');

        cluster.checkExitPeers(assert, {
            serviceName: 'Dummy',
            hostPort: dummies[0].hostPort
        });

        entryNode.client.getConnections({
            serviceName: 'Dummy'
        }, onResults);
    }

    function onResults(err, resp) {
        assert.comment('-- onResults');

        if (err) {
            finish(err);
            return;
        }

        var exitHosts = entryNode.hostsFor('Dummy');

        var body = resp.body;
        assert.deepEqual(
            exitHosts.sort(),
            Object.keys(body).sort(),
            'got expected exit hosts back');

        Object.keys(body).forEach(function checkInstances(key) {
            if (body[key].err) {
                assert.ifError(body[key].err);
                return;
            }

            var exitInstances = body[key].instances;
            var areConnected = Object.keys(exitInstances).map(function getInstanceConnected(key2) {
                var exitInstance = exitInstances[key2];
                return exitInstance.connected.out ||
                       exitInstance.connected.in;
            });

            assert.ok(areConnected.every(boolEye),
                      'all exit instances are connected');
        });

        finish(null);
    }

    function finish(err) {
        assert.comment('-- finish');
        assert.ifError(err);

        assert.end();
    }
});

function pruneClusterPears(cluster, assert, callback) {
    collectParallel(
        cluster.apps,
        function pruneEach(app, i, done) {
            var serviceProxy = app.clients.serviceProxy;
            serviceProxy.peerPruner.run(done);
        },
        function finish(_, results) {
            for (var i = 0; i < results.length; i++) {
                var res = results[i];
                assert.ifError(res.err, 'no error from pruning app ' + i);
            }
            callback();
        }
    );
}

function boolEye(x) {
    return !!x;
}
<|endoftext|>


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

    /*
     * Implementation notes:
     *
     * - a grid is indexed (y,x) because ultimately it's easier for me to
     *   write array literals indexed like this
     */

    /*
     * Application declarations and definitions
     */
    var element = document.getElementById('board'),
        context = element.getElementsByTagName('canvas')[0].getContext('2d'),
        wWidth = window.innerWidth,
        wHeight = window.innerHeight - 50,
        size = 8,
        tileSide,
        radius,
        setup,
        main;

    /*
     * Color configuration
     */
    var colors = [
        '#F5B437', // 0:  orange
        '#3340AE', // 1:  blue
        '#1E8AD1', // 2:  sky
        '#F8D6C4', // 3:  pink
        '#F6E500', // 4:  yellow
        '#DC442F', // 5:  red
        '#BAD360', // 6:  green
        '#6B451E', // 7:  brown
        '#080D07', // 8:  player 0
        '#F4FFF4'  // 9:  player 1
    ];

    var tileColorPattern = [
        [0,1,2,3,4,5,6,7],
        [5,0,3,6,1,4,7,2],
        [6,3,0,5,2,7,4,1],
        [3,2,1,0,7,6,5,4],
        [4,5,6,7,0,1,2,3],
        [1,4,7,2,5,0,3,6],
        [2,7,4,1,6,3,0,5],
        [7,6,5,4,3,2,1,0]
    ];

    /*
     * Utilities
     */

    function min(a,b) {
        return (a < b) ? a : b;
    }

    Array.prototype.repeat = function(what, L) {
        while (L) {
            this[--L] = what;
        }
        return this;
    };

    // globally unique ID generator
    // usage: guid() -- different output each time
    var guid = (function() {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
                .toString(16)
                .substring(1);
        }

        return function() {
            return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
                   s4() + '-' + s4() + s4() + s4();
        };
    })();

    function parseHash() {
        var hash = location.hash.slice(1);
        if (hash === '') {
            hash = guid();
            location.hash = '#' + hash;
        }
        return hash;
    }

    // simple coordinate pair
    function Pos(x, y) {
        this.x = x;
        this.y = y;
    }

    function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return new Pos(evt.clientX - rect.left,
                       evt.clientY - rect.top);
    }

    // comonadic wrapper around a grid state
    function Board(grid, pos, gameId, selected, player) {
        this.grid = grid;
        this.pos   = pos;

        this.selected = typeof selected !== 'undefined'
            ? selected
            : null;

        this.player = typeof player !== 'undefined'
            ? player
            : 0;

        this.gameId = typeof gameId !== 'undefined'
            ? gameId
            : 'test-game';
    }

    Board.prototype.save = function() {
        var state = {
            grid     : this.grid,
            player   : this.player,
            gameId   : this.gameId,
            selected : this.selected
        };
        localStorage.setItem(this.gameId,
                JSON.stringify(state));
        console.log('saved as gameId = ' + this.gameId);
    };

    Board.prototype.updatePos = function(pos) {
        this.pos = pos;
        return this;
    };

    Board.prototype.extract = function() {
        return this.grid[this.pos.y][this.pos.x];
    };

    Board.prototype.duplicate = function() {
        var me = this, oldGrid = this.grid;
        var x, y, grid = [];
        for (y = 0; y < me.grid.length; y++) {
            grid[y] = [];
            for (x = 0; x < me.grid[y].length; x++) {
                grid[y][x] = new Board(oldGrid, new Pos(x, y),
                                       me.gameId, me.selected,
                                       me.player);
            }
        }
        this.grid = grid;
        return this;
    };

    Board.prototype.map = function(f) {
        var x, y, grid = [], me = this;
        for (y = 0; y < me.grid.length; y++) {
            grid[y] = [];
            for (x = 0; x < me.grid[y].length; x++) {
                grid[y][x] = f(me.grid[y][x]);
            }
        }
        this.grid = grid;
        return this;
    };

    Board.prototype.extend = Comonad.prototype.extend;

    // Called on every refresh for each cell on the grid.
    function drawCell (ptr) { return new IO(function() {

        // draw the background color
        var cell = ptr.extract();
        var cellColor = colors[tileColorPattern[ptr.pos.y][ptr.pos.x]];
        context.fillStyle = cellColor;
        context.fillRect(ptr.pos.x * tileSide, ptr.pos.y * tileSide,
                                     tileSide,             tileSide);

        if (cell === 0) { return cell; }

        // if there is a piece on this cell, draw it as well
        var x = ptr.pos.x + 1;
        var y = ptr.pos.y + 1;
        var center = {
            x: ((x) * tileSide) - (tileSide / 2),
            y: ((y) * tileSide) - (tileSide / 2)
        };

        var bezel = (cell > size) ? colors[9] : colors[8];
        var color = colors[(cell - 1) % 8];

        // bezel
        context.beginPath();
        context.arc(center.x, center.y, radius, 0,
                Math.PI*2, false);
        context.closePath();
        context.fillStyle = bezel;
        context.fill();
        context.strokeStyle = bezel;
        context.stroke();

        // piece color
        context.beginPath();
        context.arc(center.x, center.y, radius * 0.75, 0,
                Math.PI*2, false);
        context.closePath();
        context.fillStyle = color;
        context.fill();
        context.strokeStyle = color;
        context.stroke();

        if (ptr.selected !== null         &&
            ptr.selected.x === ptr.pos.x &&
            ptr.selected.y === ptr.pos.y) {
            context.beginPath();
            context.arc(center.x, center.y, radius * 0.5, 0,
                    Math.PI*2, false);
            context.fillStyle = bezel;
            context.fill();
            context.strokeStyle = bezel;
            context.stroke();
        }

        return cell;
    }).start(); }

    Board.prototype.drawCells = function() {
        return this.extend(drawCell);
    };

    // Called from clicked(), so this.pos is the position that has been
    // clicked. The piece is starting from this.selected
    Board.prototype.legalMove = function() {
        // direction dependent: if the current player is 0, they are going
        // "down" the page, and vice versa for player 1.

        // FIXME
        // This does not take into account if any pieces are blocking you
        return ((this.player ? this.selected.y > this.pos.y
                             : this.selected.y < this.pos.y)
            &&  (this.extract() === 0)
            && ((Math.abs(this.selected.x - this.pos.x)
            ===  Math.abs(this.selected.y - this.pos.y))
            ||  (this.selected.x - this.pos.x) === 0));
    };

    Board.prototype.clicked = function(clickPos) {
        var cell = this.updatePos(clickPos).extract();
        console.log("Clicked: x = " + this.pos.x + ", y = " + this.pos.y);
        console.log(this.extract());

        if (this.selected === null) {
            this.selected = new Pos(-1, -1);
        }

        // is this cell already selected?
        if (this.selected.x === this.pos.x &&
            this.selected.y === this.pos.y) {
            // do nothing
            this.player = (this.player) ? 0 : 1;
            this.selectNextPiece();
            return this;
        }

        else {
            // not selected and the cell contains a piece
            // -> select this new piece
            if (cell > 0) {
                this.selected = this.pos;
            }

            // not selected and cell does not contain a piece
            // -> move the currently selected piece here
            if (cell === 0) {
                if (!this.legalMove()) {
                    return this;
                }
                // else ...
                this.grid[this.pos.y][this.pos.x] =
                    this.grid[this.selected.y][this.selected.x];
                this.grid[this.selected.y][this.selected.x] = 0;

                this.selected.x = this.pos.x;
                this.selected.y = this.pos.y;

                this.player = (this.player) ? 0 : 1 ;
                console.log("moved. switched to player " + this.player);

            }
        }

        this.selectNextPiece();
        this.save();
        return this;
    };

    Board.prototype.selectNextPiece = function() {
        var x, y, nextCell;
        var selectedColor = tileColorPattern[this.selected.y][this.selected.x];
        var nextPiece = (selectedColor + 1) + (this.player * 8);
        for (y = 0; y < this.grid.length; y++) {
            for (x = 0; x < this.grid[y].length; x++) {
                nextCell = this.grid[y][x];
                if (nextCell === nextPiece) {
                    this.selected.x = x;
                    this.selected.y = y;
                    break;
                }
            }
        }
    };

    function getBoard() {
        return new IO(function() {
            var hash = parseHash();
            var saved = JSON.parse(localStorage.getItem(hash));
            if (saved === null) {
                var grid = [], y;
                for (y = 1; y < (size-1); y++) {
                    grid[y] = [].repeat(0, 8);
                }
                grid[0] = [  1,  2,  3,  4,  5,  6,  7, 8 ];
                grid[7] = [ 16, 15, 14, 13, 12, 11, 10, 9 ];
                return new Board(grid, new Pos(0, 0), hash);
            }
            else {
                return new Board(saved.grid, new Pos(0, 0),
                                 saved.gameId,
                                 saved.selected, saved.player);
            }
        });
    }

    setup = new IO(function() {
        context.canvas.width = 0.9*(min(wWidth, wHeight));
        context.canvas.height = context.canvas.width;
        tileSide = ((0.9*min(wWidth, wHeight)) / size);
        radius = (tileSide * 0.9) / 2;
    });

    function listen(board) {
        return new IO(function() {
            context.canvas.addEventListener('click', function(evt) {
                var mousePos = getMousePos(this, evt);
                mousePos.x = Math.floor(mousePos.x / tileSide);
                mousePos.y = Math.floor(mousePos.y / tileSide);
                board
                    .clicked(mousePos)
                    .drawCells();
            });
            document.getElementById('new-game')
                .addEventListener('click', function() {
                console.log("clicked new game");
                location.hash = '';
                location.reload();
            });
        });
    }

    main = setup.
            chain(getBoard).
            chain(function (board) { return new IO.of(board.drawCells()); }).
            chain(listen);

    main.start();

})();
<commit_msg>removed extraneous log commands, as well as a pointless new keyword<commit_after>(function() {
    'use strict';

    /*
     * Implementation notes:
     *
     * - a grid is indexed (y,x) because ultimately it's easier for me to
     *   write array literals indexed like this
     */

    /*
     * Application declarations and definitions
     */
    var element = document.getElementById('board'),
        context = element.getElementsByTagName('canvas')[0].getContext('2d'),
        wWidth = window.innerWidth,
        wHeight = window.innerHeight - 50,
        size = 8,
        tileSide,
        radius,
        setup,
        main;

    /*
     * Color configuration
     */
    var colors = [
        '#F5B437', // 0:  orange
        '#3340AE', // 1:  blue
        '#1E8AD1', // 2:  sky
        '#F8D6C4', // 3:  pink
        '#F6E500', // 4:  yellow
        '#DC442F', // 5:  red
        '#BAD360', // 6:  green
        '#6B451E', // 7:  brown
        '#080D07', // 8:  player 0
        '#F4FFF4'  // 9:  player 1
    ];

    var tileColorPattern = [
        [0,1,2,3,4,5,6,7],
        [5,0,3,6,1,4,7,2],
        [6,3,0,5,2,7,4,1],
        [3,2,1,0,7,6,5,4],
        [4,5,6,7,0,1,2,3],
        [1,4,7,2,5,0,3,6],
        [2,7,4,1,6,3,0,5],
        [7,6,5,4,3,2,1,0]
    ];

    /*
     * Utilities
     */

    function min(a,b) {
        return (a < b) ? a : b;
    }

    Array.prototype.repeat = function(what, L) {
        while (L) {
            this[--L] = what;
        }
        return this;
    };

    // globally unique ID generator
    // usage: guid() -- different output each time
    var guid = (function() {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
                .toString(16)
                .substring(1);
        }

        return function() {
            return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
                   s4() + '-' + s4() + s4() + s4();
        };
    })();

    function parseHash() {
        var hash = location.hash.slice(1);
        if (hash === '') {
            hash = guid();
            location.hash = '#' + hash;
        }
        return hash;
    }

    // simple coordinate pair
    function Pos(x, y) {
        this.x = x;
        this.y = y;
    }

    function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return new Pos(evt.clientX - rect.left,
                       evt.clientY - rect.top);
    }

    // comonadic wrapper around a grid state
    function Board(grid, pos, gameId, selected, player) {
        this.grid = grid;
        this.pos   = pos;

        this.selected = typeof selected !== 'undefined'
            ? selected
            : null;

        this.player = typeof player !== 'undefined'
            ? player
            : 0;

        this.gameId = typeof gameId !== 'undefined'
            ? gameId
            : 'test-game';
    }

    Board.prototype.save = function() {
        var state = {
            grid     : this.grid,
            player   : this.player,
            gameId   : this.gameId,
            selected : this.selected
        };
        localStorage.setItem(this.gameId,
                JSON.stringify(state));
    };

    Board.prototype.updatePos = function(pos) {
        this.pos = pos;
        return this;
    };

    Board.prototype.extract = function() {
        return this.grid[this.pos.y][this.pos.x];
    };

    Board.prototype.duplicate = function() {
        var me = this, oldGrid = this.grid;
        var x, y, grid = [];
        for (y = 0; y < me.grid.length; y++) {
            grid[y] = [];
            for (x = 0; x < me.grid[y].length; x++) {
                grid[y][x] = new Board(oldGrid, new Pos(x, y),
                                       me.gameId, me.selected,
                                       me.player);
            }
        }
        this.grid = grid;
        return this;
    };

    Board.prototype.map = function(f) {
        var x, y, grid = [], me = this;
        for (y = 0; y < me.grid.length; y++) {
            grid[y] = [];
            for (x = 0; x < me.grid[y].length; x++) {
                grid[y][x] = f(me.grid[y][x]);
            }
        }
        this.grid = grid;
        return this;
    };

    Board.prototype.extend = Comonad.prototype.extend;

    // Called on every refresh for each cell on the grid.
    function drawCell (ptr) { return new IO(function() {

        // draw the background color
        var cell = ptr.extract();
        var cellColor = colors[tileColorPattern[ptr.pos.y][ptr.pos.x]];
        context.fillStyle = cellColor;
        context.fillRect(ptr.pos.x * tileSide, ptr.pos.y * tileSide,
                                     tileSide,             tileSide);

        if (cell === 0) { return cell; }

        // if there is a piece on this cell, draw it as well
        var x = ptr.pos.x + 1;
        var y = ptr.pos.y + 1;
        var center = {
            x: ((x) * tileSide) - (tileSide / 2),
            y: ((y) * tileSide) - (tileSide / 2)
        };

        var bezel = (cell > size) ? colors[9] : colors[8];
        var color = colors[(cell - 1) % 8];

        // bezel
        context.beginPath();
        context.arc(center.x, center.y, radius, 0,
                Math.PI*2, false);
        context.closePath();
        context.fillStyle = bezel;
        context.fill();
        context.strokeStyle = bezel;
        context.stroke();

        // piece color
        context.beginPath();
        context.arc(center.x, center.y, radius * 0.75, 0,
                Math.PI*2, false);
        context.closePath();
        context.fillStyle = color;
        context.fill();
        context.strokeStyle = color;
        context.stroke();

        if (ptr.selected !== null         &&
            ptr.selected.x === ptr.pos.x &&
            ptr.selected.y === ptr.pos.y) {
            context.beginPath();
            context.arc(center.x, center.y, radius * 0.5, 0,
                    Math.PI*2, false);
            context.fillStyle = bezel;
            context.fill();
            context.strokeStyle = bezel;
            context.stroke();
        }

        return cell;
    }).start(); }

    Board.prototype.drawCells = function() {
        return this.extend(drawCell);
    };

    // Called from clicked(), so this.pos is the position that has been
    // clicked. The piece is starting from this.selected
    Board.prototype.legalMove = function() {
        // direction dependent: if the current player is 0, they are going
        // "down" the page, and vice versa for player 1.

        // FIXME
        // This does not take into account if any pieces are blocking you
        return ((this.player ? this.selected.y > this.pos.y
                             : this.selected.y < this.pos.y)
            &&  (this.extract() === 0)
            && ((Math.abs(this.selected.x - this.pos.x)
            ===  Math.abs(this.selected.y - this.pos.y))
            ||  (this.selected.x - this.pos.x) === 0));
    };

    Board.prototype.clicked = function(clickPos) {
        var cell = this.updatePos(clickPos).extract();

        if (this.selected === null) {
            this.selected = new Pos(-1, -1);
        }

        // is this cell already selected?
        if (this.selected.x === this.pos.x &&
            this.selected.y === this.pos.y) {
            // do nothing
            this.player = (this.player) ? 0 : 1;
            this.selectNextPiece();
            return this;
        }

        else {
            // not selected and the cell contains a piece
            // -> select this new piece
            if (cell > 0) {
                this.selected = this.pos;
            }

            // not selected and cell does not contain a piece
            // -> move the currently selected piece here
            if (cell === 0) {
                if (!this.legalMove()) {
                    return this;
                }
                // else ...
                this.grid[this.pos.y][this.pos.x] =
                    this.grid[this.selected.y][this.selected.x];
                this.grid[this.selected.y][this.selected.x] = 0;

                this.selected.x = this.pos.x;
                this.selected.y = this.pos.y;

                this.player = (this.player) ? 0 : 1 ;
            }
        }

        this.selectNextPiece();
        this.save();
        return this;
    };

    Board.prototype.selectNextPiece = function() {
        var x, y, nextCell;
        var selectedColor = tileColorPattern[this.selected.y][this.selected.x];
        var nextPiece = (selectedColor + 1) + (this.player * 8);
        for (y = 0; y < this.grid.length; y++) {
            for (x = 0; x < this.grid[y].length; x++) {
                nextCell = this.grid[y][x];
                if (nextCell === nextPiece) {
                    this.selected.x = x;
                    this.selected.y = y;
                    break;
                }
            }
        }
    };

    function getBoard() {
        return new IO(function() {
            var hash = parseHash();
            var saved = JSON.parse(localStorage.getItem(hash));
            if (saved === null) {
                var grid = [], y;
                for (y = 1; y < (size-1); y++) {
                    grid[y] = [].repeat(0, 8);
                }
                grid[0] = [  1,  2,  3,  4,  5,  6,  7, 8 ];
                grid[7] = [ 16, 15, 14, 13, 12, 11, 10, 9 ];
                return new Board(grid, new Pos(0, 0), hash);
            }
            else {
                return new Board(saved.grid, new Pos(0, 0),
                                 saved.gameId,
                                 saved.selected, saved.player);
            }
        });
    }

    setup = new IO(function() {
        context.canvas.width = 0.9*(min(wWidth, wHeight));
        context.canvas.height = context.canvas.width;
        tileSide = ((0.9*min(wWidth, wHeight)) / size);
        radius = (tileSide * 0.9) / 2;
    });

    function listen(board) {
        return new IO(function() {
            context.canvas.addEventListener('click', function(evt) {
                var mousePos = getMousePos(this, evt);
                mousePos.x = Math.floor(mousePos.x / tileSide);
                mousePos.y = Math.floor(mousePos.y / tileSide);
                board
                    .clicked(mousePos)
                    .drawCells();
            });
            document.getElementById('new-game')
                .addEventListener('click', function() {
                location.hash = '';
                location.reload();
            });
        });
    }

    main = setup.
            chain(getBoard).
            chain(function (board) { return IO.of(board.drawCells()); }).
            chain(listen);

    main.start();

})();
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert'),
    HtmlReport = require('./report.js').HtmlReport,

    FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m,
    FN_ARG_SPLIT = /,/,
    STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;

function introspect(object, closure) {

    for (var property in object) {
        if (object.hasOwnProperty(property)) {
            closure.call(undefined, property);
        }
    }
}

function build(context, dependencies) {

    var message = "";
    introspect(context, function (clause) {
        message += contextualize(clause, dependencies) + "\n";
    });
    return message;
}

function contextualize(message, dependencies) {

    introspect(dependencies, function (variable) {
        message = message.replace(new RegExp("\\${" + variable + "}", "gi"), dependencies[variable]);
    });
    return message;
}

function lookup(regexp, object) {

    for (var property in object) {
        if (object.hasOwnProperty(property) && regexp.test(property)) {
            return object[property];
        }
    }
}

function bddify(object) {

    return {
        get before() {
            return lookup(/^([b|B]efore).*/, object);
        },
        get given() {
            return lookup(/^([g|G]iven).*/, object);
        },
        get when() {
            return lookup(/^([w|W]hen).*/, object);
        },
        get then() {
            return lookup(/^([t|T]hen).*/, object);
        },
        get where() {
            return lookup(/^([w|W]here).*/, object);
        }
    };
}

/**
 * Call fn and inject dependencies matching in arguments.
 *
 * @param fn is the function called
 * @param scope is the 'this' pass through to fn
 * @param args contains values injected as dependencies to fn
 */
function di(fn, scope, args) {

    var dependencies = [];
    if (!fn) {
        return;
    }
    fn.toString().replace(STRIP_COMMENTS, '').match(FN_ARGS)[1].split(FN_ARG_SPLIT).forEach(function (arg) {
        dependencies.push(args[arg.trim()]);
    });

    fn.apply(scope, dependencies);
}

/**
 * Describe your test with a fluent DSL.
 *
 * e.g
 *  khan({
 *      given:  [object],
 *      when:   [function],
 *      then:   [function],
 *      where:  [list of object]
 *  });
 *
 * @param context describe the expected behaviour.
 */
function khan(context) {

    return function () {
        var bdd = bddify(context);
        assert(!bdd.given || !bdd.where, "given & when shouldn't be defined for a test as they are semantically identical");
        var where = bdd.where || [],
            report = new HtmlReport();
        if (bdd.given) {
            where.splice(0, 0, bdd.given);
        }
        where.forEach(function (given) {
            try {
                var scope = {};
                di(bdd.before, scope, given);
                di(bdd.when, scope, given);
                di(bdd.then, scope, given);
                report.dump(build(context, given));
            } catch (assertion) {
                report.done();
                throw assertion;
            }
        });
        report.done();
    };
}

exports.khan = khan;<commit_msg>Rename given to variables<commit_after>"use strict";

var assert = require('assert'),
    HtmlReport = require('./report.js').HtmlReport,

    FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m,
    FN_ARG_SPLIT = /,/,
    STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;

function introspect(object, closure) {

    for (var property in object) {
        if (object.hasOwnProperty(property)) {
            closure.call(undefined, property);
        }
    }
}

function build(context, dependencies) {

    var message = "";
    introspect(context, function (clause) {
        message += contextualize(clause, dependencies) + "\n";
    });
    return message;
}

function contextualize(message, dependencies) {

    introspect(dependencies, function (variable) {
        message = message.replace(new RegExp("\\${" + variable + "}", "gi"), dependencies[variable]);
    });
    return message;
}

function lookup(regexp, object) {

    for (var property in object) {
        if (object.hasOwnProperty(property) && regexp.test(property)) {
            return object[property];
        }
    }
}

function bddify(object) {

    return {
        get before() {
            return lookup(/^([b|B]efore).*/, object);
        },
        get given() {
            return lookup(/^([g|G]iven).*/, object);
        },
        get when() {
            return lookup(/^([w|W]hen).*/, object);
        },
        get then() {
            return lookup(/^([t|T]hen).*/, object);
        },
        get where() {
            return lookup(/^([w|W]here).*/, object);
        }
    };
}

/**
 * Call fn and inject dependencies matching in arguments.
 *
 * @param fn is the function called
 * @param scope is the 'this' pass through to fn
 * @param args contains values injected as dependencies to fn
 */
function di(fn, scope, args) {

    var dependencies = [];
    if (!fn) {
        return;
    }
    fn.toString().replace(STRIP_COMMENTS, '').match(FN_ARGS)[1].split(FN_ARG_SPLIT).forEach(function (arg) {
        dependencies.push(args[arg.trim()]);
    });

    fn.apply(scope, dependencies);
}

/**
 * Describe your test with a fluent DSL.
 *
 * e.g
 *  khan({
 *      given:  [object],
 *      when:   [function],
 *      then:   [function],
 *      where:  [list of object]
 *  });
 *
 * @param context describe the expected behaviour.
 */
function khan(context) {

    return function () {
        var bdd = bddify(context);
        assert(!bdd.given || !bdd.where, "given & when shouldn't be defined for a test as they are semantically identical");
        var where = bdd.where || [],
            report = new HtmlReport();
        if (bdd.given) {
            where.splice(0, 0, bdd.given);
        }
        where.forEach(function (variables) {
            try {
                var scope = {};
                di(bdd.before, scope, variables);
                di(bdd.when, scope, variables);
                di(bdd.then, scope, variables);
                report.dump(build(context, variables));
            } catch (assertion) {
                report.done();
                throw assertion;
            }
        });
        report.done();
    };
}

exports.khan = khan;<|endoftext|>


<commit_before>Vue.component('cloudprovider-select', {
    template: '
\

',
    props: ['cloudproviders', 'value'],
    methods: {
        updateValue: function (value) {
            this.$emit('input', value)
        }
    }
});

Vue.component('cell-select', {
    template: '
\

',
    props: ['cells', 'value'],
    methods: {
        updateValue: function (value) {
            this.$emit('input', value);
        },
        updateCellValue: function(value) {
            this.$emit('cellchange', value);
            this.$emit('imagenamechange', value)
        }
    }
});

Vue.component('baseimage-select', {
    template: '
\
 \
\

',
    props: ['imagenames', 'baseimages', 'imagenamevalue', 'baseimagevalue', 'inadvanced'],
    methods: {
        updateBaseImage: function (value) {
            this.$emit('baseimagechange', value)
        },
        updateImageName: function (value) {
            this.$emit('imagenamechange', value)
        },
        helpClick: function (value) {
            this.$emit('helpclick')
        }
    }
});

Vue.component('base-image-help', {
    template: '<help-table v-bind:headers="baseImageHelpHeaders" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            baseImageHelpHeaders: [{ name: 'Publish Date', headerClass: 'col-sm-2' },
            { name: 'Name', headerClass: 'col-sm-1' },
            { name: 'Id', headerClass: 'col-sm-1' },
            { name: 'Qualified', headerClass: 'col-sm-1' },
            { name: 'Description', headerClass: 'col-sm-4' },
            { name: 'Acceptance', headerClass: 'col-sm-4' }],
            keys: ['publish_date', 'abstract_name', 'provider_name', 'qualified', 'description', 'acceptance']
        }
    },
}
)

Vue.component('add-config-button', {
    template: '
\
    <button type="button" class="deployToolTip btn btn-default btn-sm"\
        data-toggle="modal" v-bind:data-target="target">\
            {{text}}\
        </button>\

',
    props: ['text', 'target'],
});

Vue.component('data-config-field', {
    template: '
\
        {{name}}\

\
            <input class="form-control" type="text" v-bind:value="value" v-on:input="change(name,$event.target.value)" v-bind:readonly="readonly ? true : false"></input>\

\

\
            <button type="button" class="delete_button btn btn-default" v-on:click="deleteConfig(name)" v-bind:disabled="readonly ? true : false">Delete</button>\

\

',
    props: ['name', 'value', 'readonly'],
    methods: {
        change: function (name, value) {
            this.$emit("change", { name: name, value: value })
        },
        deleteConfig: function (name) {
            this.$emit('deleteConfig', name)
        }
    }
});

Vue.component('data-config-readonly-field', {
    template: '
\
        {{name}}\

\
            <input class="form-control" type="text" v-bind:value="value"  v-bind:readonly="readonly ? true : false"></input>\

\

',
    props: ['name', 'value', 'readonly']
});

Vue.component('aws-user-data', {
    template: '
\
    <data-config-field v-for="data in alluserdata" v-bind:name="data.name" v-bind:value="data.value" v-bind:readonly="data.readonly" v-bind:inadvanced="inadvanced"\
     v-show="shouldShow(data.name)" v-on:change="change" v-on:deleteConfig="deleteConfig"></data-config-field>\

',
    props: ['alluserdata', 'inadvanced', 'showcmpgroup'],
    methods: {
        change: function (value) {
            this.$emit("change", value)
        },
        deleteConfig: function (name) {
            this.$emit('deleteconfig', name)
        },
        shouldShow: function (name) {
            if (this.inadvanced) {
                return this.showcmpgroup ? true : name != "cmp_group"
            }
            else {
                return !name.startsWith("pinfo_") && name != "cmp_group"
            }
        }
    }
});

Vue.component('aws-readonly-user-data', {
    template: '
\
    <data-config-readonly-field v-for="data in alluserdata" v-bind:name="data.name" v-bind:value="data.value" v-bind:readonly="data.readonly" v-bind:inadvanced="inadvanced"\
     v-show="shouldShow(data.name)"></data-config-readonly-field>\

',
    props: ['alluserdata', 'inadvanced', 'showcmpgroup'],
    methods: {
        shouldShow: function (name) {
            if (this.inadvanced) {
                return this.showcmpgroup ? true : name != "cmp_group"
            }
            else {
                return !name.startsWith("pinfo_") && name != "cmp_group"
            }
        }
    }
});

Vue.component('add-config-button', {
    template: '<button type="button" class="deployToolTip btn btn-default btn-sm" data-toggle="modal" v-bind:data-target="target">\
             Add Config\
        </button>',
    props: ['target']
});

Vue.component('aws-config-modal', {
    template: '
\

\

\
            <form id="newEntryFormId" class="form-horizontal" method="post" role="form">\

\
                    <button type="button" class="close" data-dismiss="modal">×Close\
                    </button>\

Add a new user data config
\

\

\

\
                        Name\

\
                        <select class="form-control" v-on:change="updateValue($event.target.value)" v-bind:value="selectedValue">\
                            <option v-for="option in options" v-bind:value="option.name" >{{option.text}}</option>\
                        </select>\

\

\

\

\
                        <input type="checkbox" class="checkToCustomize" v-model="useCustomizedName" v-on:click="toggleCustomizedName($event.target.checked)"> Check to customize name</input>\

\
                            Name\

\
                                <input type="text" class="form-control"placeholder="name..." v-model="customizedName">\

\

\

\

\
                        Value\

\
                            <input type="text" class="form-control" placeholder="value..." v-model="selectedOptionValue"></input>\

\

\

\

\
                    <button type="button" class="btn btn-primary" data-dismiss="modal" v-on:click="addConfig">Add</button>\
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\

\
            </form>

',
    props: ['options', 'id'],
    data: function () {
        return {
            useCustomizedName: false,
            selectedOption: this.options[0],
            selectedOptionValue: this.options[0].default,
            selectedValue: this.options[0].name,
            customizedName: ""
        };
    },
    methods: {
        updateValue: function (value) {
            this.selectedValue = value
            if (value === "") {
                this.selectedOptionValue = ""
            }
            else {
                this.selectedOption = this.options.filter(function (item) { return item.name === value })[0];
                this.selectedOptionValue = this.selectedOption.default;
            }
        },
        addConfig: function () {
            if (this.useCustomizedName) {
                if (this.customizedName !='spiffe_id' && this.customizedName!='assign_public_ip'){
                    this.$emit('click', { name: this.customizedName, value: this.selectedOptionValue })
                }
                else {
                    alert("teletraan currently do not allow user to modify spiffe_id and assign_public_ip")
                }
            }
            else {
                this.$emit('click', { name: this.selectedOption.name, value: this.selectedOptionValue })
            }
        },
        toggleCustomizedName: function (checked) {
            if (checked) {
                this.selectedOption = null
                this.selectedValue = ""
                this.useCustomizedName = true
            }
            else {
                this.useCustomizedName = true
                this.customizedName = ""
            }
            this.selectedOptionValue = null
        }
    }
});

Vue.component('hostype-help', {
    template: '<help-table v-bind:headers="headers" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            headers: [{ name: 'Name', headerClass: 'col-sm-1' },
            { name: 'Id', headerClass: 'col-sm-1' },
            { name: 'Cores', headerClass: 'col-sm-1' },
            { name: 'Memory(GB)', headerClass: 'col-sm-1' },
            { name: 'Storage', headerClass: 'col-sm-2' },
            { name: 'Description', headerClass: 'col-sm-5' }],
            keys: ['abstract_name', 'provider_name', 'core', 'mem', 'storage', 'description']
        }
    },
})

Vue.component('securityzone-help', {
    template: '<help-table v-bind:headers="headers" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            headers: [{ name: 'Name', headerClass: 'col-sm-1' },
            { name: 'Id', headerClass: 'col-sm-1' },
            { name: 'Description', headerClass: 'col-sm-9' }],
            keys: ['abstract_name', 'provider_name', 'description']
        }
    },
})

Vue.component('placements-help', {
    template: '<help-table v-bind:headers="headers" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            headers: [{ name: 'Name', headerClass: 'col-sm-2' },
            { name: 'Id', headerClass: 'col-sm-2' },
            { name: 'Capacity', headerClass: 'col-sm-1' },
            { name: 'Assign Public IP', headerClass: 'col-sm-2' },
            { name: 'Description', headerClass: 'col-sm-4' }],
            keys: ['abstract_name', 'provider_name', 'capacity', 'assign_public_ip', 'description',]
        }
    },
});

/**
* A form control with a label and multiple selection box
*/
Vue.component("placements-select", {
    template: '
\
    \
      {{label}}\
    \

\
          <select class="form-control chosen-select"  v-on:change="updateValue($event.target.value)" multiple>\
            <option v-for="option in selectoptions" v-bind:value="option.value" v-bind:selected="option.isSelected">{{option.text}}</option>\
          </select>\
    \
    <button class="deployToolTip btn btn-default" type="button" data-toggle="tooltip" v-on:click="helpClick" title="click to see more information">\
        \
    </button>\

\

\

\
      <input type="checkbox" id="checkbox" v-bind:checked="assignpublicip" v-on:click="assignipchange($event.target.checked)">\
      Assign Public IP\

',
    props: ['label', 'title', 'selectoptions', 'showhelp', 'assignpublicip'],
    data: function () {
        return {
            groupStyle: this.showhelp ? 'input-group' : ''
        }
    },
    methods: {
        updateValue: function (value) {
            this.$emit('input', value)
        },
        helpClick: function () {
            this.$emit('helpclick')
        },
        assignipchange: function (value) {
            this.$emit('assignpublicipclick', value)
        }
    }
});
<commit_msg>enabled Add button and provide red error message when user add spiffe_id and assign_public_ip (#654)<commit_after>Vue.component('cloudprovider-select', {
    template: '
\

',
    props: ['cloudproviders', 'value'],
    methods: {
        updateValue: function (value) {
            this.$emit('input', value)
        }
    }
});

Vue.component('cell-select', {
    template: '
\

',
    props: ['cells', 'value'],
    methods: {
        updateValue: function (value) {
            this.$emit('input', value);
        },
        updateCellValue: function(value) {
            this.$emit('cellchange', value);
            this.$emit('imagenamechange', value)
        }
    }
});

Vue.component('baseimage-select', {
    template: '
\
 \
\

',
    props: ['imagenames', 'baseimages', 'imagenamevalue', 'baseimagevalue', 'inadvanced'],
    methods: {
        updateBaseImage: function (value) {
            this.$emit('baseimagechange', value)
        },
        updateImageName: function (value) {
            this.$emit('imagenamechange', value)
        },
        helpClick: function (value) {
            this.$emit('helpclick')
        }
    }
});

Vue.component('base-image-help', {
    template: '<help-table v-bind:headers="baseImageHelpHeaders" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            baseImageHelpHeaders: [{ name: 'Publish Date', headerClass: 'col-sm-2' },
            { name: 'Name', headerClass: 'col-sm-1' },
            { name: 'Id', headerClass: 'col-sm-1' },
            { name: 'Qualified', headerClass: 'col-sm-1' },
            { name: 'Description', headerClass: 'col-sm-4' },
            { name: 'Acceptance', headerClass: 'col-sm-4' }],
            keys: ['publish_date', 'abstract_name', 'provider_name', 'qualified', 'description', 'acceptance']
        }
    },
}
)

Vue.component('add-config-button', {
    template: '
\
    <button type="button" class="deployToolTip btn btn-default btn-sm"\
        data-toggle="modal" v-bind:data-target="target">\
            {{text}}\
        </button>\

',
    props: ['text', 'target'],
});

Vue.component('data-config-field', {
    template: '
\
        {{name}}\

\
            <input class="form-control" type="text" v-bind:value="value" v-on:input="change(name,$event.target.value)" v-bind:readonly="readonly ? true : false"></input>\

\

\
            <button type="button" class="delete_button btn btn-default" v-on:click="deleteConfig(name)" v-bind:disabled="readonly ? true : false">Delete</button>\

\

',
    props: ['name', 'value', 'readonly'],
    methods: {
        change: function (name, value) {
            this.$emit("change", { name: name, value: value })
        },
        deleteConfig: function (name) {
            this.$emit('deleteConfig', name)
        }
    }
});

Vue.component('data-config-readonly-field', {
    template: '
\
        {{name}}\

\
            <input class="form-control" type="text" v-bind:value="value"  v-bind:readonly="readonly ? true : false"></input>\

\

',
    props: ['name', 'value', 'readonly']
});

Vue.component('aws-user-data', {
    template: '
\
    <data-config-field v-for="data in alluserdata" v-bind:name="data.name" v-bind:value="data.value" v-bind:readonly="data.readonly" v-bind:inadvanced="inadvanced"\
     v-show="shouldShow(data.name)" v-on:change="change" v-on:deleteConfig="deleteConfig"></data-config-field>\

',
    props: ['alluserdata', 'inadvanced', 'showcmpgroup'],
    methods: {
        change: function (value) {
            this.$emit("change", value)
        },
        deleteConfig: function (name) {
            this.$emit('deleteconfig', name)
        },
        shouldShow: function (name) {
            if (this.inadvanced) {
                return this.showcmpgroup ? true : name != "cmp_group"
            }
            else {
                return !name.startsWith("pinfo_") && name != "cmp_group"
            }
        }
    }
});

Vue.component('aws-readonly-user-data', {
    template: '
\
    <data-config-readonly-field v-for="data in alluserdata" v-bind:name="data.name" v-bind:value="data.value" v-bind:readonly="data.readonly" v-bind:inadvanced="inadvanced"\
     v-show="shouldShow(data.name)"></data-config-readonly-field>\

',
    props: ['alluserdata', 'inadvanced', 'showcmpgroup'],
    methods: {
        shouldShow: function (name) {
            if (this.inadvanced) {
                return this.showcmpgroup ? true : name != "cmp_group"
            }
            else {
                return !name.startsWith("pinfo_") && name != "cmp_group"
            }
        }
    }
});

Vue.component('add-config-button', {
    template: '<button type="button" class="deployToolTip btn btn-default btn-sm" data-toggle="modal" v-bind:data-target="target">\
             Add Config\
        </button>',
    props: ['target']
});

Vue.component("aws-config-modal", {
    template:
        '
\

\

\
            <form id="newEntryFormId" class="form-horizontal" method="post" role="form">\

\
                    <button type="button" class="close" data-dismiss="modal">×Close\
                    </button>\

Add a new user data config
\

\

\

\
                        Name\

\
                        <select class="form-control" v-on:change="updateValue($event.target.value)" v-bind:value="selectedValue">\
                            <option v-for="option in options" v-bind:value="option.name" >{{option.text}}</option>\
                        </select>\

\

\

\

\
                        <input type="checkbox" class="checkToCustomize" v-model="useCustomizedName" v-on:click="toggleCustomizedName($event.target.checked)"> Check to customize name</input>\

\
                            Name\

\
                                <input type="text" class="form-control"placeholder="name..." v-on:keyup="checkReadOnlyValue" v-model="customizedName">\

{{errorMessage}}
\

\

\

\

\
                        Value\

\
                            <input type="text" class="form-control" placeholder="value..." v-model="selectedOptionValue"></input>\

\

\

\

\
                    <button type="button" class="btn btn-primary" data-dismiss="modal" v-on:click="addConfig" id="disableConfigButton">Add</button>\
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\

\
            </form>

',
    props: ["options", "id"],
    data: function() {
        return {
            useCustomizedName: false,
            shouldShowError: false,
            errorMessage: "",
            selectedOption: this.options[0],
            selectedOptionValue: this.options[0].default,
            selectedValue: this.options[0].name,
            customizedName: ""
        };
    },
    methods: {
        updateValue: function(value) {
            this.selectedValue = value;
            if (value === "") {
                this.selectedOptionValue = "";
            } else {
                this.selectedOption = this.options.filter(function(item) {
                    return item.name === value;
                })[0];
                this.selectedOptionValue = this.selectedOption.default;
            }
        },
        addConfig: function() {
            if (this.useCustomizedName) {
                if (
                    this.customizedName != "spiffe_id" &&
                    this.customizedName != "assign_public_ip"
                ) {
                    this.$emit("click", {
                        name: this.customizedName,
                        value: this.selectedOptionValue
                    });
                } else {
                    document.getElementById(
                        "disableConfigButton"
                    ).disabled = true;
                }
            } else {
                this.$emit("click", {
                    name: this.selectedOption.name,
                    value: this.selectedOptionValue
                });
            }
        },
        checkReadOnlyValue: function () {
            if (this.useCustomizedName) {
                if (this.customizedName === "spiffe_id" ||
                    this.customizedName === "assign_public_ip"
                ) {
                    document.getElementById(
                        "disableConfigButton"
                    ).disabled = true;
                    this.shouldShowError = true;
                    if (this.customizedName === "spiffe_id") {
                        this.errorMessage =
                            this.customizedName + " cannot be added. it will be auto generated";
                    } else {
                        this.errorMessage =
                            this.customizedName + " cannot be added. we only allow assign_public_ip checkbox to modify the value";
                    }
                } else {
                    document.getElementById(
                        "disableConfigButton"
                    ).disabled = false;
                    this.shouldShowError = false;
                }
            }
        },
        toggleCustomizedName: function(checked) {
            if (checked) {
                this.selectedOption = null;
                this.selectedValue = "";
                this.useCustomizedName = true;
            } else {
                this.useCustomizedName = true;
                this.customizedName = "";
            }
            this.selectedOptionValue = null;
        }
    }
});

Vue.component('hostype-help', {
    template: '<help-table v-bind:headers="headers" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            headers: [{ name: 'Name', headerClass: 'col-sm-1' },
            { name: 'Id', headerClass: 'col-sm-1' },
            { name: 'Cores', headerClass: 'col-sm-1' },
            { name: 'Memory(GB)', headerClass: 'col-sm-1' },
            { name: 'Storage', headerClass: 'col-sm-2' },
            { name: 'Description', headerClass: 'col-sm-5' }],
            keys: ['abstract_name', 'provider_name', 'core', 'mem', 'storage', 'description']
        }
    },
})

Vue.component('securityzone-help', {
    template: '<help-table v-bind:headers="headers" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            headers: [{ name: 'Name', headerClass: 'col-sm-1' },
            { name: 'Id', headerClass: 'col-sm-1' },
            { name: 'Description', headerClass: 'col-sm-9' }],
            keys: ['abstract_name', 'provider_name', 'description']
        }
    },
})

Vue.component('placements-help', {
    template: '<help-table v-bind:headers="headers" v-bind:data="data" v-bind:keys="keys" ></help-table>',
    props: ['data'],
    data: function () {
        return {
            headers: [{ name: 'Name', headerClass: 'col-sm-2' },
            { name: 'Id', headerClass: 'col-sm-2' },
            { name: 'Capacity', headerClass: 'col-sm-1' },
            { name: 'Assign Public IP', headerClass: 'col-sm-2' },
            { name: 'Description', headerClass: 'col-sm-4' }],
            keys: ['abstract_name', 'provider_name', 'capacity', 'assign_public_ip', 'description',]
        }
    },
});

/**
* A form control with a label and multiple selection box
*/
Vue.component("placements-select", {
    template: '
\
    \
      {{label}}\
    \

\
          <select class="form-control chosen-select"  v-on:change="updateValue($event.target.value)" multiple>\
            <option v-for="option in selectoptions" v-bind:value="option.value" v-bind:selected="option.isSelected">{{option.text}}</option>\
          </select>\
    \
    <button class="deployToolTip btn btn-default" type="button" data-toggle="tooltip" v-on:click="helpClick" title="click to see more information">\
        \
    </button>\

\

\

\
      <input type="checkbox" id="checkbox" v-bind:checked="assignpublicip" v-on:click="assignipchange($event.target.checked)">\
      Assign Public IP\

',
    props: ['label', 'title', 'selectoptions', 'showhelp', 'assignpublicip'],
    data: function () {
        return {
            groupStyle: this.showhelp ? 'input-group' : ''
        }
    },
    methods: {
        updateValue: function (value) {
            this.$emit('input', value)
        },
        helpClick: function () {
            this.$emit('helpclick')
        },
        assignipchange: function (value) {
            this.$emit('assignpublicipclick', value)
        }
    }
});
<|endoftext|>