<commit_before>//Object to generate chart
function ChartFactory(editor, div){
  var self = this;
  this.editor = editor;
  this.div = div;

  this.chart = null; //Chart object for ChartJS
  this.chartType = 'radar';
  this.chartDataX = null; //feature for x
  this.chartDataY = null; //feature for y

  this.chartTypeLabel = $('<label>').html('Chart : ').appendTo(this.div);
  this.chartTypeSelect = $('<select>').appendTo(this.div).change(function(){
    self.chartType = self.chartTypeSelect.val();
    console.log(self.chartType);
    self.drawChart();
  });

  this.chartTypeSelect.append('<option value="radar">Radar</option>');
  this.chartTypeSelect.append('<option value="bubble">Bubble</option>');
  this.chartTypeSelect.append('<option value="pie">Pie</option>');

  this.chartXLabel = $('<label>').html(' x : ').appendTo(this.div);
  this.chartXselect = $('<select>').appendTo(this.div).change(function(){
    self.chartDataX = self.editor.getFeatureByID(self.chartXselect.val());
    self.drawChart();
  });
  this.chartYLabel = $('<label>').html(' y : ').appendTo(this.div);
  this.chartYselect = $('<select>').appendTo(this.div).change(function(){
    self.chartDataY = self.editor.getFeatureByID(self.chartYselect.val());
    self.drawChart();
  });
  this.chartCanvas = null;
}

//Called when pcm is loaded to init chart
ChartFactory.prototype.init = function(){
  for(var f in this.editor.features){
    var feature = this.editor.features[f];
    if(feature.filter.type == 'integer' || feature.filter.type == 'float'){
      if(this.chartDataX == null){
        this.chartDataX = feature;
      }else if(this.chartDataY == null){
        this.chartDataY = feature;
      }
      this.chartXselect.append('<option value="'+feature.generated_KMF_ID+'">'+feature.name+'</option>');
      this.chartYselect.append('<option value="'+feature.generated_KMF_ID+'">'+feature.name+'</option>');
    }
  }
  this.drawChart();
}

ChartFactory.prototype.drawChart = function(){
  if(this.chartType=='bubble'){
    this.drawBubble();
  }else if(this.chartType=='pie'){
    this.drawPie();
  }else if(this.chartType == 'radar') {
    this.drawRadar();
  }else{
    console.log('Unsupported chart type : '+this.chartType);
  }
}

//Draw chart using this.chartDataX and this.chartDataY
ChartFactory.prototype.drawBubble = function(){
  if(this.chartDataX != null && this.chartDataY != null){
    if(this.chartCanvas != null){
      this.chartCanvas.remove();
    }
    this.chartCanvas = $('<canvas>').appendTo(this.div);
    this.chartData = {
      type: 'bubble',
      data: {
          datasets: []
      },
      options:{
        animation: false,
        scales: {
          xAxes: [{
            scaleLabel: {
              display: true,
              labelString: this.chartDataX.name
            }
          }],
          yAxes: [{
            scaleLabel: {
              display: true,
              labelString: this.chartDataY.name
            }
          }]
        }
      }
    };
    for(var p in this.editor.products){
      var product = this.editor.products[p];
      this.chartData.data.datasets.push(product.newDataset(this.editor.features[0], this.chartDataX, this.chartDataY));
    }
    this.chart = new Chart(this.chartCanvas[0], this.chartData);
  }else{
    console.log('X or Y features not defined');
  }
}

ChartFactory.prototype.drawPie = function(){
  if(this.chartDataX != null){
    if(this.chartCanvas != null){
      this.chartCanvas.remove();
    }
    this.chartCanvas = $('<canvas>').appendTo(this.div);
    this.chartData = {
      type: 'pie',
      data: {
        labels: [],
        datasets: [
          {
            data: []
          }
        ]
      }
      /*options:{

      }*/
    };
    for(var p in this.editor.products){
      var product = this.editor.products[p];
      this.chartData.data.labels.push(product.getCell(this.editor.features[0]).content);
      this.chartData.data.datasets[0].data.push(parseFloat(product.getCell(this.chartDataX).content));
    }
    this.chart = new Chart(this.chartCanvas[0], this.chartData);
  }else{
    console.log('Value undefined');
  }
}

ChartFactory.prototype.drawRadar = function(){
  if(this.chartCanvas != null){
    this.chartCanvas.remove();
  }
  this.chartCanvas = $('<canvas>').appendTo(this.div);
  this.chartData = {
    type: 'radar',
    data: {
      labels: [],
      datasets: []
    }
  };

  var labels = [];
  for(var f in this.editor.features) {
    var feature = this.editor.features[f]
    if(feature.isNumber){
      labels.push(feature.name);
    }
  }
  for(var p in this.editor.products){ //currently all products are selected
    var product = this.editor.products[p];
    var data = [];
    for (var f in this.editor.features){
      var feature = this.editor.features[f];
      if(feature.isNumber){
        var cellValue = parseFloat(product.getCell(this.editor.features[f]).content);
        data.push(cellValue / feature.filter.max);
      }
    }
    this.chartData.data.labels = labels;
    var label = product.getCell(this.editor.features[0]).content;
    this.chartData.data.datasets.push({label: label, borderColor:label.toColour(), data: data});
  }
  this.chart = new Chart(this.chartCanvas[0], this.chartData);
}

/**
 * Return a color based on a string
 * @return {string} A color in hexadecimal.
 */
String.prototype.toColour = function () {
   var hash = 0;
   for (var i = 0; i < this.length; i++) {
     hash = this.charCodeAt(i) + ((hash << 5) - hash);
   }
   var colour = '#';
   for (var i = 0; i < 3; i++) {
     var value = (hash >> (i * 8)) & 0xFF;
     colour += ('00' + value.toString(16)).substr(-2);
   }
   return colour;
 }
//Update chart when configurator change
ChartFactory.prototype.update = function(){
  if(this.chart != null){
    console.log("plop")
    this.chart.update();
  }
}
<commit_msg>Fix charts not being connected to the configurator<commit_after>//Object to generate chart
function ChartFactory(editor, div){
  var self = this;
  this.editor = editor;
  this.div = div;

  this.chart = null; //Chart object for ChartJS
  this.chartType = 'radar';
  this.chartDataX = null; //feature for x
  this.chartDataY = null; //feature for y

  this.chartTypeLabel = $('<label>').html('Chart : ').appendTo(this.div);
  this.chartTypeSelect = $('<select>').appendTo(this.div).change(function(){
    self.chartType = self.chartTypeSelect.val();
    self.drawChart();
  });

  this.chartTypeSelect.append('<option value="radar">Radar</option>');
  this.chartTypeSelect.append('<option value="bubble">Bubble</option>');
  this.chartTypeSelect.append('<option value="pie">Pie</option>');

  this.chartXLabel = $('<label>').html(' x : ').appendTo(this.div);
  this.chartXselect = $('<select>').appendTo(this.div).change(function(){
    self.chartDataX = self.editor.getFeatureByID(self.chartXselect.val());
    self.drawChart();
  });
  this.chartYLabel = $('<label>').html(' y : ').appendTo(this.div);
  this.chartYselect = $('<select>').appendTo(this.div).change(function(){
    self.chartDataY = self.editor.getFeatureByID(self.chartYselect.val());
    self.drawChart();
  });
  this.chartCanvas = null;
}

//Called when pcm is loaded to init chart
ChartFactory.prototype.init = function(){
  for(var f in this.editor.features){
    var feature = this.editor.features[f];
    if(feature.filter.type == 'integer' || feature.filter.type == 'float'){
      if(this.chartDataX == null){
        this.chartDataX = feature;
      }else if(this.chartDataY == null){
        this.chartDataY = feature;
      }
      this.chartXselect.append('<option value="'+feature.generated_KMF_ID+'">'+feature.name+'</option>');
      this.chartYselect.append('<option value="'+feature.generated_KMF_ID+'">'+feature.name+'</option>');
    }
  }
  this.drawChart();
}

ChartFactory.prototype.drawChart = function(){
  if(this.chartType=='bubble'){
    this.drawBubble();
  }else if(this.chartType=='pie'){
    this.drawPie();
  }else if(this.chartType == 'radar') {
    this.drawRadar();
  }else{
    console.log('Unsupported chart type : '+this.chartType);
  }
}

//Draw chart using this.chartDataX and this.chartDataY
ChartFactory.prototype.drawBubble = function(){
  if(this.chartDataX != null && this.chartDataY != null){
    if(this.chartCanvas != null){
      this.chartCanvas.remove();
    }
    this.chartCanvas = $('<canvas>').appendTo(this.div);
    this.chartData = {
      type: 'bubble',
      data: {
          datasets: []
      },
      options:{
        animation: false,
        scales: {
          xAxes: [{
            scaleLabel: {
              display: true,
              labelString: this.chartDataX.name
            }
          }],
          yAxes: [{
            scaleLabel: {
              display: true,
              labelString: this.chartDataY.name
            }
          }]
        }
      }
    };
    for(var p in this.editor.products){
      var product = this.editor.products[p];
      this.chartData.data.datasets.push(product.newDataset(this.editor.features[0], this.chartDataX, this.chartDataY));
    }
    this.chart = new Chart(this.chartCanvas[0], this.chartData);
  }else{
    console.log('X or Y features not defined');
  }
}

ChartFactory.prototype.drawPie = function(){
  if(this.chartDataX != null){
    if(this.chartCanvas != null){
      this.chartCanvas.remove();
    }
    this.chartCanvas = $('<canvas>').appendTo(this.div);
    this.chartData = {
      type: 'pie',
      data: {
        labels: [],
        datasets: [
          {
            data: []
          }
        ]
      },
      options: {
        animation: false
      }
    };
    for(var p in this.editor.products){
      var product = this.editor.products[p];
      if(product.visible) {
        this.chartData.data.labels.push(product.getCell(this.editor.features[0]).content);
        this.chartData.data.datasets[0].data.push(parseFloat(product.getCell(this.chartDataX).content));
      }
    }
    this.chart = new Chart(this.chartCanvas[0], this.chartData);
  }else{
    console.log('Value undefined');
  }
}

ChartFactory.prototype.drawRadar = function(){
  if(this.chartCanvas != null){
    this.chartCanvas.remove();
  }
  this.chartCanvas = $('<canvas>').appendTo(this.div);
  this.chartData = {
    type: 'radar',
    data: {
      labels: [],
      datasets: []
    },
    options: {
      animation: false
    }
  };

  var labels = [];
  for(var f in this.editor.features) {
    var feature = this.editor.features[f]
    if(feature.isNumber){
      labels.push(feature.name);
    }
  }
  for(var p in this.editor.products){ //currently all products are selected
    var product = this.editor.products[p];
    var data = [];
    if(product.visible) {
      for (var f in this.editor.features){
        var feature = this.editor.features[f];
        if(feature.isNumber){
          var cellValue = parseFloat(product.getCell(this.editor.features[f]).content);
          data.push(cellValue / feature.filter.max);
        }
      }
    }
    this.chartData.data.labels = labels;
    var label = product.getCell(this.editor.features[0]).content;
    this.chartData.data.datasets.push({label: label, borderColor:label.toColour(), data: data});
  }
  this.chart = new Chart(this.chartCanvas[0], this.chartData);
}

