<commit_before>describe("Journal", function() {
  beforeEach(function() {
    $("body").append($('

'));
  });
  afterEach(function() {
    $('#sandbox').remove();
  });

  it("show add item action in journal panel", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox .wikimate-story').dblclick();
    $('.wikimate-story textarea').text("hello world\n");
    Keyboard.hitEnter($('.wikimate-story textarea'));

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(1);
  });

  it("records actions", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox .wikimate-story').dblclick();
    $('.wikimate-story textarea').text("hello\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("hello2\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("").focusout();

    var actions = $('#sandbox .wikimate-journal .action').map(function(_, element) {
      return $(element).data('data');
    });

    expect(actions.length).toEqual(3);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('edit');
    expect(actions[2].type).toEqual('remove');
  });

  it("highlight item and action when mouseover", function() {
    $('#sandbox').wikimate({
      story: [{ "id": "1", "type": "paragraph", "text": "paragraph 1\n" }]
    }).wikimate('journal', [{id: '1', type: 'add', item: { "id": "1", "type": "paragraph", "text": "paragraph 1\n" }}]);

    expect($('#1').hasClass('highlight')).toEqual(false);
    $('.wikimate-journal .action').mouseover();
    expect($('#1').hasClass('highlight')).toEqual(true);
    $('.wikimate-journal .action').mouseleave();
    expect($('#1').hasClass('highlight')).toEqual(false);
  });

  it("undo last action", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox .wikimate-story').dblclick();
    $('.wikimate-story textarea').text("hello\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("hello2\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("").focusout();

    $('#sandbox').wikimate('undo');

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(2);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('edit');

    var items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(1);
    expect(items[0].text).toEqual("hello2\n");
  });

  it("undo remove action should add item back to removed position", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello2").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello3").focusout();

    var items = $('#sandbox').wikimate('story');

    $('#' + items[1].id).story_item('edit');

    $('#sandbox textarea').text("").focusout();
    $('#' + items[0].id).story_item('edit');
    $('#sandbox textarea').text("").focusout();

    $('#sandbox').wikimate('undo');
    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(4);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('add');
    expect(actions[2].type).toEqual('add');
    expect(actions[3].type).toEqual('remove');

    items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(2);
    expect(items[0].text).toEqual("hello");
    expect(items[1].text).toEqual("hello3");

    $('#sandbox').wikimate('undo');

    actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(3);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('add');
    expect(actions[2].type).toEqual('add');

    items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(3);
    expect(items[0].text).toEqual("hello");
    expect(items[1].text).toEqual("hello2");
    expect(items[2].text).toEqual("hello3");
  });

  it("undo add action should remove item", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello2").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello3").focusout();

    $('#sandbox').wikimate('undo');

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(2);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('add');
    var items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(2);
    expect(items[0].text).toEqual("hello");
    expect(items[1].text).toEqual("hello2");
  });

  it("undo edit action should update item", function() {
    $('#sandbox').wikimate({
      story: [{ "id": "3", "type": "paragraph", "text": "3" }, { "id": "1", "type": "paragraph", "text": "2" }]
    }).wikimate('journal', [
      {"id": "1", "type": "add", "item": { "id": "1", "type": "paragraph", "text": "1" }},
      {"id": "3", "type": "add", "item": { "id": "1", "type": "paragraph", "text": "3" }, after: '1'},
      {"id": "1", "type": "move", "order": ["3", "1"]},
      {"id": "1", "type": "edit", "item": { "id": "1", "type": "paragraph", "text": "2" }}
    ]);

    $('#sandbox').wikimate('undo');
    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(3);

    var items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(2);
    expect(items[1].text).toEqual("1");
  });

  it("undo move action should move item back to original position", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello2").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello3").focusout();

    var items = $('#sandbox .item');
    $(items[1]).insertAfter(items[2]);

    $(items[1]).story_item('moved', {
      order: [items[0].id, items[2].id, items[1].id]
    });

    // check move successfully
    expect($('#sandbox').wikimate('journal').length).toEqual(4);

    $('#sandbox').wikimate('undo');

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(3);
    expect(actions[0].type).toEqual('add');
    expect(actions[0].type).toEqual('add');
    expect(actions[0].type).toEqual('add');

    var orderedText = $.map($('#sandbox .item p'), function(item) {
      return $(item).text();
    });
    expect(orderedText).toEqual(['hello', 'hello2', 'hello3']);
  });
});
<commit_msg>added test for showing action tooltip<commit_after>describe("Journal", function() {
  beforeEach(function() {
    $("body").append($('

'));
  });
  afterEach(function() {
    $('#sandbox').remove();
  });

  it("show add item action in journal panel", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox .wikimate-story').dblclick();
    $('.wikimate-story textarea').text("hello world\n");
    Keyboard.hitEnter($('.wikimate-story textarea'));

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(1);
  });

  it("records actions", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox .wikimate-story').dblclick();
    $('.wikimate-story textarea').text("hello\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("hello2\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("").focusout();

    var actions = $('#sandbox .wikimate-journal .action').map(function(_, element) {
      return $(element).data('data');
    });

    expect(actions.length).toEqual(3);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('edit');
    expect(actions[2].type).toEqual('remove');
  });

  it("highlight item and action when mouseover", function() {
    $('#sandbox').wikimate({
      story: [{ "id": "1", "type": "paragraph", "text": "paragraph 1\n" }]
    }).wikimate('journal', [{id: '1', type: 'add', item: { "id": "1", "type": "paragraph", "text": "paragraph 1\n" }}]);

    expect($('#1').hasClass('highlight')).toEqual(false);
    $('.wikimate-journal .action').mouseover();
    expect($('#1').hasClass('highlight')).toEqual(true);
    $('.wikimate-journal .action').mouseleave();
    expect($('#1').hasClass('highlight')).toEqual(false);
  });

  it("show diff tooltip on action element when mouseover", function() {
    $('#sandbox').wikimate({
      story: [{ "id": "1", "type": "paragraph", "text": "paragraph 1\n" }]
    }).wikimate('journal', [{id: '1', type: 'add', item: { "id": "1", "type": "paragraph", "text": "paragraph 1\n" }}]);

    expect($('.diff').length).toEqual(0);
    $('.wikimate-journal .action').mouseover();
    expect($('.diff').length).toEqual(1);
    var action = $('.wikimate-journal .action');
    var tip = $('.wikimate .diff');
    expect(tip.offset().left).toEqual(action.offset().left + action.width() * 3 / 4);
    expect(tip.offset().top).toEqual(action.offset().top - tip.height());
    $('.wikimate-journal .action').mouseleave();
    expect($('.diff').length).toEqual(0);
  });

  it("undo last action", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox .wikimate-story').dblclick();
    $('.wikimate-story textarea').text("hello\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("hello2\n").focusout();

    $('.item').story_item('edit');
    $('.wikimate-story textarea').text("").focusout();

    $('#sandbox').wikimate('undo');

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(2);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('edit');

    var items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(1);
    expect(items[0].text).toEqual("hello2\n");
  });

  it("undo remove action should add item back to removed position", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello2").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello3").focusout();

    var items = $('#sandbox').wikimate('story');

    $('#' + items[1].id).story_item('edit');

    $('#sandbox textarea').text("").focusout();
    $('#' + items[0].id).story_item('edit');
    $('#sandbox textarea').text("").focusout();

    $('#sandbox').wikimate('undo');
    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(4);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('add');
    expect(actions[2].type).toEqual('add');
    expect(actions[3].type).toEqual('remove');

    items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(2);
    expect(items[0].text).toEqual("hello");
    expect(items[1].text).toEqual("hello3");

    $('#sandbox').wikimate('undo');

    actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(3);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('add');
    expect(actions[2].type).toEqual('add');

    items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(3);
    expect(items[0].text).toEqual("hello");
    expect(items[1].text).toEqual("hello2");
    expect(items[2].text).toEqual("hello3");
  });

  it("undo add action should remove item", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello2").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello3").focusout();

    $('#sandbox').wikimate('undo');

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(2);
    expect(actions[0].type).toEqual('add');
    expect(actions[1].type).toEqual('add');
    var items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(2);
    expect(items[0].text).toEqual("hello");
    expect(items[1].text).toEqual("hello2");
  });

  it("undo edit action should update item", function() {
    $('#sandbox').wikimate({
      story: [{ "id": "3", "type": "paragraph", "text": "3" }, { "id": "1", "type": "paragraph", "text": "2" }]
    }).wikimate('journal', [
      {"id": "1", "type": "add", "item": { "id": "1", "type": "paragraph", "text": "1" }},
      {"id": "3", "type": "add", "item": { "id": "1", "type": "paragraph", "text": "3" }, after: '1'},
      {"id": "1", "type": "move", "order": ["3", "1"]},
      {"id": "1", "type": "edit", "item": { "id": "1", "type": "paragraph", "text": "2" }}
    ]);

    $('#sandbox').wikimate('undo');
    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(3);

    var items = $('#sandbox').wikimate('story');
    expect(items.length).toEqual(2);
    expect(items[1].text).toEqual("1");
  });

  it("undo move action should move item back to original position", function() {
    $('#sandbox').wikimate({}).wikimate('journal', []);

    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello2").focusout();
    $('#sandbox').wikimate('newItem');
    $('#sandbox textarea').text("hello3").focusout();

    var items = $('#sandbox .item');
    $(items[1]).insertAfter(items[2]);

    $(items[1]).story_item('moved', {
      order: [items[0].id, items[2].id, items[1].id]
    });

    // check move successfully
    expect($('#sandbox').wikimate('journal').length).toEqual(4);

    $('#sandbox').wikimate('undo');

    var actions = $('#sandbox').wikimate('journal');
    expect(actions.length).toEqual(3);
    expect(actions[0].type).toEqual('add');
    expect(actions[0].type).toEqual('add');
    expect(actions[0].type).toEqual('add');

    var orderedText = $.map($('#sandbox .item p'), function(item) {
      return $(item).text();
    });
    expect(orderedText).toEqual(['hello', 'hello2', 'hello3']);
  });
});
<|endoftext|>


