<commit_before>"use strict";

var cycl = require('cycl'),
    processor = require('./processor.js'),
    presets = require('./presets.js'),
    rubix = require('./rubix.js'),
    Props = require('./props.js'),
    Values = require('./values.js'),
    Pointer = require('../input/pointer.js'),
    KEY = require('../opts/keys.js'),
    calc = require('../utils/calc.js'),
    utils = require('../utils/utils.js'),
    Data = require('../bits/data.js'),

    Action = function () {
        var self = this;

        // Create value manager
        this.values = new Values();

        // Create new property manager
        this.props = new Props();

        // Create data store
        this.data = new Data();

        // Register process wth cycl
        this.process = cycl.newProcess(function (framestamp, frameDuration) {
            processor.action(self, framestamp, frameDuration);
        });
    };

Action.prototype = {

    // [number]: Progress represented in a range of 0 - 1
    progress: 0,

    // [number]: Time elapsed in ms
    elapsed: 0,

    /*
        Play the provided actions as animations

        Syntax
            .play(playlist, [override])
                @param [string]: Playlist of presets
                @param [object]: (optional) Override object

            .play(params)
                @param [object]: Action properties

        @return [Action]
    */
    play: function (defs, override) {
        return this.start(KEY.RUBIX.TIME, presets.createBase(defs, override));
    },

    /*
        Track values to mouse, touch or custom Input

        Syntax
            .track(preset, [override], input)
                @param [string]: Name of preset
                @param [object]: (optional) Override object
                @param [event || Input]: Input or event to start tracking

            .track(params, input)
                @param [object]: Action properties
                @param [event || Input]: Input or event to start tracking

        @return [Action]
    */
    track: function (defs) {
        var hasAllArgs = (arguments[2] !== undefined),
            input = hasAllArgs ? arguments[2] : arguments[1],
            override = hasAllArgs ? arguments[1] : {},
            base = presets.createBase(defs, override);

        // If we have an input, check if it's a custom input.
        // Create a new pointer if it isn't
        if (input) {
            base.input = (input.current) ? input : new Pointer(input);
            base.inputOrigin = base.input.get();
        }

        return this.start(KEY.RUBIX.INPUT, base);
    },

    /*
        Run Action indefinitely

        Syntax
            .run(preset, [override])
                @param [string]: Name of preset
                @param [object]: (optional) Override object

            .run(params)
                @param [object]: Action properties

        @return [Action]
    */
    run: function (defs, override) {
        return this.start(KEY.RUBIX.RUN, presets.createBase(defs, override));
    },

    /*
        Start Action

        @param [string]: Name of processing type to sue
        @param [object]: Base Action properties to apply
        @return [Action]
    */
    start: function (processType, base) {
        this.resetProgress();
        this.change(processType, base);
        this.isActive(true);
        this.started = utils.currentTime() + this.props.get('delay');
        this.framestamp = this.started;
        this.firstFrame = true;

        this.process.start();

        return this;
    },

    /*
        Stop current Action process
    */
    stop: function () {
        this.isActive(false);
        this.process.stop();

        return this;
    },

    /*
        Pause current Action
    */
    pause: function () {
        this.stop();

        return this;
    },

    /*
        Resume a paused Action
    */
    resume: function () {
        this.started = utils.currentTime() - this.elapsed;
        this.framestamp = this.started;

        this.process.start();

        return this;
    },

    /*
        Reset Action progress and values
    */
    reset: function () {
        this.resetProgress();
        this.values.reset();

        return this;
    },

    /*
	    Reset Action progress
    */
    resetProgress: function () {
        this.progress = 0;
        this.elapsed = 0;
        this.started = utils.currentTime();
    },

    /*
	    Reverse Action progress and values
    */
    reverse: function () {
        this.progress = calc.difference(this.progress, 1);
        this.elapsed = calc.difference(this.elapsed, this.props.get('duration'));
        this.values.reverse();

        return this;
    },

    /*
        Check for next steps and perform, stop if not
    */
    next: function () {
        var nexts = [{
                key: 'loop',
                callback: this.reset
            }, {
                key: 'yoyo',
                callback: this.reverse
            }],
            possibles = nexts.length,
            hasNext = false;

        for (var i = 0; i < possibles; ++i) {
            if (this.checkNextStep(nexts[i].key, nexts[i].callback)) {
                hasNext = true;
                break;
            }
        }

        if (!hasNext && !this.playNext()) {
            this.stop();
        }
    },

    /*
        Check next step

        @param [string]: Name of step ('yoyo' or 'loop')
        @param [callback]: Function to run if we take this step
    */
    checkNextStep: function (key, callback) {
        var stepTaken = false,
            step = this.props.get(key),
            count = this.props.get(key + 'Count'),
            forever = (step === true);

        if (forever || utils.isNum(step)) {
            ++count;
            this.props.set(key + 'Count', count);

            if (forever || count <= step) {
                callback.call(this);
                stepTaken = true;
            }
        }

        return stepTaken;
    },

    /*
        Next in playlist
    */
    playNext: function () {
        var stepTaken = false,
            playlist = this.props.get('playlist'),
            playlistLength = playlist.length,
            playhead = this.props.get('playhead'),
            next = {};

        // Check we have a playlist
        if (playlistLength > 1) {
            ++playhead;

            if (playhead < playlistLength) {
                next = presets.getDefined(playlist[playhead]);
                next.playhead = playhead;
                this.change(KEY.RUBIX.TIME, next);
                this.reset();
                stepTaken = true;
            }
        }

        return stepTaken;
    },

    setValue: function (key, value) {
        this.values.set(key, value);
    },

    getValue: function (key) {
        return this.values.get(key);
    },

    setProp: function (key, value) {
        this.props.set(key, value);
    },

    getProp: function (key) {
        return this.props.get(key);
    },

    /*
        Is Action active?

        @param [boolean] (optional): If provided, will set action to active/inactive
        @return [boolean]: Active status
    */
    isActive: function (active) {
        if (active !== active) {
            this.active = active;
        }

        return this.active;
    },

    /*
        Change Action properties

        @param [string]: Type of processing rubix to use
        @param [object]: Base properties of new input
    */
    change: function (processType, base) {
	    var values = {};

        // Assign the processing rubix
        base.rubix = rubix[processType];

        this.props.apply(base);
        this.values.apply(base.values, this.props);
        values = this.values.getAll();

        this.origin = {};
        // Create origins
        for (var key in values) {
            if (values.hasOwnProperty(key)) {
                this.origin[key] = values[key].current;
            }
        }
    }

};

module.exports = Action;<commit_msg>adding active check around process<commit_after>"use strict";

var cycl = require('cycl'),
    processor = require('./processor.js'),
    presets = require('./presets.js'),
    rubix = require('./rubix.js'),
    Props = require('./props.js'),
    Values = require('./values.js'),
    Pointer = require('../input/pointer.js'),
    KEY = require('../opts/keys.js'),
    calc = require('../utils/calc.js'),
    utils = require('../utils/utils.js'),
    Data = require('../bits/data.js'),

    Action = function () {
        var self = this;

        // Create value manager
        this.values = new Values();

        // Create new property manager
        this.props = new Props();

        // Create data store
        this.data = new Data();

        // Register process wth cycl
        this.process = cycl.newProcess(function (framestamp, frameDuration) {
	        if (self.active) {
            	processor.action(self, framestamp, frameDuration);
	        }
        });
    };

Action.prototype = {

    // [number]: Progress represented in a range of 0 - 1
    progress: 0,

    // [number]: Time elapsed in ms
    elapsed: 0,

    /*
        Play the provided actions as animations

        Syntax
            .play(playlist, [override])
                @param [string]: Playlist of presets
                @param [object]: (optional) Override object

            .play(params)
                @param [object]: Action properties

        @return [Action]
    */
    play: function (defs, override) {
        return this.start(KEY.RUBIX.TIME, presets.createBase(defs, override));
    },

    /*
        Track values to mouse, touch or custom Input

        Syntax
            .track(preset, [override], input)
                @param [string]: Name of preset
                @param [object]: (optional) Override object
                @param [event || Input]: Input or event to start tracking

            .track(params, input)
                @param [object]: Action properties
                @param [event || Input]: Input or event to start tracking

        @return [Action]
    */
    track: function (defs) {
        var hasAllArgs = (arguments[2] !== undefined),
            input = hasAllArgs ? arguments[2] : arguments[1],
            override = hasAllArgs ? arguments[1] : {},
            base = presets.createBase(defs, override);

        // If we have an input, check if it's a custom input.
        // Create a new pointer if it isn't
        if (input) {
            base.input = (input.current) ? input : new Pointer(input);
            base.inputOrigin = base.input.get();
        }

        return this.start(KEY.RUBIX.INPUT, base);
    },

    /*
        Run Action indefinitely

        Syntax
            .run(preset, [override])
                @param [string]: Name of preset
                @param [object]: (optional) Override object

            .run(params)
                @param [object]: Action properties

        @return [Action]
    */
    run: function (defs, override) {
        return this.start(KEY.RUBIX.RUN, presets.createBase(defs, override));
    },

    /*
        Start Action

        @param [string]: Name of processing type to sue
        @param [object]: Base Action properties to apply
        @return [Action]
    */
    start: function (processType, base) {
        this.resetProgress();
        this.change(processType, base);
        this.isActive(true);
        this.started = utils.currentTime() + this.props.get('delay');
        this.framestamp = this.started;
        this.firstFrame = true;

        this.process.start();

        return this;
    },

    /*
        Stop current Action process
    */
    stop: function () {
        this.isActive(false);
        this.process.stop();

        return this;
    },

    /*
        Pause current Action
    */
    pause: function () {
        this.stop();

        return this;
    },

    /*
        Resume a paused Action
    */
    resume: function () {
        this.started = utils.currentTime() - this.elapsed;
        this.framestamp = this.started;

        this.process.start();

        return this;
    },

    /*
        Reset Action progress and values
    */
    reset: function () {
        this.resetProgress();
        this.values.reset();

        return this;
    },

    /*
	    Reset Action progress
    */
    resetProgress: function () {
        this.progress = 0;
        this.elapsed = 0;
        this.started = utils.currentTime();
    },

    /*
	    Reverse Action progress and values
    */
    reverse: function () {
        this.progress = calc.difference(this.progress, 1);
        this.elapsed = calc.difference(this.elapsed, this.props.get('duration'));
        this.values.reverse();

        return this;
    },

    /*
        Check for next steps and perform, stop if not
    */
    next: function () {
        var nexts = [{
                key: 'loop',
                callback: this.reset
            }, {
                key: 'yoyo',
                callback: this.reverse
            }],
            possibles = nexts.length,
            hasNext = false;

        for (var i = 0; i < possibles; ++i) {
            if (this.checkNextStep(nexts[i].key, nexts[i].callback)) {
                hasNext = true;
                break;
            }
        }

        if (!hasNext && !this.playNext()) {
            this.stop();
        }
    },

    /*
        Check next step

        @param [string]: Name of step ('yoyo' or 'loop')
        @param [callback]: Function to run if we take this step
    */
    checkNextStep: function (key, callback) {
        var stepTaken = false,
            step = this.props.get(key),
            count = this.props.get(key + 'Count'),
            forever = (step === true);

        if (forever || utils.isNum(step)) {
            ++count;
            this.props.set(key + 'Count', count);

            if (forever || count <= step) {
                callback.call(this);
                stepTaken = true;
            }
        }

        return stepTaken;
    },

    /*
        Next in playlist
    */
    playNext: function () {
        var stepTaken = false,
            playlist = this.props.get('playlist'),
            playlistLength = playlist.length,
            playhead = this.props.get('playhead'),
            next = {};

        // Check we have a playlist
        if (playlistLength > 1) {
            ++playhead;

            if (playhead < playlistLength) {
                next = presets.getDefined(playlist[playhead]);
                next.playhead = playhead;
                this.change(KEY.RUBIX.TIME, next);
                this.reset();
                stepTaken = true;
            }
        }

        return stepTaken;
    },

    setValue: function (key, value) {
        this.values.set(key, value);
    },

    getValue: function (key) {
        return this.values.get(key);
    },

    setProp: function (key, value) {
        this.props.set(key, value);
    },

    getProp: function (key) {
        return this.props.get(key);
    },

    /*
        Is Action active?

        @param [boolean] (optional): If provided, will set action to active/inactive
        @return [boolean]: Active status
    */
    isActive: function (active) {
        if (active !== undefined) {
            this.active = active;
        }

        return this.active;
    },

    /*
        Change Action properties

        @param [string]: Type of processing rubix to use
        @param [object]: Base properties of new input
    */
    change: function (processType, base) {
	    var values = {};

        // Assign the processing rubix
        base.rubix = rubix[processType];

        this.props.apply(base);
        this.values.apply(base.values, this.props);
        values = this.values.getAll();

        this.origin = {};
        // Create origins
        for (var key in values) {
            if (values.hasOwnProperty(key)) {
                this.origin[key] = values[key].current;
            }
        }
    }

};