/**
 * Return a color based on a string
 * @return {string} A color in hexadecimal.
 */
String.prototype.toColour = function () {
   var hash = 0;
   for (var i = 0; i < this.length; i++) {
     hash = this.charCodeAt(i) + ((hash << 5) - hash);
   }
   var colour = '#';
   for (var i = 0; i < 3; i++) {
     var value = (hash >> (i * 8)) & 0xFF;
     colour += ('00' + value.toString(16)).substr(-2);
   }
   return colour;
 }

//Update chart when configurator change
ChartFactory.prototype.update = function(){
  if(this.chart != null){
    var that = this;
    setTimeout(function(){
      if(that.chartType !== "bubble") {
        that.drawChart();
      } else {
        that.chart.update();
      }
    },1000);
  }
}
<|endoftext|>


<commit_before>module('lively.tests.ModuleSystemTests').requires('lively.TestFramework').toRun(function() {

TestCase.subclass('lively.tests.ModuleSystemTests.ModuleTest', {
    testGetModulesInDir: function() {
        var moduleNames, cb = URL.codeBase,
            url = cb.withFilename('foo/');
        this.mockClass(WebResource, 'getSubElements', function() {
            this.subDocuments = [cb.withFilename('foo/Foo.js').asWebResource(),
                                 cb.withFilename('foo/Bar.js').asWebResource()];
        });

        lively.Module.findAllInThenDo(url, function(modules) {
            moduleNames = modules.invoke('name');
        });
        this.assertMatches(['foo.Foo', 'foo.Bar'], moduleNames);
    },

    testGetModulesInDirWorksOnlyForDirectory: function() {
        var url = URL.codeBase.withFilename('foo');
        this.assertRaises(function() {
            lively.Module.findAllInThenDo(url, function() {});
        }, /foo is not a directory/, 'no error on non-dir URL');
    },
    testUriWithRealtivePath: function() {
        // FIXME this is for handling core in the namespace root
        var m = module('../users/robertkrahn/foo.js'),
            uri = m.uri(),
            expected = URL.root.withFilename('users/robertkrahn/foo.js').toString();
        this.assertEquals(expected, m.uri());
    },
    testRelativePathModule: function() {
        this.assertEquals(module('../users/robertkrahn/foo.js').uri(),
                          module('users/robertkrahn/foo.js').uri());
        this.assertEquals(module('users/robertkrahn/foo.js').uri(),
                          module('users.robertkrahn.foo').uri());
    },
    testToRun: function() {
        var moduleCodeExecuted = false;
        module('foo.baz').requires().toRun(function() {
            moduleCodeExecuted = true;
        });
        this.assert(moduleCodeExecuted, 'module not executed');
    },
    testRequireLib: function() {
        var moduleCodeExecuted = false;
        module('foo.bar').requires().requiresLib().toRun(function() {
            moduleCodeExecuted = true;
        });
        this.assert(!moduleCodeExecuted, 'module prematurely executed');
    }

});

AsyncTestCase.subclass('lively.tests.ModuleSystemTests.ModuleLoad',
'running', {
    setUp: function($super) {
        this.originalJSLoader = Global.JSLoader;
        Global.JSLoader = {
            loadJs: Functions.Null,
            scriptInDOM: Functions.True
        }
        $super();
    },
    tearDown: function($super) {
        Global.JSLoader = this.originalJSLoader;
        $super();
    }
},
'testing', {

    testRequireLib: function() {
        var moduleCodeExecuted = false,
            libBazIsLoaded = false,
            loadTestCalled = 0;
        module('foo.bar')
            .requires()
            .requiresLib({
                url: Config.codeBase + 'lib/baz.js',
                loadTest: function() { loadTestCalled++; return libBazIsLoaded; }
            }).toRun(function() {
                moduleCodeExecuted = true;
            });
        this.assert(module('foo.bar').hasPendingRequirements(), 'hasPendingRequirements 1');
        this.delay(function() {
            this.assert(loadTestCalled > 1, 'load test call count');
            this.assert(!moduleCodeExecuted, 'module prematurely executed');
            this.assert(module('foo.bar').hasPendingRequirements(), 'hasPendingRequirements 2');
            libBazIsLoaded = true;
        }, 60);
        this.delay(function() {
            this.assert(moduleCodeExecuted, 'module not executed');
            this.assert(!module('foo.bar').hasPendingRequirements(), 'hasPendingRequirements 3');
            this.done();
        }, 120);
    }

});

});<commit_msg>fixed RequireLib test so that it actually requires a lib<commit_after>module('lively.tests.ModuleSystemTests').requires('lively.TestFramework').toRun(function() {

TestCase.subclass('lively.tests.ModuleSystemTests.ModuleTest', {
    testGetModulesInDir: function() {
        var moduleNames, cb = URL.codeBase,
            url = cb.withFilename('foo/');
        this.mockClass(WebResource, 'getSubElements', function() {
            this.subDocuments = [cb.withFilename('foo/Foo.js').asWebResource(),
                                 cb.withFilename('foo/Bar.js').asWebResource()];
        });

        lively.Module.findAllInThenDo(url, function(modules) {
            moduleNames = modules.invoke('name');
        });
        this.assertMatches(['foo.Foo', 'foo.Bar'], moduleNames);
    },

    testGetModulesInDirWorksOnlyForDirectory: function() {
        var url = URL.codeBase.withFilename('foo');
        this.assertRaises(function() {
            lively.Module.findAllInThenDo(url, function() {});
        }, /foo is not a directory/, 'no error on non-dir URL');
    },
    testUriWithRealtivePath: function() {
        // FIXME this is for handling core in the namespace root
        var m = module('../users/robertkrahn/foo.js'),
            uri = m.uri(),
            expected = URL.root.withFilename('users/robertkrahn/foo.js').toString();
        this.assertEquals(expected, m.uri());
    },
    testRelativePathModule: function() {
        this.assertEquals(module('../users/robertkrahn/foo.js').uri(),
                          module('users/robertkrahn/foo.js').uri());
        this.assertEquals(module('users/robertkrahn/foo.js').uri(),
                          module('users.robertkrahn.foo').uri());
    },
    testToRun: function() {
        var moduleCodeExecuted = false;
        module('foo.goo').requires().toRun(function() {
            moduleCodeExecuted = true;
        });
        this.assert(moduleCodeExecuted, 'module not executed');
    },
    testRequireLib: function() {
        var moduleCodeExecuted = false,
            lib = {uri: URL.root.withFilename('foo.js'), loadTest: function() { return false; }};
        module('foo.bar').requires().requiresLib(lib).toRun(function() {
            moduleCodeExecuted = true;
        });
        this.assert(!moduleCodeExecuted, 'module prematurely executed');
    }
});

AsyncTestCase.subclass('lively.tests.ModuleSystemTests.ModuleLoad',
'running', {
    setUp: function($super) {
        this.originalJSLoader = Global.JSLoader;
        Global.JSLoader = {
            loadJs: Functions.Null,
            scriptInDOM: Functions.True
        }
        $super();
    },
    tearDown: function($super) {
        Global.JSLoader = this.originalJSLoader;
        $super();
    }
},
'testing', {

    testRequireLib: function() {
        var moduleCodeExecuted = false,
            libBazIsLoaded = false,
            loadTestCalled = 0;
        module('foo.bar')
            .requires()
            .requiresLib({
                url: Config.codeBase + 'lib/baz.js',
                loadTest: function() { loadTestCalled++; return libBazIsLoaded; }
            }).toRun(function() {
                moduleCodeExecuted = true;
            });
        this.assert(module('foo.bar').hasPendingRequirements(), 'hasPendingRequirements 1');
        this.delay(function() {
            this.assert(loadTestCalled > 1, 'load test call count');
            this.assert(!moduleCodeExecuted, 'module prematurely executed');
            this.assert(module('foo.bar').hasPendingRequirements(), 'hasPendingRequirements 2');
            libBazIsLoaded = true;
        }, 60);
        this.delay(function() {
            this.assert(moduleCodeExecuted, 'module not executed');
            this.assert(!module('foo.bar').hasPendingRequirements(), 'hasPendingRequirements 3');
            this.done();
        }, 120);
    }

});

});<|endoftext|>


<commit_before>import React from 'react';
import {Row, Col, Form, DatePicker, Input} from 'antd';
import moment from 'moment';
import styles from './BaseInfo.less';

function BaseInfo( props ) {
	const FormItem = Form.Item;
	const { getFieldDecorator } = props.form;
	const formItemLayout = {
		labelCol: {
			xs: { span: 24 },
			sm: { span: 8 },
		},
		wrapperCol: {
			xs: { span: 24 },
			sm: { span: 16 },
		},
	};

	return (

基本信息

				<Row>
					<Col span={12}>
						<FormItem {...formItemLayout} label="委托人姓名">
							<Input style={{ width: 200 }} value={props.doctorName} disabled/>
						</FormItem>
					</Col>
					<Col span={12}>
						<FormItem {...formItemLayout} label="委托人联系方式">
							<Input style={{ width: 200 }} value={props.doctorTel} disabled/>
						</FormItem>
					</Col>
				</Row>
				<Row>
					<Col span={12}>
						<FormItem {...formItemLayout} label="任务截止时间">
							{getFieldDecorator( 'taskDeadlineDate', {
								initialValue: props.taskDeadlineDate ? moment( props.taskDeadlineDate, 'YYYY-MM-DD' ) : undefined,
								rules: [
									{ required: true, message: '请选择截止日期！' },
								],
							} )(
								<DatePicker style={{ width: 200 }} disabled={props.disabled}/>
							)}
						</FormItem>
					</Col>
					<Col span={12}>
						<FormItem {...formItemLayout} label="委托人数" style={{ display: props.display }}>
							<Input style={{ width: 200 }} value={props.entrustNumber} disabled/>
						</FormItem>
					</Col>
				</Row>

	);
}

export default Form.create()( BaseInfo );<commit_msg>baseInfo<commit_after>import React from 'react';
import {Row, Col, Form, DatePicker, Input} from 'antd';
import moment from 'moment';
import styles from './BaseInfo.less';