<commit_before>describe('A Resource instance', function() {
  var Model, model;

  beforeEach(function() {
    Model = SC.Resource.define({
      schema: {
        id:       Number,
        name:     String
      },
    }).extend({
      url: '/people'
    });
  });

  describe('with no ID', function() {

    beforeEach(function() {
      model = Model.create({});
    });

    it('does not fetch when setting an attribute', function() {
      spyOn(model, 'fetch');
      model.set('name', 'Patricia');
      expect(model.fetch).not.toHaveBeenCalled();
    });

    it('allows setting a property to undefined', function() {
      model.set('name', 'Carlos');
      expect(model.get('name')).toEqual('Carlos');
      model.set('name', undefined);
      expect(model.get('name')).toBeUndefined();
    });

  });

});
<commit_msg>added failing spec for #10<commit_after>describe('A Resource instance', function() {
  var Model, model;

  beforeEach(function() {
    Model = SC.Resource.define({
      schema: {
        id:       Number,
        name:     String
      },
    }).extend({
      url: '/people'
    });
  });

  describe('with no ID', function() {

    beforeEach(function() {
      model = Model.create({});
    });

    it('does not fetch when setting an attribute', function() {
      spyOn(model, 'fetch');
      model.set('name', 'Patricia');
      expect(model.fetch).not.toHaveBeenCalled();
    });

    it('allows setting a property to undefined', function() {
      model.set('name', 'Carlos');
      expect(model.get('name')).toEqual('Carlos');
      model.set('name', undefined);
      expect(model.get('name')).toBeUndefined();
    });

  });

  it('allows setting of properties not in the schema during creation', function() {
    model = Model.create({ undefinedProperty: 'foo' });
    expect(model.get('undefinedProperty')).toEqual('foo');
  });

});
<|endoftext|>


<commit_before>/**
 * Poster v0.1.0
 * A React webapp to list upcoming movies and maintain a watchlist, powered by TMDb
 *
 * Author: Kushal Pandya <kushalspandya@gmail.com> (https://doublslash.com)
 * Date: 22 June, 2016
 * License: MIT
 *
 * Poster Reducer
 */

import { PosterAction } from "../actions/poster";

const initialState = {
    loadTopRatedCompleted: false,
    loadUpcomingCompleted: false,
    loadWatchlistCompleted: false,
    topRatedMovies: [],
    upcomingMovies: [],
    watchlistMovies: []
};

const poster = (state = initialState, action) => {
    switch (action.type)
    {
        case PosterAction.GET_TOP_RATED:
            {
                let newState = Object.assign({}, state);
                newState.topRatedMovies = action.movies;
                newState.loadTopRatedCompleted = true;

                return newState;
            }

        case PosterAction.GET_UPCOMING:
            {
                let newState = Object.assign({}, state);
                newState.upcomingMovies = action.movies;
                newState.loadUpcomingCompleted = true;

                return newState;
            }

        case PosterAction.GET_WATCHLIST:
            {
                let newState = Object.assign({}, state);
                newState.watchlistMovies = action.movies;
                newState.loadWatchlistCompleted = true;

                return newState;
            }

        case PosterAction.ADD_MOVIE_WATCHLIST:
            {
                let newState = Object.assign({}, state);
                newState.movie = action.movie;
                newState.loadWatchlistCompleted = false;

                return newState;
            }

        case PosterAction.REMOVE_MOVIE_WATCHLIST:
            {
                let newState = Object.assign({}, state);
                newState.watchlistMovies = newState.watchlistMovies.filter(function(movie) {
                    return movie.id !== action.movieId;
                });
                newState.loadTopRatedCompleted = false;
                newState.loadUpcomingCompleted = false;

                return newState;
            }

        default:
            return state;
    }
}

export default poster;
<commit_msg>Handle Search dispatcher state.<commit_after>/**
 * Poster v0.1.0
 * A React webapp to list upcoming movies and maintain a watchlist, powered by TMDb
 *
 * Author: Kushal Pandya <kushalspandya@gmail.com> (https://doublslash.com)
 * Date: 22 June, 2016
 * License: MIT
 *
 * Poster Reducer
 */

import { PosterAction } from "../actions/poster";

const initialState = {
    loadTopRatedCompleted: false,
    loadUpcomingCompleted: false,
    loadWatchlistCompleted: false,
    loadSearchResultsCompleted: false,
    topRatedMovies: [],
    upcomingMovies: [],
    watchlistMovies: [],
    searchResults: []
};

const poster = (state = initialState, action) => {
    switch (action.type)
    {
        case PosterAction.GET_TOP_RATED:
            {
                let newState = Object.assign({}, state);
                newState.topRatedMovies = action.movies;
                newState.loadTopRatedCompleted = true;

                return newState;
            }

        case PosterAction.GET_UPCOMING:
            {
                let newState = Object.assign({}, state);
                newState.upcomingMovies = action.movies;
                newState.loadUpcomingCompleted = true;

                return newState;
            }

        case PosterAction.GET_WATCHLIST:
            {
                let newState = Object.assign({}, state);
                newState.watchlistMovies = action.movies;
                newState.loadWatchlistCompleted = true;

                return newState;
            }

        case PosterAction.SEARCH:
            {
                let newState = Object.assign({}, state);
                newState.searchResults = [];
                newState.loadSearchResultsCompleted = false;

                return newState;
            }

        case PosterAction.SEARCH_COMPLETE:
            {
                let newState = Object.assign({}, state);
                newState.searchResults = action.movies;
                newState.loadSearchResultsCompleted = true;

                return newState;
            }

        case PosterAction.ADD_MOVIE_WATCHLIST:
            {
                let newState = Object.assign({}, state);
                newState.movie = action.movie;
                newState.loadWatchlistCompleted = false;

                return newState;
            }

        case PosterAction.REMOVE_MOVIE_WATCHLIST:
            {
                let newState = Object.assign({}, state);
                newState.watchlistMovies = newState.watchlistMovies.filter(function(movie) {
                    return movie.id !== action.movieId;
                });
                newState.loadTopRatedCompleted = false;
                newState.loadUpcomingCompleted = false;

                return newState;
            }

        default:
            return state;
    }
}

export default poster;
<|endoftext|>