module.exports = Action;<|endoftext|>


<commit_before>var Router = require('../../../../concrete/router'),
Request = require('./request');

exports.types = ['pull','pullMulti'];

exports.test = function(expr)
{

	return expr.type == 'pullMulti' || expr.type == 'pull' ? (expr.meta.multi ? 'pullMulti' : 'pull') : null;
}

exports.newRouter = function(type)
{
	var ops = { RequestClass: Request };

	if(type == 'pullMulti') ops.multi = true;

	return new Router(ops);
}<commit_msg>pullMulti wasn't being returned<commit_after>var Router = require('../../../../concrete/router'),
Request = require('./request');

exports.types = ['pull','pullMulti'];

exports.test = function(expr)
{
	if(expr.type == 'pullMulti') return 'pullMulti';
	return expr.type == 'pull' ? (expr.meta.multi ? 'pullMulti' : 'pull') : null;
}

exports.newRouter = function(type)
{
	var ops = { RequestClass: Request };

	if(type == 'pullMulti') ops.multi = true;

	return new Router(ops);
}<|endoftext|>


<commit_before>(function (i, s, o, g, r, a, m) {
    i['GoogleAnalyticsObject'] = r;
    i[r] = i[r] || function () {
        (i[r].q = i[r].q || []).push(arguments)
    }, i[r].l = 1 * new Date();
    a = s.createElement(o),
        m = s.getElementsByTagName(o)[0];
    a.async = 1;
    a.src = g;
    m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

ga('create', 'UA-2184335-14', 'azu.github.io');
ga('send', 'pageview');

(function () {
    var downloadButton = document.getElementById("download-pdf");
    downloadButton.onClick = function (event) {
        ga('send', 'event', 'Downloads', 'click', '/javascript-promise-book.pdf', {
            hitCallback: function () {
                location.href = downloadButton.href;
            }
        });
        event.preventDefault();
    }
})();
window.addEventListener("hashchange", function hashChange() {
    var hash = location.hash;
    var header = document.querySelector(hash);
    var title = header.textContent || header.innerText;
    ga('send', 'pageview', {
        'page': location.pathname + location.search + location.hash,
        'title': title
    });
}, false);
<commit_msg>chore(html): window.onload event<commit_after>(function (i, s, o, g, r, a, m) {
    i['GoogleAnalyticsObject'] = r;
    i[r] = i[r] || function () {
        (i[r].q = i[r].q || []).push(arguments)
    }, i[r].l = 1 * new Date();
    a = s.createElement(o),
        m = s.getElementsByTagName(o)[0];
    a.async = 1;
    a.src = g;
    m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

ga('create', 'UA-2184335-14', 'azu.github.io');
ga('send', 'pageview');

window.onload = function () {
    var downloadButton = document.getElementById("download-pdf");
    downloadButton.onClick = function (event) {
        ga('send', 'event', 'Downloads', 'click', '/javascript-promise-book.pdf', {
            hitCallback: function () {
                location.href = downloadButton.href;
            }
        });
        event.preventDefault();
    }
}
window.addEventListener("hashchange", function hashChange() {
    var hash = location.hash;
    var header = document.querySelector(hash);
    var title = header.textContent || header.innerText;
    ga('send', 'pageview', {
        'page': location.pathname + location.search + location.hash,
        'title': title
    });
}, false);
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import _ from 'lodash';
import Track from './Track'

export default class Playlist extends Component {
  static propTypes = {
    playlistActions: PropTypes.object.isRequired,
    trackSearchData: PropTypes.object.isRequired,
    trackSearchActions: PropTypes.object.isRequired,
    playlistMeta: PropTypes.object,
    playlist: PropTypes.object.isRequired
  }
  constructor(props){
    super(props);
    this.loadTracks = this.loadTracks.bind(this);
    this.onSelectionToggle = this.onSelectionToggle.bind(this);
  }
  onSelectionToggle(event){
    this.props.playlistActions.selectPlaylist(this.props.playlist.id, event.target.checked);
  }
  loadTracks(e){
    e.preventDefault();
    this.props.playlistActions.fetchPlaylistTracks(this.props.playlist.userId, this.props.playlist.id, this.props.playlistMeta.nextOffset);
  }
  render(){
    let tracks = this.props.playlist.tracks;
    let areAllSelected = (tracks.length != 0) ? !_.some(tracks, (track) => !track.isSelected) : false;
    let tracksTotalCount = this.props.playlistMeta.totalCount;
    let tracksFetchedCount = tracks.length;
    let pendingCount = tracksTotalCount - tracksFetchedCount;
    return (

<input type="checkbox" checked={areAllSelected} onChange={this.onSelectionToggle}/> {this.props.playlist.name}
          { pendingCount != 0 && Load more tracks ({pendingCount} left...)}

          {_.map(tracks, (track) => <Track
            key={track.id}
            track={track}
            playlistId={this.props.playlist.id}
            playlistActions={this.props.playlistActions}
            trackSearchData={this.props.trackSearchData}
            trackSearchActions={this.props.trackSearchActions}/>)}

    )
  }
}
<commit_msg>Add space<commit_after>import React, { Component, PropTypes } from 'react';
import _ from 'lodash';
import Track from './Track'

export default class Playlist extends Component {
  static propTypes = {
    playlistActions: PropTypes.object.isRequired,
    trackSearchData: PropTypes.object.isRequired,
    trackSearchActions: PropTypes.object.isRequired,
    playlistMeta: PropTypes.object,
    playlist: PropTypes.object.isRequired
  }
  constructor(props){
    super(props);
    this.loadTracks = this.loadTracks.bind(this);
    this.onSelectionToggle = this.onSelectionToggle.bind(this);
  }
  onSelectionToggle(event){
    this.props.playlistActions.selectPlaylist(this.props.playlist.id, event.target.checked);
  }
  loadTracks(e){
    e.preventDefault();
    this.props.playlistActions.fetchPlaylistTracks(this.props.playlist.userId, this.props.playlist.id, this.props.playlistMeta.nextOffset);
  }
  render(){
    let tracks = this.props.playlist.tracks;
    let areAllSelected = (tracks.length != 0) ? !_.some(tracks, (track) => !track.isSelected) : false;
    let tracksTotalCount = this.props.playlistMeta.totalCount;
    let tracksFetchedCount = tracks.length;
    let pendingCount = tracksTotalCount - tracksFetchedCount;
    return (

<input type="checkbox" checked={areAllSelected} onChange={this.onSelectionToggle}/> {this.props.playlist.name}
          {' '}{ pendingCount != 0 && Load more tracks ({pendingCount} left...)}

          {_.map(tracks, (track) => <Track
            key={track.id}
            track={track}
            playlistId={this.props.playlist.id}
            playlistActions={this.props.playlistActions}
            trackSearchData={this.props.trackSearchData}
            trackSearchActions={this.props.trackSearchActions}/>)}

    )
  }
}
<|endoftext|>


<commit_before>// This will be created inside the WklineCtrl scope, but it will be globally
// available for data injection into the controller scope
var wkInject,
    wkHandlers,
    merge_recursive

merge_recursive = function (obj1, obj2) {
	// http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
	for (var p in obj2) {
		try {
			// Property in destination object set update its value.
			if (obj2[p].constructor === Object) {
				obj1[p] = merge_recursive(obj1[p], obj2[p])
			} else {
				obj1[p] = obj2[p]
			}
		}
		catch (e) {
			// Property in destination object not set create it and set its value.
			obj1[p] = obj2[p]
		}
	}

	return obj1
}

wkHandlers = {
	widget: function ($scope, data) {
		if (! $scope.widget.hasOwnProperty(data._widget)) {
			$scope.widget[data._widget] = {}
		}
		$scope.widget[data._widget] = merge_recursive($scope.widget[data._widget], data)
	},
}

angular.module('Wkline', [])
	.controller('WklineCtrl', ['$scope', function ($scope) {
		$scope.widget = {}
		wkInject = function (payload) {
			if (! payload) {
				return false
			}

			$scope.$apply(function () {
				var handler

				if (payload.hasOwnProperty('widget')) {
					handler = 'widget'
					payload.data._widget = payload.widget
				}
				if (payload.hasOwnProperty('init')) {
					handler = 'init'
				}
				if (payload.hasOwnProperty('action')) {
					handler = 'action'
				}

				if (! handler || ! wkHandlers.hasOwnProperty(handler)) {
					return false
				}

				try {
					wkHandlers[handler]($scope, payload.data)
				}
				catch (e) {}
			})
		}
	}])
<commit_msg>Move datetime updater to wkline controller<commit_after>// This will be created inside the WklineCtrl scope, but it will be globally
// available for data injection into the controller scope
var wkInject,
    wkHandlers,
    merge_recursive,
    pad

merge_recursive = function (obj1, obj2) {
	// http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
	for (var p in obj2) {
		try {
			// Property in destination object set update its value.
			if (obj2[p].constructor === Object) {
				obj1[p] = merge_recursive(obj1[p], obj2[p])
			} else {
				obj1[p] = obj2[p]
			}
		}
		catch (e) {
			// Property in destination object not set create it and set its value.
			obj1[p] = obj2[p]
		}
	}

	return obj1
}

pad = function (n, width, z) {
	z = z || '0'
	n = n + ''
	return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n
}

wkHandlers = {
	widget: function ($scope, data) {
		if (! $scope.widget.hasOwnProperty(data._widget)) {
			$scope.widget[data._widget] = {}
		}
		$scope.widget[data._widget] = merge_recursive($scope.widget[data._widget], data)
	},
}

angular.module('Wkline', [])
	.controller('WklineCtrl', ['$scope', function ($scope) {
		$scope.widget = {};

		var updateDatetimeWidget = function () {
			var now = new Date()
			$scope.widget.datetime = {
				date: now.getFullYear() + '-' +
					pad(now.getMonth() + 1, 2) + '-' +
					pad(now.getDate(), 2),
				time: pad(now.getHours(), 2) + ':' +
					pad(now.getMinutes(), 2),
			}
		}

		// For some reason $scope.$apply breaks if run outside this setTimeout block
		setTimeout(function () { $scope.$apply(updateDatetimeWidget)}, 1)
		setInterval(function () { $scope.$apply(updateDatetimeWidget)}, 10000)

		wkInject = function (payload) {
			if (! payload) {
				return false
			}

			$scope.$apply(function () {
				var handler

				if (payload.hasOwnProperty('widget')) {
					handler = 'widget'
					payload.data._widget = payload.widget
				}
				if (payload.hasOwnProperty('init')) {
					handler = 'init'
				}
				if (payload.hasOwnProperty('action')) {
					handler = 'action'
				}

				if (! handler || ! wkHandlers.hasOwnProperty(handler)) {
					return false
				}

				try {
					wkHandlers[handler]($scope, payload.data)
				}
				catch (e) {}
			})
		}
	}])
<|endoftext|>


<commit_before>var lightPink = '#ffc1c9';

function randomGap(min,max)
{
    return Math.floor(Math.random()*(max-min+1)+min);
}

// Check the distance between passed Variable and this one.
function getDistance(position1, position2) {

    var distGap = position2.subtract(position1);

    var tempLength = distGap.length;
    var rtnLength = 0;

    if(tempLength < 110) {
        rtnLength = 110 - tempLength;
    } else {
        rtnLength = 0;
    }
    return rtnLength;
}

function createBubble(initialPos) {

    var bubblePos = initialPos;
    var bubbleRadius =  20;
    var bubbleSpeed = new paper.Point(1.2, 1.2).multiply(paper.Point.random());
    var bubbleDirection = new paper.Point(1,1);

    var bubbleShape = new paper.Path.Circle(bubblePos, bubbleRadius);
        bubbleShape.fillColor = lightPink;
        // bubbleShape.scaling = 1.0;
        bubbleShape.size = new paper.Size(10,10);

    var canvasSize = new paper.Size(paper.view.bounds.width, paper.view.bounds.height);

    function getBubbleShape() {
        return bubbleShape;
    }

    function getBubblePos() {
        return bubblePos;
    }

    function setBubbleRadius(scal) {
        bubbleShape.bounds.width = scal;
        bubbleShape.bounds.height = scal;
    }

    function moveBubble() {
        if( bubblePos.x >= canvasSize.width || bubblePos.x <= 0)
            { bubbleDirection.x = bubbleDirection.x * -1;}
        if( bubblePos.y >= canvasSize.height || bubblePos.y <= 0)
            { bubbleDirection.y = bubbleDirection.y * -1;}

        bubblePos = bubblePos.add(bubbleSpeed.multiply(bubbleDirection));
        bubbleShape.position = bubblePos;
    }

    function removeBubble(){
        bubbleShape.remove();
    }

    function setCanvasBounds(tempCanSize){
        canvasSize = tempCanSize;
    }

    function resizeCanvas(tempCanSize){
        setCanvasBounds(tempCanSize);

        if(bubblePos.x > tempCanSize.width+2){bubblePos.x = tempCanSize.width-2;}
        if(bubblePos.y > tempCanSize.height+2){bubblePos.y = tempCanSize.height-2;}

        if(bubblePos.x < -2){bubblePos.x = 2;}
        if(bubblePos.y < -2){bubblePos.y = 2;}
    }

    var bubble = {
      getBubbleShape: getBubbleShape,
      setBubbleRadius: setBubbleRadius,
      getBubblePos: getBubblePos,
      moveBubble: moveBubble,
      removeBubble: removeBubble,
      setCanvasBounds: setCanvasBounds,
      resizeCanvas: resizeCanvas
    }

    return bubble;
}

function makeBubbles(amount, array, tempCanSize){

    var bubbleTotal = amount;

    for(var i=0; i < bubbleTotal; i ++) {
        var tempPos = new paper.Point(tempCanSize.width, tempCanSize.height).multiply(paper.Point.random());
        var tempBubble = createBubble(tempPos);
        tempBubble.setCanvasBounds(tempCanSize);
        array.push(tempBubble);
    }

}

function deleteAllBubbles(){
    for(var i=0; i <= bubbles.length-1; i ++) {
       var bubble1 = bubbles[i];
       bubble1.removeBubble();
    }
    bubbles = [];
}

paper.install(window);

    //instantiate bubbles
    var bubbles = [];

    // Only executed our code once the DOM is ready.
    window.onload = function() {

    // Get a reference to the canvas object
    var canvas = document.getElementById('papercanvas');

    // Create an empty project and a view for the canvas:
    paper.setup(canvas);

    var totalBubbles = 60;
    var firstCanvasSize = new paper.Size(paper.view.bounds.width, paper.view.bounds.height);

    makeBubbles(totalBubbles, bubbles, firstCanvasSize);

    paper.view.onFrame = function(event) {
       for(var i=0; i <= bubbles.length-1; i ++) {
            var bubble1 = bubbles[i];
            bubble1.moveBubble();

            var bubble1Pos = bubble1.getBubblePos();

            var tempRad = 5;

            for(var j=0; j <= bubbles.length-1; j ++) {
                if(j!=i) {
                    var bubble2 = bubbles[j];
                    var bubble2Pos = bubble2.getBubblePos();

                    var testDist = getDistance(bubble2Pos, bubble1Pos);
                    tempRad += testDist;
                }
            }

            bubble1.setBubbleRadius(tempRad);

        }

    }

    // Draw the view now:
    paper.view.draw();

  }

  window.addEventListener("resize", function(){

     var newCanvasSize = new paper.Size(paper.view.bounds.width, paper.view.bounds.height);

    for(var i=0; i <= bubbles.length-1; i ++) {
        var bubble1 = bubbles[i];
        // bubble1.setCanvasBounds(newCanvasSize);
        bubble1.resizeCanvas(newCanvasSize);
    }
c
  });<commit_msg>metaball bubGap<commit_after>var lightPink = '#ffc1c9';

function randomGap(min,max)
{
    return Math.floor(Math.random()*(max-min+1)+min);
}

// Check the distance between passed Variable and this one.
function getDistance(position1, position2, tempGap) {

    var distGap = position2.subtract(position1);

    var tempLength = distGap.length;
    var rtnLength = 0;

    var bubGap = tempGap;

    if(tempLength < bubGap) {
        rtnLength = bubGap - tempLength;
    } else {
        rtnLength = 0;
    }
    return rtnLength;
}

function createBubble(initialPos) {

    var bubblePos = initialPos;
    var bubbleRadius =  20;
    var bubbleSpeed = new paper.Point(1.2, 1.2).multiply(paper.Point.random());
    var bubbleDirection = new paper.Point(1,1);

    var bubbleShape = new paper.Path.Circle(bubblePos, bubbleRadius);
        bubbleShape.fillColor = lightPink;
        // bubbleShape.scaling = 1.0;
        bubbleShape.size = new paper.Size(10,10);

    var canvasSize = new paper.Size(paper.view.bounds.width, paper.view.bounds.height);

    function getBubbleShape() {
        return bubbleShape;
    }

    function getBubblePos() {
        return bubblePos;
    }

    function setBubbleRadius(scal) {
        bubbleShape.bounds.width = scal;
        bubbleShape.bounds.height = scal;
    }

    function moveBubble() {
        if( bubblePos.x >= canvasSize.width || bubblePos.x <= 0)
            { bubbleDirection.x = bubbleDirection.x * -1;}
        if( bubblePos.y >= canvasSize.height || bubblePos.y <= 0)
            { bubbleDirection.y = bubbleDirection.y * -1;}

        bubblePos = bubblePos.add(bubbleSpeed.multiply(bubbleDirection));
        bubbleShape.position = bubblePos;
    }

    function removeBubble(){
        bubbleShape.remove();
    }

    function setCanvasBounds(tempCanSize){
        canvasSize = tempCanSize;
    }

    function resizeCanvas(tempCanSize){
        setCanvasBounds(tempCanSize);

        if(bubblePos.x > tempCanSize.width+2){bubblePos.x = tempCanSize.width-2;}
        if(bubblePos.y > tempCanSize.height+2){bubblePos.y = tempCanSize.height-2;}

        if(bubblePos.x < -2){bubblePos.x = 2;}
        if(bubblePos.y < -2){bubblePos.y = 2;}
    }

    var bubble = {
      getBubbleShape: getBubbleShape,
      setBubbleRadius: setBubbleRadius,
      getBubblePos: getBubblePos,
      moveBubble: moveBubble,
      removeBubble: removeBubble,
      setCanvasBounds: setCanvasBounds,
      resizeCanvas: resizeCanvas
    }

    return bubble;
}

function makeBubbles(amount, array, tempCanSize){

    var bubbleTotal = amount;

    for(var i=0; i < bubbleTotal; i ++) {
        var tempPos = new paper.Point(tempCanSize.width, tempCanSize.height).multiply(paper.Point.random());
        var tempBubble = createBubble(tempPos);
        tempBubble.setCanvasBounds(tempCanSize);
        array.push(tempBubble);
    }

}

function deleteAllBubbles(){
    for(var i=0; i <= bubbles.length-1; i ++) {
       var bubble1 = bubbles[i];
       bubble1.removeBubble();
    }
    bubbles = [];
}

var bubGap = 110;

paper.install(window);

    //instantiate bubbles
    var bubbles = [];

    // Only executed our code once the DOM is ready.
    window.onload = function() {

    // Get a reference to the canvas object
    var canvas = document.getElementById('papercanvas');

    // Create an empty project and a view for the canvas:
    paper.setup(canvas);

    var totalBubbles = 60;
    var firstCanvasSize = new paper.Size(paper.view.bounds.width, paper.view.bounds.height);

    makeBubbles(totalBubbles, bubbles, firstCanvasSize);

    paper.view.onFrame = function(event) {
       for(var i=0; i <= bubbles.length-1; i ++) {
            var bubble1 = bubbles[i];
            bubble1.moveBubble();

            var bubble1Pos = bubble1.getBubblePos();

            var tempRad = 5;

            for(var j=0; j <= bubbles.length-1; j ++) {
                if(j!=i) {
                    var bubble2 = bubbles[j];
                    var bubble2Pos = bubble2.getBubblePos();

                    var testDist = getDistance(bubble2Pos, bubble1Pos, bubGap);
                    tempRad += testDist;
                }
            }

            bubble1.setBubbleRadius(tempRad);

        }

    }

    // Draw the view now:
    paper.view.draw();

  }

  window.addEventListener("resize", function(){

     var newCanvasSize = new paper.Size(paper.view.bounds.width, paper.view.bounds.height);

     bubGap = newCanvasSize.width / 12;
     // console.log(bubGap);

    for(var i=0; i <= bubbles.length-1; i ++) {
        var bubble1 = bubbles[i];
        // bubble1.setCanvasBounds(newCanvasSize);
        bubble1.resizeCanvas(newCanvasSize);
    }

  });<|endoftext|>


<commit_before>import React from 'react';
import 'react-highcharts/dist/bundle/highcharts';
import RainbowDemo from './rainbow-demo';

class Charts extends React.Component {
  /**
   * @method render
   */
  render() {
    return (

Charts

        <RainbowDemo />

    );
  }
}

export default Charts;
<commit_msg>fix rainbow in demo site<commit_after>import React from 'react';
import 'highcharts';
import RainbowDemo from './rainbow-demo';

class Charts extends React.Component {
  /**
   * @method render
   */
  render() {
    return (

Charts

        <RainbowDemo />

    );
  }
}

export default Charts;
<|endoftext|>


<commit_before>var encodings = require('./encodings')
var varint = require('varint')
var genobj = require('generate-object-property')
var genfun = require('generate-function')

var skip = function(type, buffer, offset) {
  switch (type) {
    case 0:
    varint.decode(buffer, offset)
    return offset + varint.decode.bytes

    case 1:
    return offset + 8

    case 2:
    var len = varint.decode(buffer, offset)
    return offset + varint.decode.bytes + len

    case 3:
    case 4:
    throw new Error('Groups are not supported')

    case 5:
    return offset + 4
  }

  throw new Error('Unknown wire type: '+type)
}

var defined = function(val) {
  return val !== null && val !== undefined
}

var isString = function(def) {
  try {
    return !!def && typeof JSON.parse(def) === 'string'
  } catch (err) {
    return false
  }
}

var defaultValue = function(f, def) {
  if (f.repeated) return '[]'

  switch (f.type) {
    case 'string':
    return isString(def) ? def : '""'

    case 'bool':
    if (def === 'true') return 'true'
    return 'false'

    case 'float':
    case 'double':
    case 'sfixed32':
    case 'fixed32':
    case 'varint':
    case 'enum':
    case 'uint64':
    case 'uint32':
    case 'int64':
    case 'int32':
    case 'sint64':
    case 'sint32':
    return ''+parseInt(def || 0)

    default:
    return 'null'
  }
}

module.exports = function(schema, extraEncodings) {
  var messages = {}
  var enums = {}
  var cache = {}

  var visit = function(schema, prefix) {
    if (schema.enums) {
      schema.enums.forEach(function(e) {
        e.id = prefix + (prefix ? '.' : '')+e.name
        enums[e.id] = e
        visit(e, e.id)
      })
    }
    if (schema.messages) {
      schema.messages.forEach(function(m) {
        m.id = prefix + (prefix ? '.' : '')+m.name
        messages[m.id] = m
        visit(m, m.id)
      })
    }
  }

  visit(schema, '')

  var compileEnum = function(e) {
    var conditions = Object.keys(e.values)
      .map(function(k) {
        return 'val !== '+parseInt(e.values[k])
      })
      .join(' && ')

    if (!conditions) conditions = 'true'

    var encode = genfun()
      ('function encode(val, buf, offset) {')
        ('if (%s) throw new Error("Invalid enum value: "+val)', conditions)
        ('varint.encode(val, buf, offset)')
        ('encode.bytes = varint.encode.bytes')
        ('return buf')
      ('}')
      .toFunction({
        varint: varint
      })

    var decode = genfun()
      ('function decode(buf, offset) {')
        ('var val = varint.decode(buf, offset)')
        ('if (%s) throw new Error("Invalid enum value: "+val)', conditions)
        ('decode.bytes = varint.decode.bytes')
        ('return val')
      ('}')
      .toFunction({
        varint: varint
      })

    return encodings.make(0, encode, decode, varint.encodingLength)
  }

  var compileMessage = function(m, exports) {
    exports.type = 2
    exports.message = true
    exports.name = m.name

    var enc = m.fields.map(function(f, i) {
      return resolve(f.type, m.id)
    })

    var forEach = function(fn) {
      for (var i = 0; i < enc.length; i++) fn(enc[i], m.fields[i], genobj('obj', m.fields[i].name), i)
    }

    // compile encodingLength

    var encodingLength = genfun()
      ('function encodingLength(obj) {')
        ('var length = 0')

    forEach(function(e, f, val, i) {
      var packed = f.repeated && f.options && f.options.packed
      var hl = varint.encodingLength(f.tag << 3 | e.type)

      if (f.required) encodingLength('if (!defined(%s)) throw new Error(%s)', val, JSON.stringify(f.name+' is required'))
      else encodingLength('if (defined(%s)) {', val)

      if (packed) {
        encodingLength()
          ('var packedLen = 0')
          ('for (var i = 0; i < %s.length; i++) {', val)
            ('if (!defined(%s)) continue', val+'[i]')
            ('var len = enc[%d].encodingLength(%s)', i, val+'[i]')
            ('packedLen += len')
            if (e.message) encodingLength('packedLen += varint.encodingLength(len)')
          encodingLength('}')
          ('if (packedLen) {')
            ('length += %d + packedLen + varint.encodingLength(packedLen)', hl)
          ('}')
      } else {
        if (f.repeated) {
          encodingLength('for (var i = 0; i < %s.length; i++) {', val)
          val += '[i]'
          encodingLength('if (!defined(%s)) continue', val)
        }

        encodingLength('var len = enc[%d].encodingLength(%s)', i, val)
        if (e.message) encodingLength('length += varint.encodingLength(len)')
        encodingLength('length += %d + len', hl)
        if (f.repeated) encodingLength('}')
      }

      if (!f.required) encodingLength('}')
    })

    encodingLength()
        ('return length')
      ('}')

    encodingLength = encodingLength.toFunction({
      defined: defined,
      varint: varint,
      enc: enc
    })

    // compile encode

    var encode = genfun()
      ('function encode(obj, buf, offset) {')
        ('if (!offset) offset = 0')
        ('if (!buf) buf = new Buffer(encodingLength(obj))')
        ('var oldOffset = offset')

    forEach(function(e, f, val, i) {
      if (f.required) encode('if (!defined(%s)) throw new Error(%s)', val, JSON.stringify(f.name+' is required'))
      else encode('if (defined(%s)) {', val)

      var packed = f.repeated && f.options && f.options.packed
      var p = varint.encode(f.tag << 3 | 2)
      var h = varint.encode(f.tag << 3 | e.type)

      if (packed) {
        encode()
          ('var packedLen = 0')
          ('for (var i = 0; i < %s.length; i++) {', val)
            ('if (!defined(%s)) continue', val+'[i]')
            ('packedLen += enc[%d].encodingLength(%s)', i, val+'[i]')
          ('}')

        encode('if (packedLen) {')
        for (var j = 0; j < h.length; j++) encode('buf[offset++] = %d', p[j])
        encode('varint.encode(packedLen, buf, offset)')
        encode('offset += varint.encode.bytes')
        encode('}')
      }

      if (f.repeated) {
        encode('for (var i = 0; i < %s.length; i++) {', val)
        val += '[i]'
        encode('if (!defined(%s)) continue', val)
      }

      if (!packed) for (var j = 0; j < h.length; j++) encode('buf[offset++] = %d', h[j])

      if (e.message) {
        encode('varint.encode(enc[%d].encodingLength(%s), buf, offset)', i, val)
        encode('offset += varint.encode.bytes')
      }

      encode('enc[%d].encode(%s, buf, offset)', i, val)
      encode('offset += enc[%d].encode.bytes', i)

      if (f.repeated) encode('}')
      if (!f.required) encode('}')
    })

    encode()
        ('encode.bytes = offset - oldOffset')
        ('return buf')
      ('}')

    encode = encode.toFunction({
      encodingLength: encodingLength,
      defined: defined,
      varint: varint,
      enc: enc,
      Buffer: Buffer
    })

    // compile proto

    var Message = genfun()

    Message('function Message() {')
    forEach(function(e, f) {
      var def = f.options && f.options.default
      var resolved = resolve(f.type, m.id, false)
      var vals = resolved && resolved.values

      if (vals) { // is enum
        if (f.repeated) {
          Message('%s = []', genobj('this', f.name))
        } else {
          def = (def && def in vals) ? vals[def] : vals[Object.keys(vals)[0]]
          Message('%s = %s', genobj('this', f.name), ''+parseInt(def || 0))
        }
        return
      }

      Message('%s = %s', genobj('this', f.name), defaultValue(f, def))
    })
    Message('}')

    Message = Message.toFunction()

    // compile decode

    var invalid = m.fields
      .map(function(f, i) {
        return f.required && '!found'+i
      })
      .filter(function(f) {
        return f
      })
      .join(' || ')

    var decode = genfun()

    decode()
      ('function decode(buf, offset, end) {')
        ('if (!offset) offset = 0')
        ('if (!end) end = buf.length')
        ('if (!(end <= buf.length && offset <= buf.length)) throw new Error("Decoded message is not valid")')
        ('var oldOffset = offset')
        ('var obj = new Message()')

    forEach(function(e, f, val, i) {
      if (f.required) decode('var found%d = false', i)
    })

    decode('while (true) {')
      ('if (end <= offset) {')
        (invalid && 'if (%s) throw new Error("Decoded message is not valid")', invalid)
        ('decode.bytes = offset - oldOffset')
        ('return obj')
      ('}')
      ('var prefix = varint.decode(buf, offset)')
      ('offset += varint.decode.bytes')
      ('var tag = prefix >> 3')
      ('switch (tag) {')

    forEach(function(e, f, val, i) {
      var packed = f.repeated && f.options && f.options.packed

      decode('case %d:', f.tag)

      if (packed) {
        decode()
          ('var packedEnd = varint.decode(buf, offset)')
          ('offset += varint.decode.bytes')
          ('packedEnd += offset')
          ('while (offset < packedEnd) {')
      }

      if (e.message) {
        decode('var len = varint.decode(buf, offset)')
        decode('offset += varint.decode.bytes')
        if (f.repeated) decode('%s.push(enc[%d].decode(buf, offset, offset + len))', val, i)
        else decode('%s = enc[%d].decode(buf, offset, offset + len)', val, i)
      } else {
        if (f.repeated) decode('%s.push(enc[%d].decode(buf, offset))', val, i)
        else decode('%s = enc[%d].decode(buf, offset)', val, i)
      }

      decode('offset += enc[%d].decode.bytes', i)

      if (packed) decode('}')
      if (f.required) decode('found%d = true', i)
      decode('break')
    })

    decode()
          ('default:')
          ('offset = skip(prefix & 7, buf, offset)')
        ('}')
      ('}')
    ('}')

    decode = decode.toFunction({
      Message: Message,
      varint: varint,
      skip: skip,
      enc: enc
    })

    // end of compilation - return all the things

    encode.bytes = decode.bytes = 0

    exports.buffer = true
    exports.encode = encode
    exports.decode = decode
    exports.encodingLength = encodingLength

    return exports
  }

  var resolve = function(name, from, compile) {
    if (extraEncodings && extraEncodings[name]) return extraEncodings[name]
    if (encodings[name]) return encodings[name]

    var m = (from ? from+'.'+name : name).split('.')
      .map(function(part, i, list) {
        return list.slice(0, i).concat(name).join('.')
      })
      .reverse()
      .reduce(function(result, id) {
        return result || messages[id] || enums[id]
      }, null)

    if (compile === false) return m
    if (!m) throw new Error('Could not resolve '+name)

    if (m.values) return compileEnum(m)
    return cache[m.id] || compileMessage(m, cache[m.id] = {})
  }

  return (schema.enums || []).concat((schema.messages || []).map(function(message) {
    return resolve(message.id)
  }))
}<commit_msg>Expose nested enums<commit_after>var encodings = require('./encodings')
var varint = require('varint')
var genobj = require('generate-object-property')
var genfun = require('generate-function')

var skip = function(type, buffer, offset) {
  switch (type) {
    case 0:
    varint.decode(buffer, offset)
    return offset + varint.decode.bytes

    case 1:
    return offset + 8

    case 2:
    var len = varint.decode(buffer, offset)
    return offset + varint.decode.bytes + len

    case 3:
    case 4:
    throw new Error('Groups are not supported')

    case 5:
    return offset + 4
  }

  throw new Error('Unknown wire type: '+type)
}

var defined = function(val) {
  return val !== null && val !== undefined
}

var isString = function(def) {
  try {
    return !!def && typeof JSON.parse(def) === 'string'
  } catch (err) {
    return false
  }
}

var defaultValue = function(f, def) {
  if (f.repeated) return '[]'

  switch (f.type) {
    case 'string':
    return isString(def) ? def : '""'

    case 'bool':
    if (def === 'true') return 'true'
    return 'false'

    case 'float':
    case 'double':
    case 'sfixed32':
    case 'fixed32':
    case 'varint':
    case 'enum':
    case 'uint64':
    case 'uint32':
    case 'int64':
    case 'int32':
    case 'sint64':
    case 'sint32':
    return ''+parseInt(def || 0)

    default:
    return 'null'
  }
}

module.exports = function(schema, extraEncodings) {
  var messages = {}
  var enums = {}
  var cache = {}

  var visit = function(schema, prefix) {
    if (schema.enums) {
      schema.enums.forEach(function(e) {
        e.id = prefix + (prefix ? '.' : '')+e.name
        enums[e.id] = e
        visit(e, e.id)
      })
    }
    if (schema.messages) {
      schema.messages.forEach(function(m) {
        m.id = prefix + (prefix ? '.' : '')+m.name
        messages[m.id] = m
        visit(m, m.id)
      })
    }
  }

  visit(schema, '')

  var compileEnum = function(e) {
    var conditions = Object.keys(e.values)
      .map(function(k) {
        return 'val !== '+parseInt(e.values[k])
      })
      .join(' && ')

    if (!conditions) conditions = 'true'

    var encode = genfun()
      ('function encode(val, buf, offset) {')
        ('if (%s) throw new Error("Invalid enum value: "+val)', conditions)
        ('varint.encode(val, buf, offset)')
        ('encode.bytes = varint.encode.bytes')
        ('return buf')
      ('}')
      .toFunction({
        varint: varint
      })

    var decode = genfun()
      ('function decode(buf, offset) {')
        ('var val = varint.decode(buf, offset)')
        ('if (%s) throw new Error("Invalid enum value: "+val)', conditions)
        ('decode.bytes = varint.decode.bytes')
        ('return val')
      ('}')
      .toFunction({
        varint: varint
      })

    return encodings.make(0, encode, decode, varint.encodingLength)
  }

  var compileMessage = function(m, exports) {
    exports.type = 2
    exports.message = true
    exports.name = m.name

    m.enums.forEach(function( val ) {
      exports[ val.name ] = val.values
    })

    var enc = m.fields.map(function(f, i) {
      return resolve(f.type, m.id)
    })

    var forEach = function(fn) {
      for (var i = 0; i < enc.length; i++) fn(enc[i], m.fields[i], genobj('obj', m.fields[i].name), i)
    }

    // compile encodingLength

    var encodingLength = genfun()
      ('function encodingLength(obj) {')
        ('var length = 0')

    forEach(function(e, f, val, i) {
      var packed = f.repeated && f.options && f.options.packed
      var hl = varint.encodingLength(f.tag << 3 | e.type)

      if (f.required) encodingLength('if (!defined(%s)) throw new Error(%s)', val, JSON.stringify(f.name+' is required'))
      else encodingLength('if (defined(%s)) {', val)

      if (packed) {
        encodingLength()
          ('var packedLen = 0')
          ('for (var i = 0; i < %s.length; i++) {', val)
            ('if (!defined(%s)) continue', val+'[i]')
            ('var len = enc[%d].encodingLength(%s)', i, val+'[i]')
            ('packedLen += len')
            if (e.message) encodingLength('packedLen += varint.encodingLength(len)')
          encodingLength('}')
          ('if (packedLen) {')
            ('length += %d + packedLen + varint.encodingLength(packedLen)', hl)
          ('}')
      } else {
        if (f.repeated) {
          encodingLength('for (var i = 0; i < %s.length; i++) {', val)
          val += '[i]'
          encodingLength('if (!defined(%s)) continue', val)
        }

        encodingLength('var len = enc[%d].encodingLength(%s)', i, val)
        if (e.message) encodingLength('length += varint.encodingLength(len)')
        encodingLength('length += %d + len', hl)
        if (f.repeated) encodingLength('}')
      }

      if (!f.required) encodingLength('}')
    })

    encodingLength()
        ('return length')
      ('}')

    encodingLength = encodingLength.toFunction({
      defined: defined,
      varint: varint,
      enc: enc
    })

    // compile encode

    var encode = genfun()
      ('function encode(obj, buf, offset) {')
        ('if (!offset) offset = 0')
        ('if (!buf) buf = new Buffer(encodingLength(obj))')
        ('var oldOffset = offset')

    forEach(function(e, f, val, i) {
      if (f.required) encode('if (!defined(%s)) throw new Error(%s)', val, JSON.stringify(f.name+' is required'))
      else encode('if (defined(%s)) {', val)

      var packed = f.repeated && f.options && f.options.packed
      var p = varint.encode(f.tag << 3 | 2)
      var h = varint.encode(f.tag << 3 | e.type)

      if (packed) {
        encode()
          ('var packedLen = 0')
          ('for (var i = 0; i < %s.length; i++) {', val)
            ('if (!defined(%s)) continue', val+'[i]')
            ('packedLen += enc[%d].encodingLength(%s)', i, val+'[i]')
          ('}')

        encode('if (packedLen) {')
        for (var j = 0; j < h.length; j++) encode('buf[offset++] = %d', p[j])
        encode('varint.encode(packedLen, buf, offset)')
        encode('offset += varint.encode.bytes')
        encode('}')
      }

      if (f.repeated) {
        encode('for (var i = 0; i < %s.length; i++) {', val)
        val += '[i]'
        encode('if (!defined(%s)) continue', val)
      }

      if (!packed) for (var j = 0; j < h.length; j++) encode('buf[offset++] = %d', h[j])

      if (e.message) {
        encode('varint.encode(enc[%d].encodingLength(%s), buf, offset)', i, val)
        encode('offset += varint.encode.bytes')
      }

      encode('enc[%d].encode(%s, buf, offset)', i, val)
      encode('offset += enc[%d].encode.bytes', i)

      if (f.repeated) encode('}')
      if (!f.required) encode('}')
    })

    encode()
        ('encode.bytes = offset - oldOffset')
        ('return buf')
      ('}')

    encode = encode.toFunction({
      encodingLength: encodingLength,
      defined: defined,
      varint: varint,
      enc: enc,
      Buffer: Buffer
    })

    // compile proto

    var Message = genfun()

    Message('function Message() {')
    forEach(function(e, f) {
      var def = f.options && f.options.default
      var resolved = resolve(f.type, m.id, false)
      var vals = resolved && resolved.values

      if (vals) { // is enum
        if (f.repeated) {
          Message('%s = []', genobj('this', f.name))
        } else {
          def = (def && def in vals) ? vals[def] : vals[Object.keys(vals)[0]]
          Message('%s = %s', genobj('this', f.name), ''+parseInt(def || 0))
        }
        return
      }

      Message('%s = %s', genobj('this', f.name), defaultValue(f, def))
    })
    Message('}')

    Message = Message.toFunction()

    // compile decode

    var invalid = m.fields
      .map(function(f, i) {
        return f.required && '!found'+i
      })
      .filter(function(f) {
        return f
      })
      .join(' || ')

    var decode = genfun()

    decode()
      ('function decode(buf, offset, end) {')
        ('if (!offset) offset = 0')
        ('if (!end) end = buf.length')
        ('if (!(end <= buf.length && offset <= buf.length)) throw new Error("Decoded message is not valid")')
        ('var oldOffset = offset')
        ('var obj = new Message()')

    forEach(function(e, f, val, i) {
      if (f.required) decode('var found%d = false', i)
    })

    decode('while (true) {')
      ('if (end <= offset) {')
        (invalid && 'if (%s) throw new Error("Decoded message is not valid")', invalid)
        ('decode.bytes = offset - oldOffset')
        ('return obj')
      ('}')
      ('var prefix = varint.decode(buf, offset)')
      ('offset += varint.decode.bytes')
      ('var tag = prefix >> 3')
      ('switch (tag) {')

    forEach(function(e, f, val, i) {
      var packed = f.repeated && f.options && f.options.packed

      decode('case %d:', f.tag)

      if (packed) {
        decode()
          ('var packedEnd = varint.decode(buf, offset)')
          ('offset += varint.decode.bytes')
          ('packedEnd += offset')
          ('while (offset < packedEnd) {')
      }

      if (e.message) {
        decode('var len = varint.decode(buf, offset)')
        decode('offset += varint.decode.bytes')
        if (f.repeated) decode('%s.push(enc[%d].decode(buf, offset, offset + len))', val, i)
        else decode('%s = enc[%d].decode(buf, offset, offset + len)', val, i)
      } else {
        if (f.repeated) decode('%s.push(enc[%d].decode(buf, offset))', val, i)
        else decode('%s = enc[%d].decode(buf, offset)', val, i)
      }

      decode('offset += enc[%d].decode.bytes', i)

      if (packed) decode('}')
      if (f.required) decode('found%d = true', i)
      decode('break')
    })

    decode()
          ('default:')
          ('offset = skip(prefix & 7, buf, offset)')
        ('}')
      ('}')
    ('}')

    decode = decode.toFunction({
      Message: Message,
      varint: varint,
      skip: skip,
      enc: enc
    })

    // end of compilation - return all the things

    encode.bytes = decode.bytes = 0

    exports.buffer = true
    exports.encode = encode
    exports.decode = decode
    exports.encodingLength = encodingLength

    return exports
  }

  var resolve = function(name, from, compile) {
    if (extraEncodings && extraEncodings[name]) return extraEncodings[name]
    if (encodings[name]) return encodings[name]

    var m = (from ? from+'.'+name : name).split('.')
      .map(function(part, i, list) {
        return list.slice(0, i).concat(name).join('.')
      })
      .reverse()
      .reduce(function(result, id) {
        return result || messages[id] || enums[id]
      }, null)

    if (compile === false) return m
    if (!m) throw new Error('Could not resolve '+name)

    if (m.values) return compileEnum(m)
    return cache[m.id] || compileMessage(m, cache[m.id] = {})
  }

  return (schema.enums || []).concat((schema.messages || []).map(function(message) {
    return resolve(message.id)
  }))
}
<|endoftext|>


<commit_before>Shade.Exp = {
    debug_print: function(indent) {
        if (_.isUndefined(indent)) indent = 0;
        var str = "";
        for (var i=0; i<indent; ++i) { str = str + ' '; }
        if (this.parents.length === 0)
            console.log(str + "[" + this.expression_type + ":" + this.guid + "]"
                        // + "[is_constant: " + this.is_constant() + "]"
                        + "()");
        else {
            console.log(str + "[" + this.expression_type + ":" + this.guid + "]"
                        // + "[is_constant: " + this.is_constant() + "]"
                        + "(");
            for (i=0; i<this.parents.length; ++i)
                this.parents[i].debug_print(indent + 2);
            console.log(str + ')');
        }
    },
    evaluate: function() {
        return this.glsl_name + "()";
    },
    parent_is_unconditional: function(i) {
        return true;
    },
    propagate_conditions: function() {
        // the condition for an execution of a node is the
        // disjunction of the conjunction of all its children and their respective
        // edge conditions
        for (var i=0; i<this.parents.length; ++i)
            this.parents[i].is_unconditional = (
                this.parents[i].is_unconditional ||
                    (this.is_unconditional &&
                     this.parent_is_unconditional(i)));

    },
    set_requirements: function() {},
    // if stage is "vertex" then this expression will be hoisted to the vertex shader
    stage: null,
    // returns all sub-expressions in topologically-sorted order
    sorted_sub_expressions: function() {
        var so_far = [];
        var topological_sort_internal = function(exp) {
            if (so_far.indexOf(exp) != -1) {
                return;
            }
            var parents = exp.parents;
            if (_.isUndefined(parents)) {
                throw "Internal error: expression " + exp.evaluate()
                    + " has undefined parents.";
            }
            for (var i=0; i<parents.length; ++i) {
                topological_sort_internal(parents[i]);
            }
            so_far.push(exp);
        };
        topological_sort_internal(this);
        return so_far;
    },

    //////////////////////////////////////////////////////////////////////////
    // constant checking, will be useful for folding and for enforcement

    is_constant: function() {
        return false;
    },
    constant_value: function() {
        throw "invalid call: this.is_constant() == false";
    },
    element_is_constant: function(i) {
        return false;
    },
    element_constant_value: function(i) {
        throw "invalid call: no constant elements";
    },

    //////////////////////////////////////////////////////////////////////////
    // element access for compound expressions

    element: function(i) {
        throw "invalid call: atomic expression";
    },

    //////////////////////////////////////////////////////////////////////////
    // some sugar

    add: function(op) {
        return Shade.add(this, op);
    },
    mul: function(op) {
        return Shade.mul(this, op);
    },
    div: function(op) {
        return Shade.div(this, op);
    },
    sub: function(op) {
        return Shade.sub(this, op);
    },
    length: function() {
        return Shade.length(this);
    },
    distance: function(other) {
        return Shade.distance(this, other);
    },
    dot: function(other) {
        return Shade.dot(this, other);
    },
    cross: function(other) {
        return Shade.cross(this, other);
    },
    normalize: function() {
        return Shade.normalize(this);
    },
    reflect: function(other) {
        return Shade.reflect(this, other);
    },
    refract: function(o1, o2) {
        return Shade.refract(this, o1, o2);
    },
    texture2D: function(coords) {
        return Shade.texture2D(this, coords);
    },
    clamp: function(mn, mx) {
        return Shade.clamp(this, mn, mx);
    },
    min: function(other) {
        return Shade.min(this, other);
    },
    max: function(other) {
        return Shade.max(this, other);
    },

    per_vertex: function() {
        return Shade.per_vertex(this);
    },
    discard_if: function(condition) {
        return Shade.discard_if(this, condition);
    },
    // all sugar for funcs_1op is defined later on in the source

    //////////////////////////////////////////////////////////////////////////

    as_int: function() {
        if (this.type.equals(Shade.Types.int_t))
            return this;
        var parent = this;
        return Shade._create_concrete_value_exp({
            parents: [parent],
            type: Shade.Types.int_t,
            value: function() { return "int(" + this.parents[0].evaluate() + ")"; },
            is_constant: function() { return parent.is_constant(); },
            constant_value: function() {
                var v = parent.constant_value();
                return Math.floor(v);
            },
            expression_type: "cast(int)"
        });
    },
    as_bool: function() {
        if (this.type.equals(Shade.Types.bool_t))
            return this;
        var parent = this;
        return Shade._create_concrete_value_exp({
            parents: [parent],
            type: Shade.Types.bool_t,
            value: function() { return "bool(" + this.parents[0].evaluate() + ")"; },
            is_constant: function() { return parent.is_constant(); },
            constant_value: function() {
                var v = parent.constant_value();
                return ~~v;
            },
            expression_type: "cast(bool)"
        });
    },
    as_float: function() {
        if (this.type.equals(Shade.Types.float_t))
            return this;
        var parent = this;
        return Shade._create_concrete_value_exp({
            parents: [parent],
            type: Shade.Types.float_t,
            value: function() { return "float(" + this.parents[0].evaluate() + ")"; },
            is_constant: function() { return parent.is_constant(); },
            constant_value: function() {
                var v = parent.constant_value();
                return Number(v);
            },
            expression_type: "cast(float)"
        });
    },
    swizzle: function(pattern) {
        function swizzle_pattern_to_indices(pattern) {
            function to_index(v) {
                switch (v.toLowerCase()) {
                case 'r': return 0;
                case 'g': return 1;
                case 'b': return 2;
                case 'a': return 3;
                case 'x': return 0;
                case 'y': return 1;
                case 'z': return 2;
                case 'w': return 3;
                case 's': return 0;
                case 't': return 1;
                case 'p': return 2;
                case 'q': return 3;
                default: throw "invalid swizzle pattern";
                }
            }
            var result = [];
            for (var i=0; i<pattern.length; ++i) {
                result.push(to_index(pattern[i]));
            }
            return result;
        }

        var parent = this;
        var indices = swizzle_pattern_to_indices(pattern);
        return Shade._create_concrete_exp( {
            parents: [parent],
            type: parent.type.swizzle(pattern),
            expression_type: "swizzle",
            evaluate: function() { return this.parents[0].evaluate() + "." + pattern; },
            is_constant: Shade.memoize_on_field("_is_constant", function () {
                var that = this;
                return _.all(indices, function(i) {
                    return that.parents[0].element_is_constant(i);
                });
            }),
            constant_value: Shade.memoize_on_field("_constant_value", function() {
                if (this.type.is_pod()) {
                    return this.parents[0].element_constant_value(indices[0]);
                } else {
                    var that = this;
                    var ar = _.map(indices, function(index) {
                        return that.parents[0].element_constant_value(index);
                    });
                    var d = this.type.vec_dimension();
                    switch (d) {
                    case 2: return vec2.make(ar);
                    case 3: return vec3.make(ar);
                    case 4: return vec4.make(ar);
                    default:
                        throw "bad vec dimension " + d;
                    }
                }
            }),
            element: function(i) {
                return this.parents[0].element(indices[i]);
            },
            element_is_constant: Shade.memoize_on_field("_element_is_constant", function(i) {
                return this.parents[0].element_is_constant(indices[i]);
            }),
            element_constant_value: Shade.memoize_on_field("_element_constant_value", function(i) {
                return this.parents[0].element_constant_value(indices[i]);
            }),
            compile: function() {}
        });
    },
    at: function(index) {
        var parent = this;
        index = Shade.make(index);
        // this "works around" current constant index restrictions in webgl
        // look for it to get broken in the future as this hole is plugged.
        index._must_be_function_call = true;
        if (!index.type.equals(Shade.Types.float_t) &&
            !index.type.equals(Shade.Types.int_t)) {
            throw "at expects int or float, got '" +
                index.type.repr() + "' instead";
        }
        return Shade._create_concrete_exp( {
            parents: [parent, index],
            type: parent.type.array_base(),
            expression_type: "index",
            evaluate: function() {
                if (this.parents[1].type.is_integral()) {
                    return this.parents[0].evaluate() +
                        "[" + this.parents[1].evaluate() + "]";
                } else {
                    return this.parents[0].evaluate() +
                        "[int(" + this.parents[1].evaluate() + ")]";
                }
            },
            is_constant: function() {
                return (this.parents[0].is_constant() &&
                        this.parents[1].is_constant());
            },
            constant_value: Shade.memoize_on_field("_constant_value", function() {
                var a = this.parents[0].constant_value();
                if (facet_typeOf(a) === 'array') // this was a GLSL array of stuff
                    return a[this.parents[1].constant_value()];
                else { // this was a vec.
                    if (a._type === 'vector') {
                        return a[this.parents[1].constant_value()];
                    } else {
                        // FIXME: at constant_value for mats is broken.
                        //  Lift and use matrix_row from constant.js
                        throw "at constant_value for mats is currently broken";
                    }
                }
            }),
            // the reason for the (if x === this) checks here is that sometimes
            // the only appropriate description of an element() of an
            // opaque object (uniforms and attributes, notably) is an at() call.
            // This means that (this.parents[0].element(ix) === this) is
            // sometimes true, and we're stuck in an infinite loop.
            element: Shade.memoize_on_field("_element", function(i) {
                if (!this.parents[1].is_constant()) {
                    throw "at().element cannot be called with non-constant index";
                }
                var ix = this.parents[1].constant_value();
                var x = this.parents[0].element(ix);
                if (x === this) {
                    return x.at(i);
                } else
                    return x.element(i);
            }),
            element_is_constant: Shade.memoize_on_field("_element_is_constant", function(i) {
                if (!this.parents[1].is_constant()) {
                    return false;
                }
                var ix = this.parents[1].constant_value();
                var x = this.parents[0].element(ix);
                if (x === this) {
                    return false;
                } else
                    return x.element_is_constant(i);
            }),
            element_constant_value: Shade.memoize_on_field("_element_constant_value", function(i) {
                var ix = this.parents[1].constant_value();
                var x = this.parents[0].element(ix);
                if (x === this) {
                    throw "internal error: would have gone into an infinite loop here.";
                }
                return x.element_constant_value(i);
            }),
            compile: function() {}
        });
    },
    expression_type: "other",
    _type: "shade_expression",
    _attribute_buffers: [],
    _uniforms: [],
    attribute_buffers: function() {
        return _.flatten(this.sorted_sub_expressions().map(function(v) {
            return v._attribute_buffers;
        }));
    },
    uniforms: function() {
        return _.flatten(this.sorted_sub_expressions().map(function(v) {
            return v._uniforms;
        }));
    },

    // simple re-writing of shaders, useful for moving expressions
    // around, such as the things we move around when attributes are
    // referenced in fragment programs
    //
    // NB: it's easy to create bad expressions with these.
    //
    // The general rule is that types should be preserved (although
    // that might not *always* be the case)
    find_if: function(check) {
        return _.select(this.sorted_sub_expressions(), check);
    },
    replace_if: function(check, replacement) {
        var subexprs = this.sorted_sub_expressions();
        var replaced_pairs = [];
        function has_been_replaced(x) {
            return _.some(replaced_pairs, function(v) {
                return (x.guid === v[0].guid) && (v[0].guid !== v[1].guid); //_.isEqual(x, v[0]);
            });
        }
        function parent_replacement(x) {
            var r = _.select(replaced_pairs, function(v) {
                return (x.guid === v[0].guid) && (v[0].guid !== v[1].guid); //_.isEqual(x, v[0]);
            });
            if (r.length === 0)
                return x;
            else
                return r[0][1];
        }
        for (var i=0; i<subexprs.length; ++i) {
            var exp = subexprs[i];
            if (check(exp)) {
                replaced_pairs.push([exp, replacement(exp)]);
            } else if (_.some(exp.parents, has_been_replaced)) {
                var x = [exp, Shade._create(exp, {
                    parents: _.map(exp.parents, parent_replacement)
                })];
                replaced_pairs.push(x);
            } else {
                replaced_pairs.push([exp, exp]);
            }
        }
        var result = replaced_pairs[replaced_pairs.length-1][1];
        return result;
    }
};
Shade._create_concrete_exp = Shade._create_concrete(Shade.Exp, ["parents", "compile", "type"]);
<commit_msg>better debug_print on shade expressions<commit_after>Shade.Exp = {
    debug_print: function(do_what) {
        var lst = [];
        var refs = {};
        function _debug_print(which, indent) {
            var i;
            var str = new Array(indent+2).join(" "); // This is python's '" " * indent'
            // var str = "";
            // for (var i=0; i<indent; ++i) { str = str + ' '; }
            if (which.parents.length === 0)
                lst.push(str + "[" + which.expression_type + ":" + which.guid + "]"
                            // + "[is_constant: " + which.is_constant() + "]"
                            + " ()");
            else {
                lst.push(str + "[" + which.expression_type + ":" + which.guid + "]"
                            // + "[is_constant: " + which.is_constant() + "]"
                            + " (");
                for (i=0; i<which.parents.length; ++i) {
                    if (refs[which.parents[i].guid])
                        lst.push(str + "  {{" + which.parents[i].guid + "}}");
                    else {
                        _debug_print(which.parents[i], indent + 2);
                        refs[which.parents[i].guid] = 1;
                    }
                }
                lst.push(str + ')');
            }
        };
        _debug_print(this, 0);
        do_what = do_what || function(l) {
            var s = l.join("\n");
            console.log(s);
        };
        do_what(lst);
    },
    evaluate: function() {
        return this.glsl_name + "()";
    },
    parent_is_unconditional: function(i) {
        return true;
    },
    propagate_conditions: function() {
        // the condition for an execution of a node is the
        // disjunction of the conjunction of all its children and their respective
        // edge conditions
        for (var i=0; i<this.parents.length; ++i)
            this.parents[i].is_unconditional = (
                this.parents[i].is_unconditional ||
                    (this.is_unconditional &&
                     this.parent_is_unconditional(i)));

    },
    set_requirements: function() {},
    // if stage is "vertex" then this expression will be hoisted to the vertex shader
    stage: null,
    // returns all sub-expressions in topologically-sorted order
    sorted_sub_expressions: function() {
        var so_far = [];
        var topological_sort_internal = function(exp) {
            if (so_far.indexOf(exp) != -1) {
                return;
            }
            var parents = exp.parents;
            if (_.isUndefined(parents)) {
                throw "Internal error: expression " + exp.evaluate()
                    + " has undefined parents.";
            }
            for (var i=0; i<parents.length; ++i) {
                topological_sort_internal(parents[i]);
            }
            so_far.push(exp);
        };
        topological_sort_internal(this);
        return so_far;
    },

    //////////////////////////////////////////////////////////////////////////
    // constant checking, will be useful for folding and for enforcement

    is_constant: function() {
        return false;
    },
    constant_value: function() {
        throw "invalid call: this.is_constant() == false";
    },
    element_is_constant: function(i) {
        return false;
    },
    element_constant_value: function(i) {
        throw "invalid call: no constant elements";
    },

    //////////////////////////////////////////////////////////////////////////
    // element access for compound expressions

    element: function(i) {
        throw "invalid call: atomic expression";
    },

    //////////////////////////////////////////////////////////////////////////
    // some sugar

    add: function(op) {
        return Shade.add(this, op);
    },
    mul: function(op) {
        return Shade.mul(this, op);
    },
    div: function(op) {
        return Shade.div(this, op);
    },
    sub: function(op) {
        return Shade.sub(this, op);
    },
    length: function() {
        return Shade.length(this);
    },
    distance: function(other) {
        return Shade.distance(this, other);
    },
    dot: function(other) {
        return Shade.dot(this, other);
    },
    cross: function(other) {
        return Shade.cross(this, other);
    },
    normalize: function() {
        return Shade.normalize(this);
    },
    reflect: function(other) {
        return Shade.reflect(this, other);
    },
    refract: function(o1, o2) {
        return Shade.refract(this, o1, o2);
    },
    texture2D: function(coords) {
        return Shade.texture2D(this, coords);
    },
    clamp: function(mn, mx) {
        return Shade.clamp(this, mn, mx);
    },
    min: function(other) {
        return Shade.min(this, other);
    },
    max: function(other) {
        return Shade.max(this, other);
    },

    per_vertex: function() {
        return Shade.per_vertex(this);
    },
    discard_if: function(condition) {
        return Shade.discard_if(this, condition);
    },
    // all sugar for funcs_1op is defined later on in the source

    //////////////////////////////////////////////////////////////////////////

    as_int: function() {
        if (this.type.equals(Shade.Types.int_t))
            return this;
        var parent = this;
        return Shade._create_concrete_value_exp({
            parents: [parent],
            type: Shade.Types.int_t,
            value: function() { return "int(" + this.parents[0].evaluate() + ")"; },
            is_constant: function() { return parent.is_constant(); },
            constant_value: function() {
                var v = parent.constant_value();
                return Math.floor(v);
            },
            expression_type: "cast(int)"
        });
    },
    as_bool: function() {
        if (this.type.equals(Shade.Types.bool_t))
            return this;
        var parent = this;
        return Shade._create_concrete_value_exp({
            parents: [parent],
            type: Shade.Types.bool_t,
            value: function() { return "bool(" + this.parents[0].evaluate() + ")"; },
            is_constant: function() { return parent.is_constant(); },
            constant_value: function() {
                var v = parent.constant_value();
                return ~~v;
            },
            expression_type: "cast(bool)"
        });
    },
    as_float: function() {
        if (this.type.equals(Shade.Types.float_t))
            return this;
        var parent = this;
        return Shade._create_concrete_value_exp({
            parents: [parent],
            type: Shade.Types.float_t,
            value: function() { return "float(" + this.parents[0].evaluate() + ")"; },
            is_constant: function() { return parent.is_constant(); },
            constant_value: function() {
                var v = parent.constant_value();
                return Number(v);
            },
            expression_type: "cast(float)"
        });
    },
    swizzle: function(pattern) {
        function swizzle_pattern_to_indices(pattern) {
            function to_index(v) {
                switch (v.toLowerCase()) {
                case 'r': return 0;
                case 'g': return 1;
                case 'b': return 2;
                case 'a': return 3;
                case 'x': return 0;
                case 'y': return 1;
                case 'z': return 2;
                case 'w': return 3;
                case 's': return 0;
                case 't': return 1;
                case 'p': return 2;
                case 'q': return 3;
                default: throw "invalid swizzle pattern";
                }
            }
            var result = [];
            for (var i=0; i<pattern.length; ++i) {
                result.push(to_index(pattern[i]));
            }
            return result;
        }

        var parent = this;
        var indices = swizzle_pattern_to_indices(pattern);
        return Shade._create_concrete_exp( {
            parents: [parent],
            type: parent.type.swizzle(pattern),
            expression_type: "swizzle{" + pattern + "}",
            evaluate: function() { return this.parents[0].evaluate() + "." + pattern; },
            is_constant: Shade.memoize_on_field("_is_constant", function () {
                var that = this;
                return _.all(indices, function(i) {
                    return that.parents[0].element_is_constant(i);
                });
            }),
            constant_value: Shade.memoize_on_field("_constant_value", function() {
                if (this.type.is_pod()) {
                    return this.parents[0].element_constant_value(indices[0]);
                } else {
                    var that = this;
                    var ar = _.map(indices, function(index) {
                        return that.parents[0].element_constant_value(index);
                    });
                    var d = this.type.vec_dimension();
                    switch (d) {
                    case 2: return vec2.make(ar);
                    case 3: return vec3.make(ar);
                    case 4: return vec4.make(ar);
                    default:
                        throw "bad vec dimension " + d;
                    }
                }
            }),
            element: function(i) {
                return this.parents[0].element(indices[i]);
            },
            element_is_constant: Shade.memoize_on_field("_element_is_constant", function(i) {
                return this.parents[0].element_is_constant(indices[i]);
            }),
            element_constant_value: Shade.memoize_on_field("_element_constant_value", function(i) {
                return this.parents[0].element_constant_value(indices[i]);
            }),
            compile: function() {}
        });
    },
    at: function(index) {
        var parent = this;
        index = Shade.make(index);
        // this "works around" current constant index restrictions in webgl
        // look for it to get broken in the future as this hole is plugged.
        index._must_be_function_call = true;
        if (!index.type.equals(Shade.Types.float_t) &&
            !index.type.equals(Shade.Types.int_t)) {
            throw "at expects int or float, got '" +
                index.type.repr() + "' instead";
        }
        return Shade._create_concrete_exp( {
            parents: [parent, index],
            type: parent.type.array_base(),
            expression_type: "index",
            evaluate: function() {
                if (this.parents[1].type.is_integral()) {
                    return this.parents[0].evaluate() +
                        "[" + this.parents[1].evaluate() + "]";
                } else {
                    return this.parents[0].evaluate() +
                        "[int(" + this.parents[1].evaluate() + ")]";
                }
            },
            is_constant: function() {
                return (this.parents[0].is_constant() &&
                        this.parents[1].is_constant());
            },
            constant_value: Shade.memoize_on_field("_constant_value", function() {
                var a = this.parents[0].constant_value();
                if (facet_typeOf(a) === 'array') // this was a GLSL array of stuff
                    return a[this.parents[1].constant_value()];
                else { // this was a vec.
                    if (a._type === 'vector') {
                        return a[this.parents[1].constant_value()];
                    } else {
                        // FIXME: at constant_value for mats is broken.
                        //  Lift and use matrix_row from constant.js
                        throw "at constant_value for mats is currently broken";
                    }
                }
            }),
            // the reason for the (if x === this) checks here is that sometimes
            // the only appropriate description of an element() of an
            // opaque object (uniforms and attributes, notably) is an at() call.
            // This means that (this.parents[0].element(ix) === this) is
            // sometimes true, and we're stuck in an infinite loop.
            element: Shade.memoize_on_field("_element", function(i) {
                if (!this.parents[1].is_constant()) {
                    throw "at().element cannot be called with non-constant index";
                }
                var ix = this.parents[1].constant_value();
                var x = this.parents[0].element(ix);
                if (x === this) {
                    return x.at(i);
                } else
                    return x.element(i);
            }),
            element_is_constant: Shade.memoize_on_field("_element_is_constant", function(i) {
                if (!this.parents[1].is_constant()) {
                    return false;
                }
                var ix = this.parents[1].constant_value();
                var x = this.parents[0].element(ix);
                if (x === this) {
                    return false;
                } else
                    return x.element_is_constant(i);
            }),
            element_constant_value: Shade.memoize_on_field("_element_constant_value", function(i) {
                var ix = this.parents[1].constant_value();
                var x = this.parents[0].element(ix);
                if (x === this) {
                    throw "internal error: would have gone into an infinite loop here.";
                }
                return x.element_constant_value(i);
            }),
            compile: function() {}
        });
    },
    expression_type: "other",
    _type: "shade_expression",
    _attribute_buffers: [],
    _uniforms: [],
    attribute_buffers: function() {
        return _.flatten(this.sorted_sub_expressions().map(function(v) {
            return v._attribute_buffers;
        }));
    },
    uniforms: function() {
        return _.flatten(this.sorted_sub_expressions().map(function(v) {
            return v._uniforms;
        }));
    },

    // simple re-writing of shaders, useful for moving expressions
    // around, such as the things we move around when attributes are
    // referenced in fragment programs
    //
    // NB: it's easy to create bad expressions with these.
    //
    // The general rule is that types should be preserved (although
    // that might not *always* be the case)
    find_if: function(check) {
        return _.select(this.sorted_sub_expressions(), check);
    },
    replace_if: function(check, replacement) {
        var subexprs = this.sorted_sub_expressions();
        var replaced_pairs = [];
        function has_been_replaced(x) {
            return _.some(replaced_pairs, function(v) {
                return (x.guid === v[0].guid) && (v[0].guid !== v[1].guid); //_.isEqual(x, v[0]);
            });
        }
        function parent_replacement(x) {
            var r = _.select(replaced_pairs, function(v) {
                return (x.guid === v[0].guid) && (v[0].guid !== v[1].guid); //_.isEqual(x, v[0]);
            });
            if (r.length === 0)
                return x;
            else
                return r[0][1];
        }
        for (var i=0; i<subexprs.length; ++i) {
            var exp = subexprs[i];
            if (check(exp)) {
                replaced_pairs.push([exp, replacement(exp)]);
            } else if (_.some(exp.parents, has_been_replaced)) {
                var x = [exp, Shade._create(exp, {
                    parents: _.map(exp.parents, parent_replacement)
                })];
                replaced_pairs.push(x);
            } else {
                replaced_pairs.push([exp, exp]);
            }
        }
        var result = replaced_pairs[replaced_pairs.length-1][1];
        return result;
    }
};
Shade._create_concrete_exp = Shade._create_concrete(Shade.Exp, ["parents", "compile", "type"]);
<|endoftext|>


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

// note that month indices are zero-based

module.exports.DATA_START_YEAR = 2012;
module.exports.DATA_START_MONTH = 0;

module.exports.DATA_END_YEAR = 2016;
module.exports.DATA_END_MONTH = 9;

module.exports.DATA_END_MOMENT = moment([
  module.exports.DATA_END_YEAR,
  module.exports.DATA_END_MONTH]).endOf('month');

module.exports.ASYLUM_APPLICANTS_DATA_UPDATED_MOMENT = moment([2016, 11, 15]);

module.exports.disableLabels = ['BIH', 'MKD', 'ALB', 'LUX', 'MNE', 'ARM', 'AZE', 'LBN'];

module.exports.labelShowBreakPoint = 992;
<commit_msg>Correct updated at date<commit_after>
var moment = require('moment');

// note that month indices are zero-based

module.exports.DATA_START_YEAR = 2012;
module.exports.DATA_START_MONTH = 0;

module.exports.DATA_END_YEAR = 2016;
module.exports.DATA_END_MONTH = 9;

module.exports.DATA_END_MOMENT = moment([
  module.exports.DATA_END_YEAR,
  module.exports.DATA_END_MONTH]).endOf('month');

module.exports.ASYLUM_APPLICANTS_DATA_UPDATED_MOMENT = moment([2016, 11, 26]);

module.exports.disableLabels = ['BIH', 'MKD', 'ALB', 'LUX', 'MNE', 'ARM', 'AZE', 'LBN'];

module.exports.labelShowBreakPoint = 992;
<|endoftext|>