function BaseInfo( props ) {
	const FormItem = Form.Item;
	const { getFieldDecorator } = props.form;
	const formItemLayout = {
		labelCol: {
			xs: { span: 24 },
			sm: { span: 8 },
		},
		wrapperCol: {
			xs: { span: 24 },
			sm: { span: 16 },
		},
	};

	return (

基本信息

				<FormItem>
					{getFieldDecorator( 'doctorId', {
						initialValue:props.doctorId
					})(<Input style={{ width: 200 }}  disabled type="hidden"/>)}
				</FormItem>
				<Row>
					<Col span={12}>
						<FormItem {...formItemLayout} label="委托人姓名">
							{getFieldDecorator( 'doctorName', {
								initialValue:props.doctorName
							})(<Input style={{ width: 200 }} disabled/>)}
						</FormItem>
					</Col>
					<Col span={12}>
						<FormItem {...formItemLayout} label="委托人联系方式">
							{getFieldDecorator( 'doctorTel', {
								initialValue:props.doctorTel
							})(<Input style={{ width: 200 }}  disabled/>)}
						</FormItem>
					</Col>
				</Row>
				<Row>
					<Col span={12}>
						<FormItem {...formItemLayout} label="任务截止时间">
							{getFieldDecorator( 'taskDeadlineDate', {
								initialValue: props.taskDeadlineDate ? moment( props.taskDeadlineDate, 'YYYY-MM-DD' ) : undefined,
								rules: [
									{ required: true, message: '请选择截止日期！' },
								],
							} )(<DatePicker style={{ width: 200 }} disabled={props.disabled}/>)}
						</FormItem>
					</Col>
					<Col span={12}>
						<FormItem {...formItemLayout} label="委托人数" style={{ display: props.display }}>
							{getFieldDecorator( 'entrustNumber', {
								initialValue:props.entrustNumber
							})(<Input style={{ width: 200 }} disabled/>)}
						</FormItem>
					</Col>
				</Row>

	);
}

export default Form.create()( BaseInfo );<|endoftext|>


<commit_before>
function getJsonFromUrl(hashBased) {
    'use strict'
    var query;
        if (hashBased) {
            var pos = location.href.indexOf("?");
            if (pos == -1) return [];
            query = location.href.substr(pos + 1);
        } else {
            query = location.search.substr(1);
        }
        var result = {};
        query.split("&").forEach(function(part) {
            if (!part) return;
            part = part.split("+").join(" "); // replace every + with space, regexp-free version
            var eq = part.indexOf("=");
            var key = eq > -1 ? part.substr(0, eq) : part;
            var val = eq > -1 ? decodeURIComponent(part.substr(eq + 1)) : "";
            var from = key.indexOf("[");
            if (from == -1) result[decodeURIComponent(key)] = val;
            else {
                var to = key.indexOf("]");
                var index = decodeURIComponent(key.substring(from + 1, to));
                key = decodeURIComponent(key.substring(0, from));
                if (!result[key]) result[key] = [];
                if (!index) result[key].push(val);
                else result[key][index] = val;
            }
        });
        return result;
    }

var resultado = [];

resultado = JSON.parse(getJsonFromUrl().test);

var text1 = "Como " + resultado.lambA + " = " + "<span> \\(c=\frac{2}{3x}+\ \mathop{\int\!\!\!\!\int}{xdx}\\) </span>" + " = " + resultado.lambpA
MathJax.Hub.Queue(["Typeset",MathJax.Hub, text1])

$(document).ready(function() {
    $(".project").html(resultado.project);
    $("#text1").html(text1);
    MathJax.Hub.Queue(["Typeset",MathJax.Hub,'text1'])

});

<commit_msg>Update reportCS.js<commit_after>
function getJsonFromUrl(hashBased) {
    'use strict'
    var query;
        if (hashBased) {
            var pos = location.href.indexOf("?");
            if (pos == -1) return [];
            query = location.href.substr(pos + 1);
        } else {
            query = location.search.substr(1);
        }
        var result = {};
        query.split("&").forEach(function(part) {
            if (!part) return;
            part = part.split("+").join(" "); // replace every + with space, regexp-free version
            var eq = part.indexOf("=");
            var key = eq > -1 ? part.substr(0, eq) : part;
            var val = eq > -1 ? decodeURIComponent(part.substr(eq + 1)) : "";
            var from = key.indexOf("[");
            if (from == -1) result[decodeURIComponent(key)] = val;
            else {
                var to = key.indexOf("]");
                var index = decodeURIComponent(key.substring(from + 1, to));
                key = decodeURIComponent(key.substring(0, from));
                if (!result[key]) result[key] = [];
                if (!index) result[key].push(val);
                else result[key][index] = val;
            }
        });
        return result;
    }

var resultado = [];

resultado = JSON.parse(getJsonFromUrl().test);

var text1 = "Como " + resultado.lambA + " = " + "\\(c=\frac{2}{3x}+\\ \\mathop{\int\!\!\!\!\int}{xdx}\\)\" + " = " + resultado.lambpA
MathJax.Hub.Queue(["Typeset",MathJax.Hub, text1])

$(document).ready(function() {
    $(".project").html(resultado.project);
    $("#text1").html(text1);
    MathJax.Hub.Queue(["Typeset",MathJax.Hub,'text1'])

});

<|endoftext|>


<commit_before>import { NormalModuleReplacementPlugin } from 'webpack'
import merge from 'webpack-merge'
import path from 'path'

import initConf from '../build'

export default merge(
    initConf({
        context: path.resolve(__dirname, '..'),
        mode: 'development',
        injectStyles: true,
    }),
    {
        plugins: [
            // Set up mock for WebExt APIs. Idea from:
            //   https://github.com/aeksco/react-typescript-web-extension-starter/blob/f62486ec8518eb5cf78687a2e658505fd528dc8a/.storybook/webpack.config.js
            new NormalModuleReplacementPlugin(
                /webextension-polyfill-ts/,
                resource => {
                    const absMockPath = path.resolve(
                        __dirname,
                        'mocks/webextension-polyfill-ts.js',
                    )

                    resource.request = path.relative(
                        resource.context,
                        absMockPath,
                    )
                },
            ),
        ],
    },
)
<commit_msg>Set up storybook to output an async webpack config<commit_after>import { NormalModuleReplacementPlugin } from 'webpack'
import merge from 'webpack-merge'
import path from 'path'

import initConf from '../build'

export default async () =>
    merge(
        await initConf({
            context: path.resolve(__dirname, '..'),
            mode: 'development',
            injectStyles: true,
        }),
        {
            plugins: [
                // Set up mock for WebExt APIs. Idea from:
                //   https://github.com/aeksco/react-typescript-web-extension-starter/blob/f62486ec8518eb5cf78687a2e658505fd528dc8a/.storybook/webpack.config.js
                new NormalModuleReplacementPlugin(
                    /webextension-polyfill-ts/,
                    (resource) => {
                        const absMockPath = path.resolve(
                            __dirname,
                            'mocks/webextension-polyfill-ts.js',
                        )

                        resource.request = path.relative(
                            resource.context,
                            absMockPath,
                        )
                    },
                ),
            ],
        },
    )
<|endoftext|>


<commit_before>import { h, Component } from 'preact'
import styled from 'styled-components'
import { Box } from '../Grid'
import Fixed from '../Fixed'
import Text from '../Text'
import { FaCaretDown, FaTrash, FaPieChart } from 'react-icons/lib/fa'
import Button from '../Button'
import FilterDescription from './FilterDescription'

const Wrapper = styled.div``

const UnstyledList = styled.ul`
  list-style: none;
  padding: 0 !important;
  margin: 0;
`

const PlainPanel = styled.div`
  border-radius: 2px;
  background-color: #ffffff;
  box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
  border: solid 1px #9b9b9b;
`

const Preview = styled(PlainPanel)`
  display: none;
  position: absolute;
  right: 230px;
  width: 400px;
  right: 302px;
  top: 2px;
  padding: 15px 15px 5px;
`

const ViewListItem = styled.li`
  position: relative;
  padding: 7px 20px;
  &:hover {
    background-color: #f3f3f3;
  }
  & > p {
    padding-right: 20px;
  }
  & > button {
    position: absolute;
    top: 7px;
    right: 10px;
    padding: 8px;
    background: none;
    border: none;
    display: none;
  }
  &:hover > button {
    display: block;
  }
  &:hover ${Preview} {
    display: block;
  }
`

const MenuPanel = styled(PlainPanel)`
  position: absolute;
  width: 300px;
  right: 0;
  top: 40px;
  z-index: 1;
`

class ViewsMenu extends Component {
  constructor (props) {
    super(props)

    this.state = {
      showViewsMenu: false
    }
  }

  loadView (view) {
    this.props.setRules(view.rules)
    this.setState({ showViewsMenu: false })
  }

  render () {
    const { views } = this.props
    const hasViews =
      views.length > 0 &&
      views.reduce((sum, item) => sum + item.data.length, 0) > 0
    return (
      <Wrapper>
        <Button
          onClick={() =>
            this.setState({ showViewsMenu: !this.state.showViewsMenu })}
        >
          <FaPieChart style={{ marginRight: 10 }} />
          Views
          <FaCaretDown style={{ float: 'right' }} name='caret-down' />
        </Button>
        {this.state.showViewsMenu && (
          <Fixed
            z={1}
            onClick={() => this.setState({ showViewsMenu: false })}
            top
            right
            bottom
            left
          />
        )}
        {this.state.showViewsMenu && (
          <MenuPanel className='views-menu__panel'>
            {!hasViews && (
              <Box p={3}>{"You haven't created any views yet"}</Box>
            )}
            {hasViews &&
              views.map(scope => {
                if (!scope.data || !scope.data.length) {
                  return null
                }
                return (
                  <Box>
                    {!!scope.title && (
                      <Text fontSize={13} ml={20} mb={2} mt={2} color='#aaa'>
                        {scope.title}
                      </Text>
                    )}
                    <UnstyledList>
                      {scope.data.map(view => (
                        <ViewListItem key={view.name}>
                          <Text m={0} onClick={() => this.loadView(view)}>
                            {view.name}

                            <Text m={0} fontSize={12} color='#aaa'>
                              {view.rules.length} filter{view.rules.length > 1 && 's'}
                            </Text>
                          </Text>
                          <button>
                            <FaTrash
                              name='trash'
                              onClick={() =>
                                this.props.deleteView(view, scope.key)}
                            />
                          </button>
                          <Preview>
                            {view.rules.map(rule => (
                              <Box mb={10} key={rule.id}>
                                <FilterDescription rule={rule} />
                              </Box>
                            ))}
                          </Preview>
                        </ViewListItem>
                      ))}
                    </UnstyledList>
                  </Box>
                )
              })}
          </MenuPanel>
        )}
      </Wrapper>
    )
  }
}

export default ViewsMenu
<commit_msg>Increase views menu z-index<commit_after>import { h, Component } from 'preact'
import styled from 'styled-components'
import { Box } from '../Grid'
import Fixed from '../Fixed'
import Text from '../Text'
import { FaCaretDown, FaTrash, FaPieChart } from 'react-icons/lib/fa'
import Button from '../Button'
import FilterDescription from './FilterDescription'

const Wrapper = styled.div``

const UnstyledList = styled.ul`
  list-style: none;
  padding: 0 !important;
  margin: 0;
`

const PlainPanel = styled.div`
  border-radius: 2px;
  background-color: #ffffff;
  box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
  border: solid 1px #9b9b9b;
`