<commit_before>$(function() {

    var opt =
	{
            chart: {
		renderTo: 'container'
            },
            credits: {
		enabled: false
            },
            legend: {
		enabled: true
            },
	    navigator: {
		enabled: true
	    },
	    plotOptions: {
		series: {
		    turboThreshold: 365 * 20 // 20 years
		}
	    },
	    rangeSelector: {
		selected: 2
	    },
            title: {
		text: 'Stock Chart'
            },
	    tooltip: {
		valueDecimals: 2
	    },
            yAxis: [{
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'OHLC'
                },
                height: '60%',
                offset: 0,
                lineWidth: 2
            }, {
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'Volume'
                },
                top: '65%',
                height: '35%',
                offset: 0,
                lineWidth: 2
            }, {
                labels: {
                    align: 'left',
                    x: 3
                },
                title: {
                    text: 'Reference'
                },
                height: '60%',
                offset: 25,
                lineWidth: 2
            }, {
                labels: {
                    align: 'left',
                    x: 3
                },
                title: {
                    text: 'Reference'
                },
                top: '65%',
                height: '35%',
                offset: 25,
                lineWidth: 2
            }]
	};

    var chart = new Highcharts.StockChart(opt);
    var api = new RestsigApi('http://localhost/api');

    var drawChart = function (stock_code) {
	var self = $(this);
	api.Stocks.byCode(stock_code).get()
	    .done(function (data) {
		chart.addSeries({
		    type: 'candlestick',
		    color: self.data('ohlc-color'),
		    upColor: self.data('ohlc-upcolor'),
		    lineColor: self.data('ohlc-linecolor'),
		    name: data.brand.name,
		    data: data.prices.map(
			function(s) {
			    return [s.date, s.open, s.high, s.low, s.close];
			}),
		    yAxis: self.data('ohlc-yaxis')
		});
		chart.addSeries({
		    type: 'column',
		    color: self.data('volume-color'),
		    name: 'Volume',
		    data: data.prices.map(
			function(s) {
			    return [s.date, s.volume];
			}),
		    yAxis: self.data('volume-yaxis')
		});
		setTimeout(function() {
		    $('input.highcharts-range-selector', '#' + opt.chart.renderTo)
			.datepicker({
			    format: 'yyyy-mm-dd',
			    todayBtn: 'linked',
			    orientation: 'auto left',
			    autoclose: true,
			    todayHighlight: true
			});
		}, 0);
	    });
    };
    $('.stock-code').typeahead(
	{
	    hint: true,
	    highlight: true,
	    minLength: 2
	},
	{
	    displayKey: 'value',
	    source: function (query, process) {
		api.Brands.byLike('%' + query + '%').get()
		    .done(function (data) {
			process(data.map(function (b) {
			    return {label: b.brandName + '(' + b.brandCode + ')', value: b.brandCode};
			}));
		    });
	    },
	    templates: {
		suggestion: function (b) {
		    return b.label;
		}
	    }
	});
    $('.add-stock').on({
	'typeahead:selected' : function (obj, datum, name) {
	    drawChart.bind(this)(datum.value);
	},
	'typeahead:autocompleted' : function (obj, datum, name) {
	    drawChart.bind(this)(datum.value);
	}
    });

    $('.enable-next').blur(function () {
	var next = $(this).data('enable-next-selector');
	$(next).removeAttr('disabled');
    });

    $('#add-sma-term').click(function() {
        var cd = $('#sma-code').val(),
	    keys = {1: 'n', 2: 's', 3: 'm', 4: 'l', 5: 'xl'},
	    terms = {},
	    colors = {},
	    opts = {type: 'json'};

	$.each(keys, function (k, v) {
	    terms[v] = Number($('#sma-term-' + v).val());
	    colors[v] = $('#sma-color-' + v).val();
	    if (terms[v] > 0) {
		opts[v] = terms[v];
	    }
	});

        api.Stocks.byCode(cd).Indicator.sma().get(null, null, opts)
	    .done(
		function(data) {
		    for(var i=1; i<=5; i++) {
			if (data['tl'+i] != null) {
			    chart.addSeries({
				type: 'line',
				name: data['tl'+i].label,
				data: data['tl'+i].ticks.map(function(s){return [s.k, s.v]}),
				color: colors[keys[i]],
				yAxis: 0
			    }, false, true);
			}
		    }
		    chart.redraw();
		}
	    );
    });

    $('#rm-last-sma-term').click(function() {
	var lastIdx = chart.series.length;
	chart.series[lastIdx-1].remove();
    });

    $('.color').colorpicker();

});
<commit_msg>Enable autoselect<commit_after>$(function() {

    var opt =
	{
            chart: {
		renderTo: 'container'
            },
            credits: {
		enabled: false
            },
            legend: {
		enabled: true
            },
	    navigator: {
		enabled: true
	    },
	    plotOptions: {
		series: {
		    turboThreshold: 365 * 20 // 20 years
		}
	    },
	    rangeSelector: {
		selected: 2
	    },
            title: {
		text: 'Stock Chart'
            },
	    tooltip: {
		valueDecimals: 2
	    },
            yAxis: [{
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'OHLC'
                },
                height: '60%',
                offset: 0,
                lineWidth: 2
            }, {
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'Volume'
                },
                top: '65%',
                height: '35%',
                offset: 0,
                lineWidth: 2
            }, {
                labels: {
                    align: 'left',
                    x: 3
                },
                title: {
                    text: 'Reference'
                },
                height: '60%',
                offset: 25,
                lineWidth: 2
            }, {
                labels: {
                    align: 'left',
                    x: 3
                },
                title: {
                    text: 'Reference'
                },
                top: '65%',
                height: '35%',
                offset: 25,
                lineWidth: 2
            }]
	};

    var chart = new Highcharts.StockChart(opt);
    var api = new RestsigApi('http://localhost/api');

    var drawChart = function (stock_code) {
	var self = $(this);
	api.Stocks.byCode(stock_code).get()
	    .done(function (data) {
		chart.addSeries({
		    type: 'candlestick',
		    color: self.data('ohlc-color'),
		    upColor: self.data('ohlc-upcolor'),
		    lineColor: self.data('ohlc-linecolor'),
		    name: data.brand.name,
		    data: data.prices.map(
			function(s) {
			    return [s.date, s.open, s.high, s.low, s.close];
			}),
		    yAxis: self.data('ohlc-yaxis')
		});
		chart.addSeries({
		    type: 'column',
		    color: self.data('volume-color'),
		    name: 'Volume',
		    data: data.prices.map(
			function(s) {
			    return [s.date, s.volume];
			}),
		    yAxis: self.data('volume-yaxis')
		});
		setTimeout(function() {
		    $('input.highcharts-range-selector', '#' + opt.chart.renderTo)
			.datepicker({
			    format: 'yyyy-mm-dd',
			    todayBtn: 'linked',
			    orientation: 'auto left',
			    autoclose: true,
			    todayHighlight: true
			});
		}, 0);
	    });
    };
    $('.stock-code').typeahead(
	{
	    autoselect: true,
	    hint: true,
	    highlight: true,
	    minLength: 2
	},
	{
	    displayKey: 'value',
	    source: function (query, process) {
		api.Brands.byLike('%' + query + '%').get()
		    .done(function (data) {
			process(data.map(function (b) {
			    return {label: b.brandName + '(' + b.brandCode + ')', value: b.brandCode};
			}));
		    });
	    },
	    templates: {
		suggestion: function (b) {
		    return b.label;
		}
	    }
	});
    $('.add-stock').on({
	'typeahead:selected' : function (obj, datum, name) {
	    drawChart.bind(this)(datum.value);
	},
    });

    $('.enable-next').blur(function () {
	var next = $(this).data('enable-next-selector');
	$(next).removeAttr('disabled');
    });

    $('#add-sma-term').click(function() {
        var cd = $('#sma-code').val(),
	    keys = {1: 'n', 2: 's', 3: 'm', 4: 'l', 5: 'xl'},
	    terms = {},
	    colors = {},
	    opts = {type: 'json'};

	$.each(keys, function (k, v) {
	    terms[v] = Number($('#sma-term-' + v).val());
	    colors[v] = $('#sma-color-' + v).val();
	    if (terms[v] > 0) {
		opts[v] = terms[v];
	    }
	});

        api.Stocks.byCode(cd).Indicator.sma().get(null, null, opts)
	    .done(
		function(data) {
		    for(var i=1; i<=5; i++) {
			if (data['tl'+i] != null) {
			    chart.addSeries({
				type: 'line',
				name: data['tl'+i].label,
				data: data['tl'+i].ticks.map(function(s){return [s.k, s.v]}),
				color: colors[keys[i]],
				yAxis: 0
			    }, false, true);
			}
		    }
		    chart.redraw();
		}
	    );
    });

    $('#rm-last-sma-term').click(function() {
	var lastIdx = chart.series.length;
	chart.series[lastIdx-1].remove();
    });

    $('.color').colorpicker();

});
<|endoftext|>


<commit_before>var mathjs = require('mathjs');
var RC = require('regex-chain');

var bot = null;
var mathParser = mathjs.parser();

function MathScopeEval(str) {
  try {
    return mathParser.eval(str);
  } catch(ex) {
    return null;
  }
}

var REEscape = function(s) {
      return s.replace(/[\-\/\\^\$\*\+\?\.\(\)\|\[\]{}]/g, '\\$&');
};

// custom symbols
mathjs.epsilon = 8.854187817*Math.pow(10,-12);
mathjs.k = 8.987551787368*Math.pow(10,9);

var mathKeysToGet = Object.getOwnPropertyNames(mathjs);
var mathItems = {};
for(var i=0;i<mathKeysToGet.length;i++) {
  mathItems[mathKeysToGet[i]] = mathjs[mathKeysToGet[i]];
}

//
// INPUT FULTERS
//
var mathKeys = Object.keys(mathItems);
var mathSymbols = ".,*+-/()%=";

var onlySymbols = new RC("^[\\s" + REEscape(mathSymbols) + "]*$");
var onlyNumbers = new RC(/^[\.\s\d]*$/);
var onlyKeys = new RC("^((" + mathKeys.join(")|(") + "))+$");
var onlyTime = new RC(/^(:?[0-9]+:?)+$/);
var onlyQuote = new RC(/^".+"$/);
var funnyFractions = new RC(/^(([0-9][0]?|11)\s*\/\s*(10|5|100))$/);
var plusN = new RC(/^\++\d+$/);

var ignoreRe = onlySymbols.or(onlyNumbers).or(funnyFractions).or(onlyKeys).or(plusN)
               .or(onlyQuote).or(onlyTime);

//
// OUTPUT FILTERS
//
var javascript = new RC("function|{|}|return|arguments|length"); // This is by no means "good"

module.exports.init = function(b) {
  bot = b;
}

module.exports.msg = function(text, from, reply, raw) {
  text = text.trim();

  if(ignoreRe.test(text)) {
    return;
  }

  var res = MathScopeEval(text);

  // If res is null or just echos our input, filter it
  if(res === null || res == text) {
    return;
  }

  res = res.toString();

  // If the response is javascript
  if(javascript.test(res)) {
    return;
  }

  // Truncate our responses (reckless-irc-exec)
  if(res.length < 400) {
    reply(res);
  }
  else {
    reply(res.substring(0,396) + " ...");
    bot.sayTo(from, 'All of your command output: ' + res);
  }
};

module.exports.command = "reset";

module.exports.run_reset = function(remainder, parts, reply) {
  // Create a new scope
  mathParser = mathjs.parser();
  reply("Parser reinitialized");
};

<commit_msg>Parroting check is now space insensitive.<commit_after>var mathjs = require('mathjs');
var RC = require('regex-chain');

var bot = null;
var mathParser = mathjs.parser();

function MathScopeEval(str) {
  try {
    return mathParser.eval(str);
  } catch(ex) {
    return null;
  }
}

var REEscape = function(s) {
      return s.replace(/[\-\/\\^\$\*\+\?\.\(\)\|\[\]{}]/g, '\\$&');
};

// custom symbols
mathjs.epsilon = 8.854187817*Math.pow(10,-12);
mathjs.k = 8.987551787368*Math.pow(10,9);

var mathKeysToGet = Object.getOwnPropertyNames(mathjs);
var mathItems = {};
for(var i=0;i<mathKeysToGet.length;i++) {
  mathItems[mathKeysToGet[i]] = mathjs[mathKeysToGet[i]];
}

//
// INPUT FULTERS
//
var mathKeys = Object.keys(mathItems);
var mathSymbols = ".,*+-/()%=";

var onlySymbols = new RC("^[\\s" + REEscape(mathSymbols) + "]*$");
var onlyNumbers = new RC(/^[\.\s\d]*$/);
var onlyKeys = new RC("^((" + mathKeys.join(")|(") + "))+$");
var onlyTime = new RC(/^(:?[0-9]+:?)+$/);
var onlyQuote = new RC(/^".+"$/);
var funnyFractions = new RC(/^(([0-9][0]?|11)\s*\/\s*(10|5|100))$/);
var plusN = new RC(/^\++\d+$/);

var ignoreRe = onlySymbols.or(onlyNumbers).or(funnyFractions).or(onlyKeys).or(plusN)
               .or(onlyQuote).or(onlyTime);

//
// OUTPUT FILTERS
//
var javascript = new RC("function|{|}|return|arguments|length"); // This is by no means "good"

module.exports.init = function(b) {
  bot = b;
}

module.exports.msg = function(text, from, reply, raw) {
  text = text.trim();

  if(ignoreRe.test(text)) {
    return;
  }

  var res = MathScopeEval(text);

  if(res == null) {
    return;
  }

  res = res.toString();

  var resclean = res.replace(/\s/g, '');
  var textclean = text.replace(/\s/g, '');

  // If res parrots our input, filter it
  if( res == text || resclean == text || res == textclean
      || resclean == textclean ) {
    return;
  }

  // If the response is javascript
  if(javascript.test(res)) {
    return;
  }

  // Truncate our responses (reckless-irc-exec)
  if(res.length < 400) {
    reply(res);
  }
  else {
    reply(res.substring(0,396) + " ...");
    bot.sayTo(from, 'All of your command output: ' + res);
  }
};

module.exports.command = "reset";

module.exports.run_reset = function(remainder, parts, reply) {
  // Create a new scope
  mathParser = mathjs.parser();
  reply("Parser reinitialized");
};

<|endoftext|>


<commit_before>/* globals describe, it, expect, expectObservable, hot */
var Rx = require('../../dist/cjs/Rx');
var Observable = Rx.Observable;