const Preview = styled(PlainPanel)`
  display: none;
  position: absolute;
  right: 230px;
  width: 300px;
  right: 302px;
  top: 2px;
  padding: 15px 15px 5px;
`

const ViewListItem = styled.li`
  position: relative;
  padding: 7px 20px;
  &:hover {
    background-color: #f3f3f3;
  }
  & > p {
    padding-right: 20px;
  }
  & > button {
    position: absolute;
    top: 7px;
    right: 10px;
    padding: 8px;
    background: none;
    border: none;
    display: none;
  }
  &:hover > button {
    display: block;
  }
  &:hover ${Preview} {
    display: block;
  }
`

const MenuPanel = styled(PlainPanel)`
  position: absolute;
  width: 300px;
  right: 0;
  top: 40px;
  z-index: 9999;
`

class ViewsMenu extends Component {
  constructor (props) {
    super(props)

    this.state = {
      showViewsMenu: false
    }
  }

  loadView (view) {
    this.props.setRules(view.rules)
    this.setState({ showViewsMenu: false })
  }

  render () {
    const { views } = this.props
    const hasViews =
      views.length > 0 &&
      views.reduce((sum, item) => sum + item.data.length, 0) > 0
    return (
      <Wrapper>
        <Button
          onClick={() =>
            this.setState({ showViewsMenu: !this.state.showViewsMenu })}
        >
          <FaPieChart style={{ marginRight: 10 }} />
          Views
          <FaCaretDown style={{ float: 'right' }} name='caret-down' />
        </Button>
        {this.state.showViewsMenu && (
          <Fixed
            z={1}
            onClick={() => this.setState({ showViewsMenu: false })}
            top
            right
            bottom
            left
          />
        )}
        {this.state.showViewsMenu && (
          <MenuPanel className='views-menu__panel'>
            {!hasViews && (
              <Box p={3}>{"You haven't created any views yet"}</Box>
            )}
            {hasViews &&
              views.map(scope => {
                if (!scope.data || !scope.data.length) {
                  return null
                }
                return (
                  <Box>
                    {!!scope.title && (
                      <Text fontSize={13} ml={20} mb={2} mt={2} color='#aaa'>
                        {scope.title}
                      </Text>
                    )}
                    <UnstyledList>
                      {scope.data.map(view => (
                        <ViewListItem key={view.name}>
                          <Text m={0} onClick={() => this.loadView(view)}>
                            {view.name}

                            <Text m={0} fontSize={12} color='#aaa'>
                              {view.rules.length} filter{view.rules.length > 1 && 's'}
                            </Text>
                          </Text>
                          <button>
                            <FaTrash
                              name='trash'
                              onClick={() =>
                                this.props.deleteView(view, scope.key)}
                            />
                          </button>
                          <Preview>
                            {view.rules.map(rule => (
                              <Box mb={10} key={rule.id}>
                                <FilterDescription rule={rule} />
                              </Box>
                            ))}
                          </Preview>
                        </ViewListItem>
                      ))}
                    </UnstyledList>
                  </Box>
                )
              })}
          </MenuPanel>
        )}
      </Wrapper>
    )
  }
}

export default ViewsMenu
<|endoftext|>


<commit_before>const labs = require('../../../shared/labs');
const events = require('../../lib/common/events');

const DynamicRedirectManager = require('@tryghost/express-dynamic-redirects');
const OffersModule = require('@tryghost/members-offers');

const stripeService = require('../stripe');

const config = require('../../../shared/config');
const urlUtils = require('../../../shared/url-utils');
const models = require('../../models');

const redirectManager = new DynamicRedirectManager({
    permanentMaxAge: config.get('caching:customRedirects:maxAge')
}, urlUtils);

module.exports = {
    async init() {
        const offersModule = OffersModule.create({
            OfferModel: models.Offer,
            redirectManager: redirectManager,
            stripeAPIService: stripeService.api
        });

        this.api = offersModule.api;
        this.repository = offersModule.repository;

        if (labs.isSet('offers')) {
            // handles setting up redirects
            await offersModule.init();
        }

        // TODO: Delete after GA
        let offersEnabled = labs.isSet('offers');
        events.on('settings.labs.edited', async () => {
            if (labs.isSet('offers') !== offersEnabled) {
                offersEnabled = labs.isSet('offers');

                if (offersEnabled) {
                    const offers = await this.api.listOffers();
                    for (const offer of offers) {
                        redirectManager.addRedirect(`/${offer.code}`, `/#/portal/offers/${offer.id}`, {permanent: false});
                    }
                } else {
                    redirectManager.removeAllRedirects();
                }
            }
        });
    },

    api: null,

    middleware: redirectManager.handleRequest
};
<commit_msg>Fixed handling of labs flag for Offers<commit_after>const labs = require('../../../shared/labs');
const events = require('../../lib/common/events');

const DynamicRedirectManager = require('@tryghost/express-dynamic-redirects');
const OffersModule = require('@tryghost/members-offers');

const stripeService = require('../stripe');

const config = require('../../../shared/config');
const urlUtils = require('../../../shared/url-utils');
const models = require('../../models');

const redirectManager = new DynamicRedirectManager({
    permanentMaxAge: config.get('caching:customRedirects:maxAge')
}, urlUtils);