describe('Observable.prototype.skipUntil()', function () {
  it('should skip values until another observable notifies', function () {
    var e1 =     hot('--a--b--c--d--e--|');
    var skip =   hot('-------------x--|');
    var expected =  ('--------------e--|');

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip value and raises error until another observable raises error', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('-------------#');
    var expected = '-------------#';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element when another observable does not emit and completes early', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('------------|');
    var expected = '-----------------|';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element when another observable is empty', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = Observable.empty();
    var expected = '-----------------|';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not complete if source observable does not complete', function () {
    var e1 =   hot('-');
    var skip = hot('-------------x--|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not complete if source observable never completes', function () {
    var e1 = Observable.never();
    var skip = hot('-------------x--|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should raise error if source does not completes when another observable raises error', function () {
    var e1 =   hot('-');
    var skip = hot('-------------#');
    var expected = '-------------#';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should raise error if source never completes when another observable raises error', function () {
    var e1 = Observable.never();
    var skip = hot('-------------#');
    var expected = '-------------#';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element and does not complete when another observable never completes', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = Observable.never();
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element and does not complete when another observable does not completes', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('-');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element and does not complete when another observable completes after source', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('------------------------|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not completes if source does not completes when another observable does not emit', function () {
    var e1 =   hot('-');
    var skip = hot('--------------|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not completes if source and another observable both does not complete', function () {
    var e1 =   hot('-');
    var skip = hot('-');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element when another observable unsubscribed early before emit', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('-------------x--|');
    var expected = '-';

    e1.subscribe(function () {
      skip.unsubscribe();
    });

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });
});<commit_msg>test(skipUntil): add missing marble tests for skipUntil operator<commit_after>/* globals describe, it, expect, expectObservable, hot */
var Rx = require('../../dist/cjs/Rx');
var Observable = Rx.Observable;

describe('Observable.prototype.skipUntil()', function () {
  it('should skip values until another observable notifies', function () {
    var e1 =     hot('--a--b--c--d--e--|');
    var skip =   hot('-------------x--|');
    var expected =  ('--------------e--|');

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should emit element only after another observable emits', function () {
    var e1 =     hot('--a--b--c--d--e--|');
    var skip =   hot('-----------x----|');
    var expected =  ('--------------e--|');

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip value and raises error until another observable raises error', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('-------------#');
    var expected = '-------------#';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element when another observable does not emit and completes early', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('------------|');
    var expected = '-----------------|';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element when another observable is empty', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = Observable.empty();
    var expected = '-----------------|';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not complete if source observable does not complete', function () {
    var e1 =   hot('-');
    var skip = hot('-------------x--|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not complete if source observable never completes', function () {
    var e1 = Observable.never();
    var skip = hot('-------------x--|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should raise error if source does not completes when another observable raises error', function () {
    var e1 =   hot('-');
    var skip = hot('-------------#');
    var expected = '-------------#';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should raise error if source never completes when another observable raises error', function () {
    var e1 = Observable.never();
    var skip = hot('-------------#');
    var expected = '-------------#';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element and does not complete when another observable never completes', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = Observable.never();
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element and does not complete when another observable does not completes', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('-');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element and does not complete when another observable completes after source', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('------------------------|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not completes if source does not completes when another observable does not emit', function () {
    var e1 =   hot('-');
    var skip = hot('--------------|');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should not completes if source and another observable both does not complete', function () {
    var e1 =   hot('-');
    var skip = hot('-');
    var expected = '-';

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });

  it('should skip all element when another observable unsubscribed early before emit', function () {
    var e1 =   hot('--a--b--c--d--e--|');
    var skip = hot('-------------x--|');
    var expected = '-';

    e1.subscribe(function () {
      skip.unsubscribe();
    });

    expectObservable(e1.skipUntil(skip)).toBe(expected);
  });
});<|endoftext|>


<commit_before>// Podcast Atom/RSS parser. Downloads and extract useful info from a podcast
// feed and returns the data as easy-to-consume (and minimally changed)
// JavaScript objects.
// TODO: Make this less podcast-focused; it would be a useful RSS library
// in general.
(function() {
    'use strict';

    // Download a podcast feed from the URL specified. Execute a callback
    // (the second argument) whenever the data loads.
    function getFromGoogle(url, callback) {
        return new Promise(function(resolve, reject) {
            $.ajax({
                url: 'http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=?&q=' + encodeURIComponent(url) + '&num=' + 15 + '&output=json_xml',
                dataType: 'json',
                success: function(response) {
                    var xml = new DOMParser();
                    var xmlString = response.responseData.xmlString;
                    var xmlDoc = xml.parseFromString(xmlString, 'text/xml');

                    if (callback) {
                        callback(xmlDoc);
                    }
                    resolve(xmlDoc);
                },
                error: function() {
                    reject();
                }
            });
        });
    }

    HighFidelity.RSS = window.RSS = {
        get: getFromGoogle
    };
})();
<commit_msg>Fix HTTPS RSS bug<commit_after>// Podcast Atom/RSS parser. Downloads and extract useful info from a podcast
// feed and returns the data as easy-to-consume (and minimally changed)
// JavaScript objects.
// TODO: Make this less podcast-focused; it would be a useful RSS library
// in general.
(function() {
    'use strict';

    // Download a podcast feed from the URL specified. Execute a callback
    // (the second argument) whenever the data loads.
    function getFromGoogle(url, callback) {
        return new Promise(function(resolve, reject) {
            $.ajax({
                url: document.location.protocol +
                     '//ajax.googleapis.com/ajax/' +
                     'services/feed/load?v=1.0&callback=?&q=' +
                     encodeURIComponent(url) +
                     '&num=' + 15 + '&output=json_xml',
                dataType: 'json',
                success: function(response) {
                    var xml = new DOMParser();
                    var xmlString = response.responseData.xmlString;
                    var xmlDoc = xml.parseFromString(xmlString, 'text/xml');

                    if (callback) {
                        callback(xmlDoc);
                    }
                    resolve(xmlDoc);
                },
                error: function() {
                    reject();
                }
            });
        });
    }

    HighFidelity.RSS = window.RSS = {
        get: getFromGoogle
    };
})();
<|endoftext|>


<commit_before>(function() {
    var contract_name = document.getElementById('contract_name'),
        contract_address = document.getElementById('contract_address'),
        contract_abi = document.getElementById('contract_abi'),
        createBtn = document.getElementById('create'),
        clearBtn = document.getElementById('clear'),
        downloadBtn = document.getElementById('download');

    createBtn.addEventListener('click', function() {
        var contractName = contract_name.value;
        var contractAddress = contract_address.value;
        var contractAbi = JSON.parse(contract_abi.value);

        var abi = new ABI(contractName, contractAddress, contractAbi);

        var format = 'ts';

        var abiFile = abiToFile(abi, formats[format]);
        downloadBtn.href = abiFile.url;
        downloadBtn.download = contractName + '.' + format;

        setOutput(abiFile.text);
    }, false);

    clearBtn.addEventListener('click', function() {
        contract_name.value = '';
        contract_address.value = '';
        contract_abi.value = '';
        downloadBtn.href = "#";
        downloadBtn.download = '';

        setOutput('Output');
    }, false);

    function setOutput(output) {
        document.getElementById('output').innerHTML = output;
        window.prettyPrint();
    }
})();

var currentFile = null;

function abiToFile(abi, outputFormat) {
    var parser = new outputFormat.parser(abi);
    var text = parser.Run();

    var data = new Blob([text], { type: outputFormat.format });

    // If we are replacing a previously generated file we need to
    // manually revoke the object URL to avoid memory leaks.
    if (currentFile !== null) {
        window.URL.revokeObjectURL(currentFile);
    }

    currentFile = window.URL.createObjectURL(data);

    return new ABIFile(currentFile, text);
}

var ABI = function(name, address, abiArray) {
    this.ABIArray = JSON.parse(JSON.stringify(abiArray));
    this.contractName = name;
    this.contractAddress = address;
    this.contractConstructor = null;
    this.contractMethods = [];
    this.contractEvents = [];

    for (var i = 0; i < abiArray.length; i++) {
        var element = abiArray[i];
        if (element.type === 'constructor') {
            this.contractConstructor = element;
        } else if (element.type === 'function') {
            this.contractMethods.push(element);
        } else if (element.type === 'event') {
            this.contractEvents.push(element);
        } else {
            console.log('ABI element lost: ' + JSON.stringify(element));
        }
    }
};

var ABIParser = function(abi) {
    // a value from formats (ex: formats.ts)
    this.format = '';

    this.abi = abi;
    this.currentIndent = 0;
    this.output = '';
    this.runned = false;
};

ABIParser.prototype.getInputType = function(input) {
    var type = input.type;

    var isArray = type.indexOf("[]") >= 0;
    if (isArray)
        type = type.replace("[]", "");

    if (type in this.format.types)
        type = this.format.types[type];

    if (isArray)
        type += "[]";

    return type;
};

ABIParser.prototype.appendIndent = function() {
    for (var i = 0; i < this.currentIndent; i++) {
        this.output += "\t";
    }
};

ABIParser.prototype.appendNewline = function() {
    this.output += "\r\n";
    this.appendIndent();
};

ABIParser.prototype.openBrackets = function() {
    this.output += " {";
    this.currentIndent++;

    this.appendNewline();
};

ABIParser.prototype.closeBrackets = function() {
    if (this.output[this.output.length - 1] === '\t')
        this.output = this.output.substring(0, this.output.length - 1)

    this.output += "}";
    this.currentIndent--;

    this.appendNewline();
};

ABIParser.prototype.Run = function() {
    // subclasses need to override this method
    if (this.runned)
        return this.output;
    this.output = "Not implemented";
    this.runned = true;
    return this.output;
};

var ABIToTs = function(abi) {
    ABIParser.call(this, abi);
    this.format = formats.ts;
};

ABIToTs.prototype = Object.create(ABIParser.prototype);

ABIToTs.prototype.constructor = ABIParser;

ABIToTs.prototype.appendInput = function(input, inputIndex, appendComma) {
    var name = input.name;
    name = input.name ? input.name : input.type + '_' + inputIndex;

    this.output += name + ': ' + this.getInputType(input);
    appendComma && (this.output += ', ');
};

ABIToTs.prototype.appendOutputTypes = function(outputs) {
    var out = null;
    if (outputs.length === 1) {
        out = outputs[0];
        this.output += 'Observable< ';
        (out.name) && (this.output += out.name + ' : ');
        this.output += this.getInputType(out) + ' >';
    } else {
        this.output += 'Observable<{ ';
        for (i = 0; i < outputs.length; i++) {
            out = outputs[i];
            (out.name) && (this.output += out.name + ' : ');
            this.output += this.getInputType(out);
            i + 1 < outputs.length && (this.output += ', ');
        }
        this.output += ' }>';
    }
};

ABIToTs.prototype.appendDocs = function(method, title) {
    var i, input;
    this.output += '/**';
    this.appendNewline();
    this.output += ' * ' + method.name + ' ' + title;
    this.appendNewline();
    for (i = 0; i < method.inputs.length; i++) {
        input = method.inputs[i];
        this.output += ' * @param {' + this.getInputType(input) + '} ' + input.name;
        this.appendNewline();
    }
    if (method.outputs && method.outputs.length) {
        this.output += ' * @returns {';
        this.appendOutputTypes(method.outputs);
        this.output += '}';
        this.appendNewline();
    }
    this.output += ' */';
    this.appendNewline();
};

ABIToTs.prototype.appendConstructor = function(method) {
    method.name = this.abi.contractName;
    method.inputs.unshift({ 'name': 'blockchainService', 'type': 'BlockchainService' });

    this.appendDocs(method, 'constructor');
    this.output += 'constructor (';
    if (method.inputs && method.inputs.length) {
        for (i = 0; i < method.inputs.length; i++) {
            this.output += 'private ';
            this.appendInput(method.inputs[i], i, i + 1 < method.inputs.length);
        }
    }
    this.output += ')';
    this.openBrackets();
    this.closeBrackets();
    this.appendNewline();
};

ABIToTs.prototype.appendMethod = function(method) {
    var originalName = method.name;
    method.name = method.name.charAt(0).toLowerCase() + method.name.slice(1);

    this.appendDocs(method, 'function');
    this.output += method.name + ' (';
    if (method.inputs && method.inputs.length) {
        for (i = 0; i < method.inputs.length; i++) {
            this.appendInput(method.inputs[i], i, i + 1 < method.inputs.length);
        }
    }
    this.output += ')';
    if (method.outputs && method.outputs.length) {
        this.output += ' : ';
        this.appendOutputTypes(method.outputs, true);
    }
    this.openBrackets();
    this.output += 'return this.blockchainService.executeMethod(this, \'' + originalName + '\'';
    if (method.inputs && method.inputs.length) {
        this.output += ', ';
        if (method.inputs.length === 1) {
            this.output += method.inputs[0].name;
        } else {
            this.output += '{ ';
            for (i = 0; i < method.inputs.length; i++) {
                this.output += method.inputs[i].name;
                i + 1 < method.inputs.length && (this.output += ', ');
            }
            this.output += ' }';
        }
    }
    this.output += ');';
    this.appendNewline();
    this.closeBrackets();
    this.appendNewline();
};

ABIToTs.prototype.appendEvent = function(method) {
    var originalName = method.name;
    method.name = 'on' + method.name.charAt(0).toUpperCase() + method.name.slice(1);

    this.appendDocs(method, 'event');
    this.output += method.name + ' (';
    if (method.inputs && method.inputs.length) {
        for (i = 0; i < method.inputs.length; i++) {
            this.appendInput(method.inputs[i], i, i + 1 < method.inputs.length);
        }
    }
    this.output += ')';
    if (method.outputs && method.outputs.length) {
        this.output += ' : ';
        this.appendOutputTypes(method.outputs);
    }
    this.openBrackets();
    this.output += 'return this.blockchainService.watch(this, \'' + originalName + '\');';
    this.appendNewline();
    this.closeBrackets();
    this.appendNewline();
};

ABIToTs.prototype.Run = function() {
    if (this.runned)
        return this.output;

    var m;

    this.output = '';

    this.output += 'import { IContract } from \'./abstract/icontract\';';
    this.appendNewline();
    this.output += 'import { BlockchainService } from \'../services/blockchain\';';
    this.appendNewline();
    this.output += 'import { Observable } from \'rxjs/Observable\';';
    this.appendNewline();
    this.appendNewline();

    this.output += '@Injectable()';
    this.output += 'export class ' + this.abi.contractName + ' implements IContract';
    this.openBrackets();
    this.appendNewline();
    this.output += 'IBArray = ' + JSON.stringify(this.abi.ABIArray) + ';';
    this.appendNewline();
    this.output += 'Address = ' + this.abi.contractAddress + ';';
    this.appendNewline();
    this.appendNewline();

    if (this.abi.contractConstructor !== null) {
        this.appendConstructor(this.abi.contractConstructor);
    } else {
        this.appendConstructor({ 'name': '', 'inputs': [] });
    }

    for (m = 0; m < this.abi.contractMethods.length; m++) {
        this.appendMethod(this.abi.contractMethods[m]);
    }

    for (m = 0; m < this.abi.contractEvents.length; m++) {
        this.appendEvent(this.abi.contractEvents[m]);
    }

    this.closeBrackets();

    this.runned = true;
    return this.output;
};

var ABIFile = function(url, text) {
    this.url = url;
    this.text = text;
};

var defaultObjectTypes = {
    'bool': '',
    'address': '',
    'string': '',
    'int': '',
    'uint': ''
};
for (var i = 8; i <= 256; i += 8) {
    defaultObjectTypes['int' + i] = '';
    defaultObjectTypes['uint' + i] = '';
}

var formats = {
    'ts': { 'format': 'text/typescript', 'parser': ABIToTs, 'types': Object.create(defaultObjectTypes) }
};
formats.ts.types = {
    'bool': 'boolean',
    'address': 'string',
    'string': 'string',
    'int': 'number',
    'uint': 'number'
};
for (var i = 8; i <= 256; i += 8) {
    formats.ts.types['int' + i] = 'number';
    formats.ts.types['uint' + i] = 'number';
}<commit_msg>"executeMethod" with no inputs<commit_after>(function() {
    var contract_name = document.getElementById('contract_name'),
        contract_address = document.getElementById('contract_address'),
        contract_abi = document.getElementById('contract_abi'),
        createBtn = document.getElementById('create'),
        clearBtn = document.getElementById('clear'),
        downloadBtn = document.getElementById('download');

    createBtn.addEventListener('click', function() {
        var contractName = contract_name.value;
        var contractAddress = contract_address.value;
        var contractAbi = JSON.parse(contract_abi.value);

        var abi = new ABI(contractName, contractAddress, contractAbi);

        var format = 'ts';

        var abiFile = abiToFile(abi, formats[format]);
        downloadBtn.href = abiFile.url;
        downloadBtn.download = contractName + '.' + format;

        setOutput(abiFile.text);
    }, false);

    clearBtn.addEventListener('click', function() {
        contract_name.value = '';
        contract_address.value = '';
        contract_abi.value = '';
        downloadBtn.href = "#";
        downloadBtn.download = '';

        setOutput('Output');
    }, false);

    function setOutput(output) {
        document.getElementById('output').innerHTML = output;
        window.prettyPrint();
    }
})();

var currentFile = null;

function abiToFile(abi, outputFormat) {
    var parser = new outputFormat.parser(abi);
    var text = parser.Run();

    var data = new Blob([text], { type: outputFormat.format });

    // If we are replacing a previously generated file we need to
    // manually revoke the object URL to avoid memory leaks.
    if (currentFile !== null) {
        window.URL.revokeObjectURL(currentFile);
    }

    currentFile = window.URL.createObjectURL(data);

    return new ABIFile(currentFile, text);
}

var ABI = function(name, address, abiArray) {
    this.ABIArray = JSON.parse(JSON.stringify(abiArray));
    this.contractName = name;
    this.contractAddress = address;
    this.contractConstructor = null;
    this.contractMethods = [];
    this.contractEvents = [];

    for (var i = 0; i < abiArray.length; i++) {
        var element = abiArray[i];
        if (element.type === 'constructor') {
            this.contractConstructor = element;
        } else if (element.type === 'function') {
            this.contractMethods.push(element);
        } else if (element.type === 'event') {
            this.contractEvents.push(element);
        } else {
            console.log('ABI element lost: ' + JSON.stringify(element));
        }
    }
};

var ABIParser = function(abi) {
    // a value from formats (ex: formats.ts)
    this.format = '';

    this.abi = abi;
    this.currentIndent = 0;
    this.output = '';
    this.runned = false;
};

ABIParser.prototype.getInputType = function(input) {
    var type = input.type;

    var isArray = type.indexOf("[]") >= 0;
    if (isArray)
        type = type.replace("[]", "");

    if (type in this.format.types)
        type = this.format.types[type];

    if (isArray)
        type += "[]";

    return type;
};

ABIParser.prototype.appendIndent = function() {
    for (var i = 0; i < this.currentIndent; i++) {
        this.output += "\t";
    }
};

ABIParser.prototype.appendNewline = function() {
    this.output += "\r\n";
    this.appendIndent();
};

ABIParser.prototype.openBrackets = function() {
    this.output += " {";
    this.currentIndent++;

    this.appendNewline();
};

ABIParser.prototype.closeBrackets = function() {
    if (this.output[this.output.length - 1] === '\t')
        this.output = this.output.substring(0, this.output.length - 1)

    this.output += "}";
    this.currentIndent--;

    this.appendNewline();
};

ABIParser.prototype.Run = function() {
    // subclasses need to override this method
    if (this.runned)
        return this.output;
    this.output = "Not implemented";
    this.runned = true;
    return this.output;
};

var ABIToTs = function(abi) {
    ABIParser.call(this, abi);
    this.format = formats.ts;
};

ABIToTs.prototype = Object.create(ABIParser.prototype);

ABIToTs.prototype.constructor = ABIParser;

ABIToTs.prototype.appendInput = function(input, inputIndex, appendComma) {
    var name = input.name;
    name = input.name ? input.name : input.type + '_' + inputIndex;

    this.output += name + ': ' + this.getInputType(input);
    appendComma && (this.output += ', ');
};

ABIToTs.prototype.appendOutputTypes = function(outputs) {
    var out = null;
    if (outputs.length === 1) {
        out = outputs[0];
        this.output += 'Observable< ';
        (out.name) && (this.output += out.name + ' : ');
        this.output += this.getInputType(out) + ' >';
    } else {
        this.output += 'Observable<{ ';
        for (i = 0; i < outputs.length; i++) {
            out = outputs[i];
            (out.name) && (this.output += out.name + ' : ');
            this.output += this.getInputType(out);
            i + 1 < outputs.length && (this.output += ', ');
        }
        this.output += ' }>';
    }
};

ABIToTs.prototype.appendDocs = function(method, title) {
    var i, input;
    this.output += '/**';
    this.appendNewline();
    this.output += ' * ' + method.name + ' ' + title;
    this.appendNewline();
    for (i = 0; i < method.inputs.length; i++) {
        input = method.inputs[i];
        this.output += ' * @param {' + this.getInputType(input) + '} ' + input.name;
        this.appendNewline();
    }
    if (method.outputs && method.outputs.length) {
        this.output += ' * @returns {';
        this.appendOutputTypes(method.outputs);
        this.output += '}';
        this.appendNewline();
    }
    this.output += ' */';
    this.appendNewline();
};

ABIToTs.prototype.appendConstructor = function(method) {
    method.name = this.abi.contractName;
    method.inputs.unshift({ 'name': 'blockchainService', 'type': 'BlockchainService' });

    this.appendDocs(method, 'constructor');
    this.output += 'constructor (';
    if (method.inputs && method.inputs.length) {
        for (i = 0; i < method.inputs.length; i++) {
            this.output += 'private ';
            this.appendInput(method.inputs[i], i, i + 1 < method.inputs.length);
        }
    }
    this.output += ')';
    this.openBrackets();
    this.closeBrackets();
    this.appendNewline();
};

ABIToTs.prototype.appendMethod = function(method) {
    var originalName = method.name;
    method.name = method.name.charAt(0).toLowerCase() + method.name.slice(1);

    this.appendDocs(method, 'function');
    this.output += method.name + ' (';
    if (method.inputs && method.inputs.length) {
        for (i = 0; i < method.inputs.length; i++) {
            this.appendInput(method.inputs[i], i, i + 1 < method.inputs.length);
        }
    }
    this.output += ')';
    if (method.outputs && method.outputs.length) {
        this.output += ' : ';
        this.appendOutputTypes(method.outputs, true);
    }
    this.openBrackets();
    this.output += 'return this.blockchainService.executeMethod(this, \'' + originalName + '\', ';
    if (method.inputs && method.inputs.length) {
        if (method.inputs.length === 1) {
            this.output += method.inputs[0].name;
        } else {
            this.output += '{ ';
            for (i = 0; i < method.inputs.length; i++) {
                this.output += method.inputs[i].name ? method.inputs[i].name : method.inputs[i].type + '_' + i;
                i + 1 < method.inputs.length && (this.output += ', ');
            }
            this.output += ' }';
        }
    } else {
        this.output += 'null';
    }
    this.output += ');';
    this.appendNewline();
    this.closeBrackets();
    this.appendNewline();
};

ABIToTs.prototype.appendEvent = function(method) {
    var originalName = method.name;
    method.name = 'on' + method.name.charAt(0).toUpperCase() + method.name.slice(1);

    this.appendDocs(method, 'event');
    this.output += method.name + ' (';
    if (method.inputs && method.inputs.length) {
        for (i = 0; i < method.inputs.length; i++) {
            this.appendInput(method.inputs[i], i, i + 1 < method.inputs.length);
        }
    }
    this.output += ')';
    if (method.outputs && method.outputs.length) {
        this.output += ' : ';
        this.appendOutputTypes(method.outputs);
    }
    this.openBrackets();
    this.output += 'return this.blockchainService.watch(this, \'' + originalName + '\');';
    this.appendNewline();
    this.closeBrackets();
    this.appendNewline();
};

ABIToTs.prototype.Run = function() {
    if (this.runned)
        return this.output;

    var m;

    this.output = '';

    this.output += 'import { IContract } from \'./abstract/icontract\';';
    this.appendNewline();
    this.output += 'import { BlockchainService } from \'../services/blockchain\';';
    this.appendNewline();
    this.output += 'import { Observable } from \'rxjs/Observable\';';
    this.appendNewline();
    this.appendNewline();

    this.output += '@Injectable()';
    this.output += 'export class ' + this.abi.contractName + ' implements IContract';
    this.openBrackets();
    this.appendNewline();
    this.output += 'IBArray = ' + JSON.stringify(this.abi.ABIArray) + ';';
    this.appendNewline();
    this.output += 'Address = ' + this.abi.contractAddress + ';';
    this.appendNewline();
    this.appendNewline();

    if (this.abi.contractConstructor !== null) {
        this.appendConstructor(this.abi.contractConstructor);
    } else {
        this.appendConstructor({ 'name': '', 'inputs': [] });
    }

    for (m = 0; m < this.abi.contractMethods.length; m++) {
        this.appendMethod(this.abi.contractMethods[m]);
    }

    for (m = 0; m < this.abi.contractEvents.length; m++) {
        this.appendEvent(this.abi.contractEvents[m]);
    }

    this.closeBrackets();

    this.runned = true;
    return this.output;
};

var ABIFile = function(url, text) {
    this.url = url;
    this.text = text;
};

var defaultObjectTypes = {
    'bool': '',
    'address': '',
    'string': '',
    'int': '',
    'uint': ''
};
for (var i = 8; i <= 256; i += 8) {
    defaultObjectTypes['int' + i] = '';
    defaultObjectTypes['uint' + i] = '';
}

var formats = {
    'ts': { 'format': 'text/typescript', 'parser': ABIToTs, 'types': Object.create(defaultObjectTypes) }
};
formats.ts.types = {
    'bool': 'boolean',
    'address': 'string',
    'string': 'string',
    'int': 'number',
    'uint': 'number'
};
for (var i = 8; i <= 256; i += 8) {
    formats.ts.types['int' + i] = 'number';
    formats.ts.types['uint' + i] = 'number';
}<|endoftext|>


<commit_before>import warning from '../utils/warning'
import isUnitlessCSSProperty from 'unitless-css-property'

function addUnitIfNeeded(property, value, unit) {
  const valueType = typeof value
  if (valueType === 'number' || valueType === 'string' && value == parseFloat(value)) { // eslint-disable-line
    value += unit
  }

  return value
}

function addUnit(style, unit) {
  Object.keys(style).forEach(property => {
    if (!isUnitlessCSSProperty(property)) {

      const value = style[property]
      if (Array.isArray(value)) {
        style[property] = value.map(value => addUnitIfNeeded(property, value, unit))
      } else if (value instanceof Object) {
        style[property] = addUnit(value, unit)
      } else {
        style[property] = addUnitIfNeeded(property, value, unit)
      }
    }
  })

  return style
}

export default (unit = 'px') => {
  warning(unit.match(/ch|em|ex|rem|vh|vw|vmin|vmax|px|cm|mm|in|pc|pt|mozmm|%/) !== null, 'You are using an invalid unit `' + unit + '`. Consider using one of the following ch, em, ex, rem, vh, vw, vmin, vmax, px, cm, mm, in, pc, pt, mozmm or %.')

  return style => addUnit(style, unit)
}
<commit_msg>#96 added unit per property option<commit_after>import warning from '../utils/warning'
import isUnitlessCSSProperty from 'unitless-css-property'

function addUnitIfNeeded(property, value, unit) {
  const valueType = typeof value
  if (valueType === 'number' || valueType === 'string' && value == parseFloat(value)) { // eslint-disable-line
    value += unit
  }

  return value
}

function addUnit(style, unit, propertyMap) {
  Object.keys(style).forEach(property => {
    if (!isUnitlessCSSProperty(property)) {

      const value = style[property]
      const propertyUnit = propertyMap[property] || unit
      if (Array.isArray(value)) {
        style[property] = value.map(value => addUnitIfNeeded(property, propertyUnit, unit))
      } else if (value instanceof Object) {
        style[property] = addUnit(value, unit, propertyMap)
      } else {
        style[property] = addUnitIfNeeded(property, propertyUnit, unit)
      }
    }
  })

  return style
}

export default (unit = 'px', propertyMap = { }) => {
  warning(unit.match(/ch|em|ex|rem|vh|vw|vmin|vmax|px|cm|mm|in|pc|pt|mozmm|%/) !== null, 'You are using an invalid unit `' + unit + '`. Consider using one of the following ch, em, ex, rem, vh, vw, vmin, vmax, px, cm, mm, in, pc, pt, mozmm or %.')

  return style => addUnit(style, unit, propertyMap)
}
<|endoftext|>


<commit_before>$(document).ready(function () {
    "use strict";

$('.vertM').css("display", "block");
$('.vertM > ul').toggleClass('navbar-nav nav-pills nav-stacked');

$('.slidergall').css("visibility", "visible");

$('.logo').css({"display": "block", "margin": "0px"});
$('.logo > a').attr('class','navbar-brand');

$('.ipWidget-Map').css({"height": "100%", "width": "100%"});
$('.ipWidget-Map > div.ui-resizable').css({"height": "100%", "width": "100%"});

});<commit_msg>ImpressPages 4.5.0 update <commit_after>$(document).ready(function () {
    "use strict";

$('.vertM').css("display", "block");
$('.vertM > ul').toggleClass('navbar-nav nav-pills nav-stacked');

$('.slidergall').css("visibility", "visible");

$('.logo').css({"display": "block", "margin": "0px"});
$('.logo > a').attr('class','navbar-brand');

$('.ipWidget-Map').css({"height": "100%", "width": "100%"});
$('.ipWidget-Map > div.ui-resizable').css({"height": "100%", "width": "100%"});

if($('body').hasClass('ipHasAdminNavbar ipHasAdminPanel')) {
$('.modal-dialog').css('z-index', '1600');
}

});
<|endoftext|>


<commit_before>/*
 * Translation to JavaScript
 *
 * Requiring this module adds a gen() method to each of the AST classes.
 * Nothing is actually exported from this module.
 *
 * Generally, calling e.gen() where e is an expression node will return the
 * JavaScript translation as a string, while calling s.gen() where s is a
 * statement-level node will write its translation to standard output.
 *
 *   require('./backend/javascript-generator');
 *   program.gen();
 */

const Context = require("../context");
const Parser = require("../parser");

const Program = Parser.Program;

console.log(Program);
const indentPadding = 2;
let indentLevel = 0;

function emit(line) {
  console.log(`${' '.repeat(indentPadding * indentLevel)}${line}`);
}

function genStatementList(statements) {
  indentLevel += 1;
  statements.forEach(statement => statement.gen());
  indentLevel -= 1;
}

function makeOp(op) {
  return { not: '!', and: '&&', or: '||', '==': '===', '!=': '!==' }[op] || op;
}

// jsName(e) takes any PlainScript object with an id property, such as a
// Variable, Parameter, or FunctionDeclaration, and produces a JavaScript
// name by appending a unique indentifying suffix, such as '_1' or '_503'.
// It uses a cache so it can return the same exact string each time it is
// called with a particular entity.
const jsName = (() => {
  let lastId = 0;
  const map = new Map();
  return (v) => {
    if (!(map.has(v))) {
      map.set(v, ++lastId); // eslint-disable-line no-plusplus
    }
    return `${v.id}_${map.get(v)}`;
  };
})();

// This is a nice helper for variable declarations and assignment statements.
// The AST represents both of these with lists of sources and lists of targets,
// but when writing out JavaScript it seems silly to write `[x] = [y]` when
// `x = y` suffices.
function bracketIfNecessary(a) {
  if (a.length === 1) {
    return `${a}`;
  }
  return `[${a.join(', ')}]`;
}

function generateLibraryFunctions() {
  function generateLibraryStub(name, params, body) {
    const entity = Context.INITIAL.declarations[name];
    emit(`function ${jsName(entity)}(${params}) {${body}}`);
  }
  // This is sloppy. There should be a better way to do this.
  generateLibraryStub('print', '_', 'console.log(_);');
  generateLibraryStub('sqrt', '_', 'return Math.sqrt(_);');
}

/*
Object.assign(Argument.prototype, {
  gen() { return this.expression.gen(); },
});

Object.assign(AssignmentStatement.prototype, {
  gen() {
    const targets = this.targets.map(t => t.gen());
    const sources = this.sources.map(s => s.gen());
    emit(`${bracketIfNecessary(targets)} = ${bracketIfNecessary(sources)};`);
  },
});

Object.assign(BinaryExpression.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(BooleanLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(BreakStatement.prototype, {
  gen() { return 'break;'; },
});

Object.assign(CallStatement.prototype, {
  gen() { emit(`${this.call.gen()};`); },
});

Object.assign(Call.prototype, {
  gen() {
    const fun = this.callee.referent;
    const params = {};
    const args = Array(this.args.length).fill(undefined);
    fun.params.forEach((p, i) => { params[p.id] = i; });
    this.args.forEach((a, i) => { args[a.isPositionalArgument ? i : params[a.id]] = a; });
    return `${jsName(fun)}(${args.map(a => (a ? a.gen() : 'undefined')).join(', ')})`;
  },
});

Object.assign(FunctionDeclaration.prototype, {
  gen() { return this.function.gen(); },
});

Object.assign(FunctionObject.prototype, {
  gen() {
    emit(`function ${jsName(this)}(${this.params.map(p => p.gen()).join(', ')}) {`);
    genStatementList(this.body);
    emit('}');
  },
});

Object.assign(IdentifierExpression.prototype, {
  gen() { return this.referent.gen(); },
});

Object.assign(IfStatement.prototype, {
  gen() {
    this.cases.forEach((c, index) => {
      const prefix = index === 0 ? 'if' : '} else if';
      emit(`${prefix} (${c.test.gen()}) {`);
      genStatementList(c.body);
    });
    if (this.alternate) {
      emit('} else {');
      genStatementList(this.alternate);
    }
    emit('}');
  },
});

Object.assign(NumericLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(Parameter.prototype, {
  gen() {
    let translation = jsName(this);
    if (this.defaultExpression) {
      translation += ` = ${this.defaultExpression.gen()}`;
    }
    return translation;
  },
});
*/
Object.assign(Program.prototype, {
  gen() {
    generateLibraryFunctions();
    this.statements.forEach(statement => statement.gen());
  },
});
/*

Object.assign(ReturnStatement.prototype, {
  gen() {
    if (this.returnValue) {
      emit(`return ${this.returnValue.gen()};`);
    } else {
      emit('return;');
    }
  },
});

Object.assign(StringLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(SubscriptedExpression.prototype, {
  gen() {
    const base = this.variable.gen();
    const subscript = this.subscript.gen();
    return `${base}[${subscript}]`;
  },
});

Object.assign(UnaryExpression.prototype, {
  gen() { return `(${makeOp(this.op)} ${this.operand.gen()})`; },
});

Object.assign(VariableDeclaration.prototype, {
  gen() {
    const variables = this.variables.map(v => v.gen());
    const initializers = this.initializers.map(i => i.gen());
    emit(`let ${bracketIfNecessary(variables)} = ${bracketIfNecessary(initializers)};`);
  },
});

Object.assign(Variable.prototype, {
  gen() { return jsName(this); },
});

Object.assign(WhileStatement.prototype, {
  gen() {
    emit(`while (${this.test.gen()}) {`);
    genStatementList(this.body);
    emit('}');
  },
});
*/
<commit_msg>generator additions<commit_after>/*
 * Translation to JavaScript
 *
 * Requiring this module adds a gen() method to each of the AST classes.
 * Nothing is actually exported from this module.
 *
 * Generally, calling e.gen() where e is an expression node will return the
 * JavaScript translation as a string, while calling s.gen() where s is a
 * statement-level node will write its translation to standard output.
 *
 *   require('./backend/javascript-generator');
 *   program.gen();
 */

const Context = require("../context");
const Parser = require("../parser");

const Program = Parser.Program;
const Block = Parser.Block;
const Return = Parser.Return;
const Stmt = Parser.Stmt;

console.log(Program);
const indentPadding = 2;
let indentLevel = 0;

function emit(line) {
  console.log(`${' '.repeat(indentPadding * indentLevel)}${line}`);
}

function genStatementList(statements) {
  indentLevel += 1;
  statements.forEach(statement => statement.gen());
  indentLevel -= 1;
}

function makeOp(op) {
  return { not: '!', and: '&&', or: '||', '==': '===', '!=': '!==' }[op] || op;
}

// jsName(e) takes any PlainScript object with an id property, such as a
// Variable, Parameter, or FunctionDeclaration, and produces a JavaScript
// name by appending a unique indentifying suffix, such as '_1' or '_503'.
// It uses a cache so it can return the same exact string each time it is
// called with a particular entity.
const jsName = (() => {
  let lastId = 0;
  const map = new Map();
  return (v) => {
    if (!(map.has(v))) {
      map.set(v, ++lastId); // eslint-disable-line no-plusplus
    }
    return `${v.id}_${map.get(v)}`;
  };
})();

// This is a nice helper for variable declarations and assignment statements.
// The AST represents both of these with lists of sources and lists of targets,
// but when writing out JavaScript it seems silly to write `[x] = [y]` when
// `x = y` suffices.
function bracketIfNecessary(a) {
  if (a.length === 1) {
    return `${a}`;
  }
  return `[${a.join(', ')}]`;
}

function generateLibraryFunctions() {
  function generateLibraryStub(name, params, body) {
    const entity = Context.INITIAL.declarations[name];
    emit(`function ${jsName(entity)}(${params}) {${body}}`);
  }
  // This is sloppy. There should be a better way to do this.
  generateLibraryStub('print', '_', 'console.log(_);');
  generateLibraryStub('sqrt', '_', 'return Math.sqrt(_);');
}

/*
Object.assign(Argument.prototype, {
  gen() { return this.expression.gen(); },
});

Object.assign(AssignmentStatement.prototype, {
  gen() {
    const targets = this.targets.map(t => t.gen());
    const sources = this.sources.map(s => s.gen());
    emit(`${bracketIfNecessary(targets)} = ${bracketIfNecessary(sources)};`);
  },
});

Object.assign(BinaryExpression.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(BooleanLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(BreakStatement.prototype, {
  gen() { return 'break;'; },
});

Object.assign(CallStatement.prototype, {
  gen() { emit(`${this.call.gen()};`); },
});

Object.assign(Call.prototype, {
  gen() {
    const fun = this.callee.referent;
    const params = {};
    const args = Array(this.args.length).fill(undefined);
    fun.params.forEach((p, i) => { params[p.id] = i; });
    this.args.forEach((a, i) => { args[a.isPositionalArgument ? i : params[a.id]] = a; });
    return `${jsName(fun)}(${args.map(a => (a ? a.gen() : 'undefined')).join(', ')})`;
  },
});

Object.assign(FunctionDeclaration.prototype, {
  gen() { return this.function.gen(); },
});

Object.assign(FunctionObject.prototype, {
  gen() {
    emit(`function ${jsName(this)}(${this.params.map(p => p.gen()).join(', ')}) {`);
    genStatementList(this.body);
    emit('}');
  },
});

Object.assign(IdentifierExpression.prototype, {
  gen() { return this.referent.gen(); },
});

Object.assign(IfStatement.prototype, {
  gen() {
    this.cases.forEach((c, index) => {
      const prefix = index === 0 ? 'if' : '} else if';
      emit(`${prefix} (${c.test.gen()}) {`);
      genStatementList(c.body);
    });
    if (this.alternate) {
      emit('} else {');
      genStatementList(this.alternate);
    }
    emit('}');
  },
});

Object.assign(NumericLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(Parameter.prototype, {
  gen() {
    let translation = jsName(this);
    if (this.defaultExpression) {
      translation += ` = ${this.defaultExpression.gen()}`;
    }
    return translation;
  },
});
*/
Object.assign(Program.prototype, {
  gen() {
    generateLibraryFunctions();
    this.statements.forEach(statement => statement.gen());
  },
});
/*

*/
Object.assign(Return.prototype, {
  gen() {
    if (this.returnValue) {
      emit(`return ${this.returnValue.gen()};`);
    } else {
      emit('return;');
    }
  },
});
/*

Object.assign(StringLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(SubscriptedExpression.prototype, {
  gen() {
    const base = this.variable.gen();
    const subscript = this.subscript.gen();
    return `${base}[${subscript}]`;
  },
});

Object.assign(UnaryExpression.prototype, {
  gen() { return `(${makeOp(this.op)} ${this.operand.gen()})`; },
});

Object.assign(VariableDeclaration.prototype, {
  gen() {
    const variables = this.variables.map(v => v.gen());
    const initializers = this.initializers.map(i => i.gen());
    emit(`let ${bracketIfNecessary(variables)} = ${bracketIfNecessary(initializers)};`);
  },
});

Object.assign(Variable.prototype, {
  gen() { return jsName(this); },
});

Object.assign(WhileStatement.prototype, {
  gen() {
    emit(`while (${this.test.gen()}) {`);
    genStatementList(this.body);
    emit('}');
  },
});
*/
<|endoftext|>