module.exports = {
    async init() {
        const offersModule = OffersModule.create({
            OfferModel: models.Offer,
            redirectManager: redirectManager,
            stripeAPIService: stripeService.api
        });

        this.api = offersModule.api;
        this.repository = offersModule.repository;

        let initCalled = false;
        if (labs.isSet('offers')) {
            // handles setting up redirects
            const promise = offersModule.init();
            initCalled = true;
            await promise;
        }

        // TODO: Delete after GA
        let offersEnabled = labs.isSet('offers');
        events.on('settings.labs.edited', async () => {
            if (labs.isSet('offers') && !initCalled) {
                const promise = offersModule.init();
                initCalled = true;
                await promise;
            } else if (labs.isSet('offers') !== offersEnabled) {
                offersEnabled = labs.isSet('offers');

                if (offersEnabled) {
                    const offers = await this.api.listOffers();
                    for (const offer of offers) {
                        redirectManager.addRedirect(`/${offer.code}`, `/#/portal/offers/${offer.id}`, {permanent: false});
                    }
                } else {
                    redirectManager.removeAllRedirects();
                }
            }
        });
    },

    api: null,

    middleware: redirectManager.handleRequest
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');

var dest = process.argv[2];

if (!dest) {
	return console.error('Missing path argument!');
}

// Ensure destination exists
mkdirp(path.join(dest, 'settings'), function(err) {
	if (err) {
		return console.error(err);
	}

	/**
	 * Copy root file
	 */
	fs.readFile(__dirname + '/../src/scss/kanbasu.scss', 'utf8', function(err, data) {
		if (err) {
			return console.error(err);
		}

		// Update path to partials
		var pathToAssets = path.relative(dest, __dirname + '/../src/scss');
		// Import project settings after Kanbasu default settings
		var result = data
			.replace(/@import '/g, "@import '"+pathToAssets+"/")
			.replace(/(settings\/settings';[\r\n])/g, "$1@import 'settings/settings';\r\n");

		var destFile = path.join(dest, 'main.scss');
		fs.writeFile(destFile, result, 'utf8', function(err) {
			if (err) {
				return console.error(err);
			}
			console.log('Writing "' + destFile + '"');
		});
	});

	/**
	 * Copy settings file
	 */
	fs.readFile(__dirname + '/../src/scss/settings/_settings.scss', 'utf8', function(err, data) {
		if (err) {
			return console.error(err);
		}

		// Remove Sass !default flags
		var result = data.replace(/ !default/g, '');

		var destFile = path.join(dest, 'settings/_settings.scss');
		fs.writeFile(destFile, result, 'utf8', function(err) {
			if (err) {
				return console.error(err);
			}
			console.log('Writing "' + destFile + '"');
		});
	});
});
<commit_msg>Try to use correct end of line based on OS<commit_after>#!/usr/bin/env node

var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');
var os = require('os');

var dest = process.argv[2];

if (!dest) {
	return console.error('Missing path argument!');
}

// Ensure destination exists
mkdirp(path.join(dest, 'settings'), function(err) {
	if (err) {
		return console.error(err);
	}

	/**
	 * Copy root file
	 */
	fs.readFile(__dirname + '/../src/scss/kanbasu.scss', 'utf8', function(err, data) {
		if (err) {
			return console.error(err);
		}

		// Update path to partials
		var pathToAssets = path.relative(dest, __dirname + '/../src/scss');
		// Import project settings after Kanbasu default settings
		var result = data
			.replace(/@import '/g, "@import '"+pathToAssets+"/")
			.replace(/(settings\/settings';[\r\n])/g, "$1@import 'settings/settings';" + os.EOL);

		var destFile = path.join(dest, 'main.scss');
		fs.writeFile(destFile, result, 'utf8', function(err) {
			if (err) {
				return console.error(err);
			}
			console.log('Writing "' + destFile + '"');
		});
	});

	/**
	 * Copy settings file
	 */
	fs.readFile(__dirname + '/../src/scss/settings/_settings.scss', 'utf8', function(err, data) {
		if (err) {
			return console.error(err);
		}

		// Remove Sass !default flags
		var result = data.replace(/ !default/g, '');

		var destFile = path.join(dest, 'settings/_settings.scss');
		fs.writeFile(destFile, result, 'utf8', function(err) {
			if (err) {
				return console.error(err);
			}
			console.log('Writing "' + destFile + '"');
		});
	});
});
<|endoftext|>


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

    var _               = require('lodash'),
        _s              = require('underscore.string'),
        cfg             = require('nconf'),
        when            = require('when'),
        node            = require('when/node'),
        readDir         = node.lift(require('fs').readdir),
        join            = require('path').join,
        configProvider;

    var ThemesProvider = function () {
        this.themes = [];
        this.adminThemes = [];
        this.activeTheme;
        this.activeAdminTheme;
    };

    ThemesProvider.prototype.init = function () {
        var that = this;

        // Get reference to configProvider after initialization
        configProvider  = require('../providers').configProvider;

        return when
            .all([
                readDir(join(cfg.get('paths:clientStatic'), 'css/theme')).then(namesToThemes),
                readDir(cfg.get('paths:themes')).then(namesToThemes)
            ])
            .spread(function (adminThemes, themes) {
                that.themes = themes;
                that.adminThemes = adminThemes;

                that.selectActiveTheme();
                that.selectActiveAdminTheme();
            });
    };

    ThemesProvider.prototype.getActiveTheme = function() {
        return this.activeTheme;
    }

    ThemesProvider.prototype.getActiveAdminTheme = function() {
        return this.activeAdminTheme;
    }

    ThemesProvider.prototype.selectActiveTheme = function () {
        selectThemes(this.themes, cfg.get('theme:name'));
        this.activeTheme = _.find(this.themes, { active:true });
    };

    ThemesProvider.prototype.selectActiveAdminTheme = function () {
        selectThemes(this.adminThemes, cfg.get('admin:theme'));
        this.activeAdminTheme = _.find(this.adminThemes, { active:true });
    };

    ThemesProvider.prototype.getAdminThemes = function () {
        return when.resolve(this.adminThemes);
    };

    ThemesProvider.prototype.getThemes = function () {
        return when.resolve(this.themes);
    };

    ThemesProvider.prototype.checkTheme = function (id) {
        var theme = _.find(this.themes, { id:id });
        return !!theme ? when.resolve(theme) : when.reject();
    };

    ThemesProvider.prototype.checkAdminTheme = function (id) {
        var theme = _.find(this.adminThemes, { id:id });
        return !!theme ? when.resolve(theme) : when.reject();
    };

    ThemesProvider.prototype.updateTheme = function (id) {
        return this.checkTheme(id)
            .tap(function (theme) {
                return configProvider.saveConfig('theme:name', theme.id);
            })
            .tap(function (theme) {
                cfg.set('theme:name', theme.id);
                cfg.notify('set:theme:name', theme.id);
            });
    };

    ThemesProvider.prototype.updateAdminTheme = function (id) {
        return this.checkAdminTheme(id)
            .tap(function (theme) {
                return configProvider.saveConfig('admin:theme', id);
            })
            .tap(function () {
                cfg.set('admin:theme', id);
                cfg.notify('set:admin:theme', id);
            });
    };

    function selectThemes (themes, id) {
        _.each(themes, function (theme) {
            theme.active = theme.id == id;
        });
    }

    function nameToTheme (name) {
        var id = name.replace(/^(\w+)(\.\w+)*$/, '$1');
        return {
            id: id,
            name: _s.titleize(_s.humanize(id)),
            data: name
        };
    }

    function namesToThemes (fileNames) {
        return fileNames.map(nameToTheme);
    }

    var themesProvider = new ThemesProvider();

    cfg.on('set:theme:name', themesProvider.selectActiveTheme.bind(themesProvider));
    cfg.on('set:admin:theme', themesProvider.selectActiveAdminTheme.bind(themesProvider));

    module.exports = themesProvider;

}());<commit_msg>Comments<commit_after>(function () {
    "use strict";

    var _               = require('lodash'),
        _s              = require('underscore.string'),
        cfg             = require('nconf'),
        when            = require('when'),
        node            = require('when/node'),
        readDir         = node.lift(require('fs').readdir),
        join            = require('path').join,
        configProvider;

    var ThemesProvider = function () {
        this.themes = [];
        this.adminThemes = [];
        this.activeTheme;
        this.activeAdminTheme;
    };

    ThemesProvider.prototype.init = function () {
        var that = this;

        // Get reference to configProvider after initialization
        configProvider  = require('../providers').configProvider;

        return when
            .all([
                readDir(join(cfg.get('paths:clientStatic'), 'css/theme')).then(namesToThemes),
                readDir(cfg.get('paths:themes')).then(namesToThemes)
            ])
            .spread(function (adminThemes, themes) {
                that.themes = themes;
                that.adminThemes = adminThemes;

                that.selectActiveTheme();
                that.selectActiveAdminTheme();
            });
    };

    ThemesProvider.prototype.getActiveTheme = function() {
        return this.activeTheme;
    }

    ThemesProvider.prototype.getActiveAdminTheme = function() {
        return this.activeAdminTheme;
    }

    ThemesProvider.prototype.selectActiveTheme = function () {
        selectThemes(this.themes, cfg.get('theme:name'));
        this.activeTheme = _.find(this.themes, { active:true });
    };

    ThemesProvider.prototype.selectActiveAdminTheme = function () {
        selectThemes(this.adminThemes, cfg.get('admin:theme'));
        this.activeAdminTheme = _.find(this.adminThemes, { active:true });
    };

    ThemesProvider.prototype.getAdminThemes = function () {
        return when.resolve(this.adminThemes);
    };

    ThemesProvider.prototype.getThemes = function () {
        return when.resolve(this.themes);
    };

    ThemesProvider.prototype.checkTheme = function (id) {
        var theme = _.find(this.themes, { id:id });
        return !!theme ? when.resolve(theme) : when.reject();
    };

    ThemesProvider.prototype.checkAdminTheme = function (id) {
        var theme = _.find(this.adminThemes, { id:id });
        return !!theme ? when.resolve(theme) : when.reject();
    };

    ThemesProvider.prototype.updateTheme = function (id) {
        return this.checkTheme(id)
            .tap(function (theme) {
                return configProvider.saveConfig('theme:name', theme.id);
            })
            .tap(function (theme) {
                cfg.set('theme:name', theme.id);
                cfg.notify('set:theme:name', theme.id);
            });
    };

    ThemesProvider.prototype.updateAdminTheme = function (id) {
        return this.checkAdminTheme(id)
            .tap(function (theme) {
                return configProvider.saveConfig('admin:theme', id);
            })
            .tap(function () {
                cfg.set('admin:theme', id);
                cfg.notify('set:admin:theme', id);
            });
    };

    function selectThemes (themes, id) {
        _.each(themes, function (theme) {
            theme.active = theme.id == id;
        });
    }

    function nameToTheme (name) {
        var id = name.replace(/^(\w+)(\.\w+)*$/, '$1');
        return {
            id: id,
            name: _s.titleize(_s.humanize(id)),
            data: name
        };
    }

    function namesToThemes (fileNames) {
        return fileNames.map(nameToTheme);
    }

    var themesProvider = new ThemesProvider();

    // Update active (site and admin) themes
    cfg.on('set:theme:name', themesProvider.selectActiveTheme.bind(themesProvider));
    cfg.on('set:admin:theme', themesProvider.selectActiveAdminTheme.bind(themesProvider));

    module.exports = themesProvider;

}());<|endoftext|>


<commit_before>import React, {Component} from 'react';
import classNames from 'classnames';
import { Link } from 'react-router';
import {OverlayTrigger, Tooltip} from 'react-bootstrap';

export default class LeftMenu extends Component {
    showSubmenu = () => {
      const menu = document.getElementsByClassName('menu-product').length;
      if (menu > 0) {
        document.getElementById('Products').classList.add('hidden');
        document.getElementById('Products').classList.remove('menu-product');
      } else {
        document.getElementById('Products').classList.remove('hidden');
        document.getElementById('Products').classList.add('menu-product');
      }
    }
    showSubmenuMarket = () => {
      const marketing = document.getElementsByClassName('menu-marketing').length;
      console.log('marketing : ' + marketing);
      if (marketing > 0) {
        document.getElementById('Marketing').classList.add('hidden');
        document.getElementById('Marketing').classList.remove('menu-marketing');
      } else {
        document.getElementById('Marketing').classList.remove('hidden');
        document.getElementById('Marketing').classList.add('menu-marketing');
      }
    }
    render() {
      const styles = require('./leftMenu.scss');
      const logoImg = require('./KP-white.png');
      return (

                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-cart">Order</Tooltip>}>
                    <Link to={ `/orders` } className={ styles.menu }> </Link>
                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-product">Products</Tooltip>}>

Products

                                 Product

                                 Manage Custom Attribute

 Special Label and Other

                                 Exclusive Launch Product

                                 Best Seller

                                 Hot Item

                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-user">Customer</Tooltip>}>
                    <Link to={ `/customer` } className={ styles.menu }> </Link>
                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-marketing">Marketing</Tooltip>}>

Marketing

                                 Marketing

                                 Specific Group

                                 Brand and Member Discount Limitation

                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-setting">Setting</Tooltip>}>

                </OverlayTrigger>

        );
    }
}
<commit_msg>no message<commit_after>import React, {Component} from 'react';
import classNames from 'classnames';
import { Link } from 'react-router';
import {OverlayTrigger, Tooltip} from 'react-bootstrap';

export default class LeftMenu extends Component {
    showSubmenu = () => {
      const menu = document.getElementsByClassName('menu-product').length;
      console.log('menu : ' + menu);
      if (menu > 0) {
        document.getElementById('Products').classList.add('hidden');
        document.getElementById('Products').classList.remove('menu-product');
      } else {
        document.getElementById('Products').classList.remove('hidden');
        document.getElementById('Products').classList.add('menu-product');
        document.getElementById('Marketing').classList.add('hidden');
        document.getElementById('Marketing').classList.remove('menu-marketing');
      }
    }
    showSubmenuMarket = () => {
      const marketing = document.getElementsByClassName('menu-marketing').length;
      console.log('marketing : ' + marketing);
      if (marketing > 0) {
        document.getElementById('Marketing').classList.add('hidden');
        document.getElementById('Marketing').classList.remove('menu-marketing');
      } else {
        document.getElementById('Marketing').classList.remove('hidden');
        document.getElementById('Marketing').classList.add('menu-marketing');
        document.getElementById('Products').classList.add('hidden');
        document.getElementById('Products').classList.remove('menu-product');
      }
    }
    render() {
      const styles = require('./leftMenu.scss');
      const logoImg = require('./KP-white.png');
      return (

                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-cart">Order</Tooltip>}>
                    <Link to={ `/orders` } className={ styles.menu }> </Link>
                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-product">Products</Tooltip>}>

Products

                                 Product

                                 Manage Custom Attribute

 Special Label and Other

                                 Exclusive Launch Product

                                 Best Seller

                                 Hot Item

                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-user">Customer</Tooltip>}>
                    <Link to={ `/customer` } className={ styles.menu }> </Link>
                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-marketing">Marketing</Tooltip>}>

Marketing

                                 Marketing

                                 Specific Group

                                 Brand and Member Discount Limitation

                </OverlayTrigger>
                <OverlayTrigger placement="right" overlay={<Tooltip id="menu-setting">Setting</Tooltip>}>

                </OverlayTrigger>

        );
    }
}
<|endoftext|>


<commit_before>const path = require('path')
const semver = require('semver')
const fse = require('fs-extra')
const simpleGet = require('simple-get')
const decompress = require('decompress')
const resolveFrom = require('resolve-from')
const validateNpmPackageName = require('validate-npm-package-name')
const {pathTools} = require('@sanity/util')
const dynamicRequire = require('../../util/dynamicRequire')
const pkg = require('../../../package.json')

const {absolutify, pathIsEmpty} = pathTools

module.exports = async (context, url) => {
  const {prompt, workDir} = context
  let inProjectContext = false
  try {
    const projectManifest = await fse.readJson(path.join(workDir, 'sanity.json'))
    inProjectContext = Boolean(projectManifest.root)
  } catch (err) {
    // Intentional noop
  }

  let zip
  try {
    zip = await getZip(url)
  } catch (err) {
    err.message = `Failed to get template: ${err.message}`
    throw err
  }

  const manifest = zip.find(file => path.basename(file.path) === 'package.json')
  const baseDir = path.join(path.dirname(manifest.path), 'template')
  const templateFiles = zip.filter(file => file.type === 'file' && file.path.indexOf(baseDir) === 0)
  const manifestContent = manifest.data.toString()
  const tplVars = parseJson(manifestContent).sanityTemplate || {}
  const {minimumBaseVersion} = tplVars

  if (minimumBaseVersion) {
    const installed = getSanityVersion(workDir)
    if (semver.lt(installed, minimumBaseVersion)) {
      throw new Error(
        `Template requires Sanity at version ${minimumBaseVersion}, installed is ${installed}`
      )
    }
  }

  const name = await prompt.single({
    type: 'input',
    message: 'Plugin name:',
    default: tplVars.suggestedName || '',
    validate: async pkgName => {
      const {validForNewPackages, errors} = validateNpmPackageName(pkgName)
      if (!validForNewPackages) {
        return errors[0]
      }

      const outputPath = path.join(workDir, 'plugins', pkgName)
      const isEmpty = await pathIsEmpty(outputPath)
      if (inProjectContext && !isEmpty) {
        return 'Plugin with given name already exists in project'
      }

      return true
    }
  })

  let outputPath = path.join(workDir, 'plugins', name)
  if (!inProjectContext) {
    const cwdIsEmpty = await pathIsEmpty(workDir)
    outputPath = await prompt.single({
      type: 'input',
      message: 'Output path:',
      default: cwdIsEmpty ? workDir : path.join(workDir, name),
      validate: validateEmptyPath,
      filter: absolutify
    })
  }

  let createConfig = tplVars.requiresConfig
  if (typeof createConfig === 'undefined') {
    createConfig = await prompt.single({
      type: 'confirm',
      message: 'Does the plugin need a configuration file?',
      default: false
    })
  }

  await fse.ensureDir(outputPath)
  await Promise.all(
    templateFiles.map(file => {
      const filename = file.path.slice(baseDir.length)
      return fse.outputFile(path.join(outputPath, filename), file.data)
    })
  )

  return {name, outputPath, inPluginsPath: inProjectContext}
}

async function validateEmptyPath(dir) {
  const isEmpty = await pathIsEmpty(dir)
  return isEmpty ? true : 'Path is not empty'
}

function getZip(url) {
  return new Promise((resolve, reject) => {
    simpleGet.concat(url, (err, res, data) => {
      if (err) {
        reject(err)
        return
      }

      resolve(decompress(data))
    })
  })
}

function parseJson(json) {
  try {
    return JSON.parse(json)
  } catch (err) {
    return {}
  }
}

function getSanityVersion(workDir) {
  const basePkg = resolveFrom.silent(workDir, '@sanity/base/package.json')
  return basePkg ? dynamicRequire(basePkg).version : pkg.version
}
<commit_msg>[cli] Ensure template manifest is not inside node_modules<commit_after>const path = require('path')
const semver = require('semver')
const fse = require('fs-extra')
const simpleGet = require('simple-get')
const decompress = require('decompress')
const resolveFrom = require('resolve-from')
const validateNpmPackageName = require('validate-npm-package-name')
const {pathTools} = require('@sanity/util')
const dynamicRequire = require('../../util/dynamicRequire')
const pkg = require('../../../package.json')
const debug = require('../../debug')

const {absolutify, pathIsEmpty} = pathTools

module.exports = async (context, url) => {
  const {prompt, workDir} = context
  let inProjectContext = false
  try {
    const projectManifest = await fse.readJson(path.join(workDir, 'sanity.json'))
    inProjectContext = Boolean(projectManifest.root)
  } catch (err) {
    // Intentional noop
  }

  let zip
  try {
    zip = await getZip(url)
  } catch (err) {
    err.message = `Failed to get template: ${err.message}`
    throw err
  }

  const manifest = zip.find(
    file =>
      path.basename(file.path) === 'package.json'
      && !file.path.includes('node_modules')
  )

  if (!manifest) {
    throw new Error('Could not find `package.json` in template')
  }

  const baseDir = path.join(path.dirname(manifest.path), 'template')
  debug('Base directory resolved to %s', baseDir)

  const templateFiles = zip.filter(file => file.type === 'file' && file.path.indexOf(baseDir) === 0)
  const manifestContent = manifest.data.toString()
  const tplVars = parseJson(manifestContent).sanityTemplate || {}
  const {minimumBaseVersion} = tplVars

  if (minimumBaseVersion) {
    const installed = getSanityVersion(workDir)
    if (semver.lt(installed, minimumBaseVersion)) {
      throw new Error(
        `Template requires Sanity at version ${minimumBaseVersion}, installed is ${installed}`
      )
    }
  }

  const name = await prompt.single({
    type: 'input',
    message: 'Plugin name:',
    default: tplVars.suggestedName || '',
    validate: async pkgName => {
      const {validForNewPackages, errors} = validateNpmPackageName(pkgName)
      if (!validForNewPackages) {
        return errors[0]
      }

      const outputPath = path.join(workDir, 'plugins', pkgName)
      const isEmpty = await pathIsEmpty(outputPath)
      if (inProjectContext && !isEmpty) {
        return 'Plugin with given name already exists in project'
      }

      return true
    }
  })

  let outputPath = path.join(workDir, 'plugins', name)
  if (!inProjectContext) {
    const cwdIsEmpty = await pathIsEmpty(workDir)
    outputPath = await prompt.single({
      type: 'input',
      message: 'Output path:',
      default: cwdIsEmpty ? workDir : path.join(workDir, name),
      validate: validateEmptyPath,
      filter: absolutify
    })
  }

  let createConfig = tplVars.requiresConfig
  if (typeof createConfig === 'undefined') {
    createConfig = await prompt.single({
      type: 'confirm',
      message: 'Does the plugin need a configuration file?',
      default: false
    })
  }

  await fse.ensureDir(outputPath)
  await Promise.all(
    templateFiles.map(file => {
      const filename = file.path.slice(baseDir.length)
      return fse.outputFile(path.join(outputPath, filename), file.data)
    })
  )

  return {name, outputPath, inPluginsPath: inProjectContext}
}

async function validateEmptyPath(dir) {
  const isEmpty = await pathIsEmpty(dir)
  return isEmpty ? true : 'Path is not empty'
}

function getZip(url) {
  return new Promise((resolve, reject) => {
    simpleGet.concat(url, (err, res, data) => {
      if (err) {
        reject(err)
        return
      }

      resolve(decompress(data))
    })
  })
}

function parseJson(json) {
  try {
    return JSON.parse(json)
  } catch (err) {
    return {}
  }
}

function getSanityVersion(workDir) {
  const basePkg = resolveFrom.silent(workDir, '@sanity/base/package.json')
  return basePkg ? dynamicRequire(basePkg).version : pkg.version
}
<|endoftext|>


<commit_before>
/**
 * Construct a new ServiceFinder. This is a single-use object that does a DNS
 * multicast search on creation.
 * @constructor
 * @param {function} callback The callback to be invoked when this object is
 *                            updated, or when an error occurs (passes string).
 */
var ServiceFinder = function(callback) {
  var me = this;
  this.callback_ = callback;
  this.pendingCallback_ = false;
  this.active_ = true;
  this.byIP_ = {};
  this.byService_ = {};
  this.socket_ = chrome.experimental.socket || chrome.socket;

  this.socket_.create('udp', {}, function(createInfo) {
    me.sock_ = createInfo['socketId'];

    // NOTE: This will only search for entries on the first/default network
    // interface.
    me.socket_.bind(me.sock_, '0.0.0.0', 0, function(result) {
      if (result) {
        return me.done_('could not bind socket: ' + result);
      }
      me.recv_.apply(me);
      me.broadcast.apply(me);
    });
  });
};

/**
 * Sorts the passed list of string IPs in-place.
 * @private
 */
ServiceFinder.sortIps_ = function(arg) {
  arg.sort(ServiceFinder.sortIps_.sort);
  return arg;
};
ServiceFinder.sortIps_.sort = function(l, r) {
  // TODO: support v6.
  var lp = l.split('.').map(ServiceFinder.sortIps_.toInt_);
  var rp = r.split('.').map(ServiceFinder.sortIps_.toInt_);
  for (var i = 0; i < Math.min(lp.length, rp.length); ++i) {
    if (lp[i] < rp[i]) {
      return -1;
    } else if (lp[i] > rp[i]) {
      return +1;
    }
  }
  return 0;
};
ServiceFinder.sortIps_.toInt_ = function(i) { return +i };

ServiceFinder.prototype.services = function(opt_ip) {
  var k = Object.keys(opt_ip ? this.byIP_[opt_ip] : this.byService_);
  k.sort();
  return k;
};

ServiceFinder.prototype.ips = function(opt_service) {
  var k = Object.keys(opt_service ? this.byService_[opt_service] : this.byIP_);
  return ServiceFinder.sortIps_(k);
};

/**
 * @private
 */
ServiceFinder.prototype.done_ = function(opt_error) {
  this.active_ = false;
  this.callback_(opt_error);
};

/**
 * Handles an incoming UDP packet.
 * @private
 */
ServiceFinder.prototype.recv_ = function(info) {
  this.socket_.recvFrom(this.sock_, this.recv_.bind(this));
  if (!info) {
    // We didn't receive any data, we were just setting up recvFrom.
    return false;
  }

  var getDefault_ = function(o, k, def) {
    (k in o) || false == (o[k] = def);
    return o[k];
  };

  // Update our local database.
  // TODO: Resolve IPs using the dns extension.
  var packet = DNSPacket.parse(info.data);
  var byIP = getDefault_(this.byIP_, info.address, {});

  packet.each('an', 12, function(rec) {
    var ptr = rec.asName();
    var byService = getDefault_(this.byService_, ptr, {})
    byService[info.address] = true;
    byIP[ptr] = true;
  }.bind(this));

  // Ping! Something new is here. Only update every 25ms.
  if (!this.pendingCallback_) {
    this.pendingCallback_ = true;
    setTimeout(function() {
      this.pendingCallback_ = false;
      this.callback_();
    }.bind(this), 25);
  }
};

/**
 * Broadcasts for services. Hi, everybody!
 */
ServiceFinder.prototype.broadcast = function(done) {
  var packet = new DNSPacket();
  packet.push('qd', new DNSRecord('_services._dns-sd._udp.local', 12, 1));

  var raw = packet.serialize();
  this.socket_.sendTo(this.sock_, raw, '224.0.0.251', 5353,
      function(writeInfo) {
    if (writeInfo.bytesWritten != raw.byteLength) {
      this.fail_('could not write DNS packet: ' + raw);
    }
  });

  // After five seconds, if we haven't seen anyone, we're unlikely to.
  setTimeout(this.callback_, 5000);
};

window.addEventListener('load', function() {
  var results = document.getElementById('results');
  var serviceDb = {
    '_workstation._tcp': 'Workgroup Manager',
    '_ssh._tcp': 'SSH',
    '_daap._tcp': 'iTunes',
  };
  var refreshBtn = document.getElementById('refresh');
  refreshBtn.origText = refreshBtn.innerHTML;
  refreshBtn.innerHTML = '…';
  var modeBtn = document.getElementById('mode');

  var getHtml_ = function(category, key) {
    if (category == finder.services && key in serviceDb) {
      return key + ' ' + serviceDb[key] + '';
    }
    return key;
  };

  var finder;
  var mode = 'service';
  var callback_ = function(opt_error) {
    refreshBtn.innerHTML = refreshBtn.origText;
    if (opt_error) {
      return console.warn('error', opt_error);
    }

    var outer = finder.services;
    var inner = finder.ips;
    if (mode == 'ip') {
      outer = finder.ips;
      inner = finder.services;
    }
    // TODO: render information about outer/inner
    // for IPs, render 'last seen at...'
    // for services, render known service type.

    results.innerHTML = '';
    outer.apply(finder).forEach(function(o) {
      var li = document.createElement('li');
      li.innerHTML = getHtml_(outer, o);
      results.appendChild(li);

      var ul = document.createElement('ul');
      inner.call(finder, o).forEach(function(i) {
        var li = document.createElement('li');
        li.innerHTML = getHtml_(inner, i);
        ul.appendChild(li);
      });
      ul.childNodes.length && results.appendChild(ul);
    });
  };
  finder = new ServiceFinder(callback_);

  refreshBtn.addEventListener('click', function() {
    refreshBtn.innerHTML = '…';
    finder.broadcast();
  });
  modeBtn.addEventListener('click', function() {
    var h = document.getElementById('mode-span');
    if (mode == 'service') {
      mode = 'ip';
      h.innerText = 'IP';
    } else {
      mode = 'service';
      h.innerText = 'Service';
    }
    callback_();
  });
  modeBtn.click(); modeBtn.click();

  document.getElementById('clear-refresh').addEventListener('click',
      function() {
    finder = new ServiceFinder(callback_);
    // TODO: Make the working indicator a spinner, and start it up here.
  });
});

<commit_msg>Optional support for multiple network interfaces<commit_after>
/**
 * Construct a new ServiceFinder. This is a single-use object that does a DNS
 * multicast search on creation.
 * @constructor
 * @param {function} callback The callback to be invoked when this object is
 *                            updated, or when an error occurs (passes string).
 */
var ServiceFinder = function(callback) {
  this.callback_ = callback;
  this.pendingCallback_ = false;
  this.active_ = true;
  this.byIP_ = {};
  this.byService_ = {};
  this.sock_ = [];
  this.socket_ = [];

  ServiceFinder.forEachAddress_(function(address) {
    if (address.indexOf(':') != -1) {
      // TODO: ipv6.
      console.log('IPv6 address unsupported', address);
      return true;
    }
    console.log('Broadcasting to address', address);

    ServiceFinder.bindToAddress_(address, function(socket) {
      if (!socket) {
        return false;
      }

      // Store the socket, set up a recieve handler, and broadcast on it.
      this.socket_.push(socket);
      this.recv_(socket);
      this.broadcast(socket);
    }.bind(this));
  }.bind(this));
};

ServiceFinder.api = chrome.socket || chrome.experimental.socket;

/**
 * Invokes the callback for every local network address on the system.
 * @private
 * @param {function} callback to invoke
 */
ServiceFinder.forEachAddress_ = function(callback) {
  var api = ServiceFinder.api;

  if (!api.getNetworkList) {
    // Short-circuit for Chrome built before r155662.
    callback('0.0.0.0', '*');
    return true;
  }

  api.getNetworkList(function(adapterInfo) {
    adapterInfo.forEach(function(info) {
      callback(info['address'], info['name']);
    });
  });
};

/**
 * Creates UDP socket bound to the specified address, passing it to the
 * callback. Passes null on failure.
 * @private
 * @param {string} address to bind to
 * @param {function} callback to invoke when done
 */
ServiceFinder.bindToAddress_ = function(address, callback) {
  var api = ServiceFinder.api;

  api.create('udp', {}, function(createInfo) {
    api.bind(createInfo['socketId'], address, 0, function(result) {
      if (result) {
        console.warn('could not bind udp socket', address);
        callback(null);
      } else {
        callback(createInfo['socketId']);
      }
    });
  });
};

/**
 * Sorts the passed list of string IPs in-place.
 * @private
 */
ServiceFinder.sortIps_ = function(arg) {
  arg.sort(ServiceFinder.sortIps_.sort);
  return arg;
};
ServiceFinder.sortIps_.sort = function(l, r) {
  // TODO: support v6.
  var lp = l.split('.').map(ServiceFinder.sortIps_.toInt_);
  var rp = r.split('.').map(ServiceFinder.sortIps_.toInt_);
  for (var i = 0; i < Math.min(lp.length, rp.length); ++i) {
    if (lp[i] < rp[i]) {
      return -1;
    } else if (lp[i] > rp[i]) {
      return +1;
    }
  }
  return 0;
};
ServiceFinder.sortIps_.toInt_ = function(i) { return +i };

ServiceFinder.prototype.services = function(opt_ip) {
  var k = Object.keys(opt_ip ? this.byIP_[opt_ip] : this.byService_);
  k.sort();
  return k;
};

ServiceFinder.prototype.ips = function(opt_service) {
  var k = Object.keys(opt_service ? this.byService_[opt_service] : this.byIP_);
  return ServiceFinder.sortIps_(k);
};

/**
 * @private
 */
ServiceFinder.prototype.done_ = function(opt_error) {
  this.active_ = false;
  this.callback_(opt_error);
};

/**
 * Handles an incoming UDP packet.
 * @private
 */
ServiceFinder.prototype.recv_ = function(sock, info) {
  ServiceFinder.api.recvFrom(sock, this.recv_.bind(this, sock));
  if (!info) {
    console.info('no data on socket', sock);
    // We didn't receive any data, we were just setting up recvFrom.
    return false;
  }

  var getDefault_ = function(o, k, def) {
    (k in o) || false == (o[k] = def);
    return o[k];
  };

  // Update our local database.
  // TODO: Resolve IPs using the dns extension.
  var packet = DNSPacket.parse(info.data);
  var byIP = getDefault_(this.byIP_, info.address, {});

  packet.each('an', 12, function(rec) {
    var ptr = rec.asName();
    var byService = getDefault_(this.byService_, ptr, {})
    byService[info.address] = true;
    byIP[ptr] = true;
  }.bind(this));

  // Ping! Something new is here. Only update every 25ms.
  if (!this.pendingCallback_) {
    this.pendingCallback_ = true;
    setTimeout(function() {
      this.pendingCallback_ = false;
      this.callback_();
    }.bind(this), 25);
  }
};

/**
 * Broadcasts for services. Hi, everybody!
 */
ServiceFinder.prototype.broadcast = function(opt_sock) {
  if (!opt_sock) {
    this.socket_.forEach(this.broadcast);

    // After five seconds, if we haven't seen anyone, we're unlikely to.
    setTimeout(this.callback_, 5000);
    return;
  }

  var packet = new DNSPacket();
  packet.push('qd', new DNSRecord('_services._dns-sd._udp.local', 12, 1));

  var raw = packet.serialize();
  ServiceFinder.api.sendTo(opt_sock, raw, '224.0.0.251', 5353,
      function(writeInfo) {
    if (writeInfo.bytesWritten != raw.byteLength) {
      this.fail_('could not write DNS packet: ' + raw);
    }
  });
};

window.addEventListener('load', function() {
  var results = document.getElementById('results');
  var serviceDb = {
    '_workstation._tcp': 'Workgroup Manager',
    '_ssh._tcp': 'SSH',
    '_daap._tcp': 'iTunes',
  };
  var refreshBtn = document.getElementById('refresh');
  refreshBtn.origText = refreshBtn.innerHTML;
  refreshBtn.innerHTML = '…';
  var modeBtn = document.getElementById('mode');

  var getHtml_ = function(category, key) {
    if (category == finder.services && key in serviceDb) {
      return key + ' ' + serviceDb[key] + '';
    }
    return key;
  };

  var finder;
  var mode = 'service';
  var callback_ = function(opt_error) {
    refreshBtn.innerHTML = refreshBtn.origText;
    if (opt_error) {
      return console.warn('error', opt_error);
    }

    var outer = finder.services;
    var inner = finder.ips;
    if (mode == 'ip') {
      outer = finder.ips;
      inner = finder.services;
    }
    // TODO: render information about outer/inner
    // for IPs, render 'last seen at...'
    // for services, render known service type.

    results.innerHTML = '';
    outer.apply(finder).forEach(function(o) {
      var li = document.createElement('li');
      li.innerHTML = getHtml_(outer, o);
      results.appendChild(li);

      var ul = document.createElement('ul');
      inner.call(finder, o).forEach(function(i) {
        var li = document.createElement('li');
        li.innerHTML = getHtml_(inner, i);
        ul.appendChild(li);
      });
      ul.childNodes.length && results.appendChild(ul);
    });
  };
  finder = new ServiceFinder(callback_);

  refreshBtn.addEventListener('click', function() {
    refreshBtn.innerHTML = '…';
    finder.broadcast();
  });
  modeBtn.addEventListener('click', function() {
    var h = document.getElementById('mode-span');
    if (mode == 'service') {
      mode = 'ip';
      h.innerText = 'IP';
    } else {
      mode = 'service';
      h.innerText = 'Service';
    }
    callback_();
  });
  modeBtn.click(); modeBtn.click();

  document.getElementById('clear-refresh').addEventListener('click',
      function() {
    // TODO: Destroy all old sockets. If we do this however, socket.recvFrom
    // spews logs for any incoming message to the old socket (perhaps we can do
    // this better).
    finder = new ServiceFinder(callback_);
    // TODO: Make the working indicator a spinner, and start it up here.
  });
});

<|endoftext|>


<commit_before>var ipc = require('ipc');
var fs = require('fs');

var container = document.getElementById("editor");
var hot = new Handsontable(container, {
  colHeaders: true,
  rowHeaders: true,
  columnSorting: true,
  contextMenu: false
});

container.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  if (hot.getSelected()[0] == 0) {
    rowAbove.enabled = false
  }
  if (hot.getSelected()[1] == 0) {
    columnLeft.enabled = false
  }
  menu.popup(remote.getCurrentWindow());
  rowAbove.enabled = true
  columnLeft.enabled = true
}, false);

ipc.on('loadData', function(data) {
  csv = $.csv.toArrays(data);
  hot.loadData(csv);
  fixRaggedRows(csv);
});

ipc.on('saveData', function(fileName) {
  data = $.csv.fromArrays(hot.getData());
  fs.writeFile(fileName, data, function (err) {
  });
  document.title = fileName;
});

ipc.on('getCSV', function() {
  data = $.csv.fromArrays(hot.getData());
  ipc.send('sendCSV', data);
})

ipc.on('validate', function() {
  validate();
});

ipc.on('ragged_rows', function() {
  csv = hot.getData();
  fixRaggedRows(csv);
});

// How to use:
// getValidation("Example,CSV,content\na,b,c\n")
//  .then(function(validation) {console.log(validation)})

function getValidation(content) {
  request = require('request');
  content = new Buffer(content).toString("base64");
  content = "editor.csv;data:text/csv;base64," + content;
  return new Promise(function(resolve, reject) {
    request.post("http://csvlint.io/package.json", { formData: {"files_data[]": content } }, function(error, response, body) {

      if (error) return reject(error);

      var packageURL = JSON.parse(response.body).package.url;
      var interval = setInterval(function() {
        request.get(packageURL + ".json", function(error, response, body) {
          try {
            var validationURL = JSON.parse(body).package.validations[0].url;
            clearInterval(interval);
            request.get(validationURL + ".json", function(error, response, body) {
              if (error) return reject(error);
              resolve(JSON.parse(body));
            });
          } catch(e) {}
        });
      }, 1000);

    });
  });
}

// Splits validation returned from CSVLint into errors, warnings and info messages

function validate() {
  data = $.csv.fromArrays(hot.getData());
  $('#right-panel').removeClass("hidden")
  $('#message-panel').html("

Loading validation results...

");
  getValidation(data).then(function(json_validation) {
    errors = json_validation.validation.errors
    warnings = json_validation.validation.warnings
    info_messages = json_validation.validation.info
    console.error(errors)
    console.warn(warnings)
    console.info(info_messages);
    displayValidationMessages(json_validation.validation);
  });
}

function displayValidationMessages(validation) {
  var $messagePanel = $('#message-panel');
  $messagePanel.html("
Validation results
")
  resultsTemplate = _.template('
<%= validation.errors.length %> errors, <%= validation.warnings.length %> warnings and <%= validation.info.length %> info messages:
')
  $messagePanel.append(resultsTemplate({'validation': validation}));

  var messageTemplate = _.template('<div class="<%= cssClass %>">
<%= type %> <% if (row) print("on row " + row) %> <% if (col) print("on column " + col) %>

');
  var messages = _.flatten([
    _.map(validation.errors,   function(d) { return _.extend({}, d, { cssClass: 'message validation-error' }) }),
    _.map(validation.warnings, function(d) { return _.extend({}, d, { cssClass: 'message validation-warning' }) }),
    _.map(validation.info,     function(d) { return _.extend({}, d, { cssClass: 'message validation-info' }) })
  ]);
  if (messages.length) {
    var elements = _.map(messages, function(message) {
      return $(messageTemplate(message)).data(message);
    });
    $messagePanel.append(elements);
  } else {
    $messagePanel.append('
CSV Valid!
');
  }

  clearHighlights();

  $messagePanel.on('click', '.message', function() {
    highlightCell($(this).data());
  });
}

function highlightCell(d) {
  scrollToCell(d.row, d.col);
  hot.updateSettings({
    // set the new renderer for every cell
    cells: function (row, col, prop) {
      if (row === d.row - 1 || col === d.col - 1) {
      return { renderer: errorRenderer };
      }
      return {};
    }
  });
}

function scrollToCell(row, col) {
  row = row || 1;
  col = col || 1;
  hot.selectCell(row-1, col-1);
  hot.deselectCell();
}

function clearHighlights() {
  hot.updateSettings({
    cells: null
  });
}

function errorRenderer(instance, td, row, col, prop, value, cellProperties) {
  Handsontable.renderers.TextRenderer.apply(this, arguments);
  td.style.background = 'red';
}

function getMaxColumns(csv_array) {
  max_columns = 0
  for (var i = 0; i < csv_array.length; i++) {
    col_length = csv_array[i].length
    if (col_length > max_columns) {
      max_columns = col_length
    }
  }
  return max_columns
}

// Fills undefined cells with an empty string, keeping the table in a
// rectangular format

function fixRaggedRows(csv_array) {
  ragged_rows = 0;
  //
  for (var y = 0; y < csv_array.length; y++) {
    for (var x = 0; x < getMaxColumns(csv_array); x++) {
      if (hot.getDataAtCell(y,x) === undefined || hot.getDataAtCell(y,x) === null) {
        if (ragged_rows == 0) {
          if (confirm("Your file has ragged rows, do you want to correct this?")) {
            ragged_rows = 1
            fixCell(csv_array,y,x)
          }
          else {ragged_rows = -1}
        }
        else if (ragged_rows == 1) {
          fixCell(csv_array,y,x)
        }
      }
    }
  }
  updateTable(csv_array)
}

function fixCell(csv_array,y,x) {
  csv_array[y].push("")
  console.log("Cell (" + String.fromCharCode(97 + x).toUpperCase() + "," + (y + 1) + ") has been added to file")
}

function updateTable(csv_array) {
  hot.updateSettings ({
    data: csv_array,
  });
}

$('button[data-dismiss=alert]').click(function() {
  $(this).parent('.alert').addClass('hidden')
})
<commit_msg>Pass message type as parameter instead of a CSS class<commit_after>var ipc = require('ipc');
var fs = require('fs');

var container = document.getElementById("editor");
var hot = new Handsontable(container, {
  colHeaders: true,
  rowHeaders: true,
  columnSorting: true,
  contextMenu: false
});

container.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  if (hot.getSelected()[0] == 0) {
    rowAbove.enabled = false
  }
  if (hot.getSelected()[1] == 0) {
    columnLeft.enabled = false
  }
  menu.popup(remote.getCurrentWindow());
  rowAbove.enabled = true
  columnLeft.enabled = true
}, false);

ipc.on('loadData', function(data) {
  csv = $.csv.toArrays(data);
  hot.loadData(csv);
  fixRaggedRows(csv);
});

ipc.on('saveData', function(fileName) {
  data = $.csv.fromArrays(hot.getData());
  fs.writeFile(fileName, data, function (err) {
  });
  document.title = fileName;
});

ipc.on('getCSV', function() {
  data = $.csv.fromArrays(hot.getData());
  ipc.send('sendCSV', data);
})

ipc.on('validate', function() {
  validate();
});

ipc.on('ragged_rows', function() {
  csv = hot.getData();
  fixRaggedRows(csv);
});

// How to use:
// getValidation("Example,CSV,content\na,b,c\n")
//  .then(function(validation) {console.log(validation)})

function getValidation(content) {
  request = require('request');
  content = new Buffer(content).toString("base64");
  content = "editor.csv;data:text/csv;base64," + content;
  return new Promise(function(resolve, reject) {
    request.post("http://csvlint.io/package.json", { formData: {"files_data[]": content } }, function(error, response, body) {

      if (error) return reject(error);

      var packageURL = JSON.parse(response.body).package.url;
      var interval = setInterval(function() {
        request.get(packageURL + ".json", function(error, response, body) {
          try {
            var validationURL = JSON.parse(body).package.validations[0].url;
            clearInterval(interval);
            request.get(validationURL + ".json", function(error, response, body) {
              if (error) return reject(error);
              resolve(JSON.parse(body));
            });
          } catch(e) {}
        });
      }, 1000);

    });
  });
}

// Splits validation returned from CSVLint into errors, warnings and info messages

function validate() {
  data = $.csv.fromArrays(hot.getData());
  $('#right-panel').removeClass("hidden")
  $('#message-panel').html("

Loading validation results...

");
  getValidation(data).then(function(json_validation) {
    errors = json_validation.validation.errors
    warnings = json_validation.validation.warnings
    info_messages = json_validation.validation.info
    console.error(errors)
    console.warn(warnings)
    console.info(info_messages);
    displayValidationMessages(json_validation.validation);
  });
}

function displayValidationMessages(validation) {
  var $messagePanel = $('#message-panel');
  $messagePanel.html("
Validation results
")
  resultsTemplate = _.template('
<%= validation.errors.length %> errors, <%= validation.warnings.length %> warnings and <%= validation.info.length %> info messages:
')
  $messagePanel.append(resultsTemplate({'validation': validation}));

  var messageTemplate = _.template('

<%= type %> <% if (row) print("on row " + row) %> <% if (col) print("on column " + col) %>

');
  var messages = _.flatten([
    _.map(validation.errors,   function(d) { return _.extend({}, d, { msg_type: 'error' }) }),
    _.map(validation.warnings, function(d) { return _.extend({}, d, { msg_type: 'warning' }) }),
    _.map(validation.info,     function(d) { return _.extend({}, d, { msg_type: 'info' }) })
  ]);
  if (messages.length) {
    var elements = _.map(messages, function(message) {
      return $(messageTemplate(message)).data(message)
        .addClass('message')
        .addClass('validation-' + message.msg_type);
    });
    $messagePanel.append(elements);
  } else {
    $messagePanel.append('
CSV Valid!
');
  }

  clearHighlights();

  $messagePanel.on('click', '.message', function() {
    highlightCell($(this).data());
  });
}

function highlightCell(d) {
  scrollToCell(d.row, d.col);
  hot.updateSettings({
    // set the new renderer for every cell
    cells: function (row, col, prop) {
      if (row === d.row - 1 || col === d.col - 1) {
      return { renderer: errorRenderer };
      }
      return {};
    }
  });
}

function scrollToCell(row, col) {
  row = row || 1;
  col = col || 1;
  hot.selectCell(row-1, col-1);
  hot.deselectCell();
}

function clearHighlights() {
  hot.updateSettings({
    cells: null
  });
}

function errorRenderer(instance, td, row, col, prop, value, cellProperties) {
  Handsontable.renderers.TextRenderer.apply(this, arguments);
  td.style.background = 'red';
}

function getMaxColumns(csv_array) {
  max_columns = 0
  for (var i = 0; i < csv_array.length; i++) {
    col_length = csv_array[i].length
    if (col_length > max_columns) {
      max_columns = col_length
    }
  }
  return max_columns
}

// Fills undefined cells with an empty string, keeping the table in a
// rectangular format

function fixRaggedRows(csv_array) {
  ragged_rows = 0;
  //
  for (var y = 0; y < csv_array.length; y++) {
    for (var x = 0; x < getMaxColumns(csv_array); x++) {
      if (hot.getDataAtCell(y,x) === undefined || hot.getDataAtCell(y,x) === null) {
        if (ragged_rows == 0) {
          if (confirm("Your file has ragged rows, do you want to correct this?")) {
            ragged_rows = 1
            fixCell(csv_array,y,x)
          }
          else {ragged_rows = -1}
        }
        else if (ragged_rows == 1) {
          fixCell(csv_array,y,x)
        }
      }
    }
  }
  updateTable(csv_array)
}

function fixCell(csv_array,y,x) {
  csv_array[y].push("")
  console.log("Cell (" + String.fromCharCode(97 + x).toUpperCase() + "," + (y + 1) + ") has been added to file")
}

function updateTable(csv_array) {
  hot.updateSettings ({
    data: csv_array,
  });
}

$('button[data-dismiss=alert]').click(function() {
  $(this).parent('.alert').addClass('hidden')
})
<|endoftext|>