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

var request = require('superagent');

module.exports = function(config){
    for(var param in ({user:1, apiKey:1, room:1}))
        if(!config.hasOwnProperty(param))
            throw 'Missing config parameter: ' + param;

    var DEFAULTS = {
        pingInterval: 2e3,
        pingTimeout: 30,
        autoReconnect: true,
        reconnectInterval: 30e3,
        debug: false
    };
    for(var param in DEFAULTS)
        if(!config.hasOwnProperty(param))
            config[param] = DEFAULTS[param];
    if(config.pingInterval < 2e3)
        throw 'Don\'t be a jerk.';

    /* private variables of interest */
    var apiVersion = 1,
    baseURL = 'http://www.icanhazchat.com/api.ashx?v=' + apiVersion;
    isConnected = false,
    isModded = false,
    keyedURL = '',
    cammers = {},
    listeners = {
        connect: [],
        disconnect: [],
        ping:[],
        message: [],
        pm: [],
        whisper: [],
        userJoin: [],
        userKick: [],
        userQuit: [],
        userCamUp: [],
        userCamDown: [],
        error: []
    },
    trigger = function(type, data){
        listeners[type].forEach(function(listener){
            listener.call(chain, data);
        });
    },
    error = function(message){
        if(listeners.error.length){
            trigger('error', {
                message: message
            });
        } else
            throw message;
    },
    makeRequest = function(params, success, fail){
        var url = isConnected ? keyedURL : baseURL;
        for(var param in params)
            url += '&' + param + '=' + params[param];
        request.get(url).end(function(response){
            if(!response.ok){
                error('Request error: ' + response.text);
                fail && fail.call(chain);
                return;
            }
            if(config.debug)
                console.log(url + '\n' + response.text + '\n');
            var lines = response.text.split(/\n/),
                isOK = lines.shift();
            if(isOK != 'OK'){
                fail && fail.call(chain, isOK);
                return;
            }
            success && success.call(chain, lines);
            parseResponse.call(chain, lines);
       });
    },
    pingFailures = 0,
    intPing = -1,
    disconnect = function(){
        isConnected = false;
        clearInterval(intPing);
        keyedURL = '';
        if(config.autoReconnect){
            (function reconnect(){
                chain.connect(null, function(){
                    setTimeout(reconnect, reconnectInterval)
                });
            })();
        }
    },
    ping = function(){
        makeRequest({
            a: 'recv'
        }, function(){
            pingFailures = 0;
            trigger('ping');
        }, function(){
            if(++pingFailures == config.pingTimeout)
                disconnect();
        });
    },
    parseResponse = function(lines){
        lines.forEach(function(line){
            var r = /^\[([^\]]+)\]/,
            eventType = (line.match(/^\[([^\]]+)\]/) || [, 'message'])[1];
            line = line.replace(r, '');
            switch(eventType){
                case 'message':
                    var parse = line.match(/^.+\|(.*?)(\:)?\s(.+)/);
                    if(parse){
                        username = parse[1],
                        message = parse[3];
                        if(username){
                            trigger('message', {
                                username: username,
                                message: message,
                                emote: !!parse[2]
                            });
                        } else {
                            var parseMsg;
                            if(parseMsg = message.match(/(.+?) has kicked (.+?) from the room/)){
                                trigger('userKick', {
                                    username: parseMsg[2],
                                    kickedBy: parseMsg[1]
                                });
                            }
                        }
                    }
                    break;

                case 'msg':
                    var parse = line.match(/^.+\|(.+?)\|.+?\|(.+)/);
                    trigger('whisper', {
                        username: parse[1],
                        message: parse[2]
                    });
                    break;

                case 'priv':
                    var parse = line.match(/^.+\|(.+?)\|(.+)/);
                    trigger('pm', {
                        username: parse[1],
                        message: parse[2]
                    });
                    break;

                case 'hi':
                    var rMod = /\*$/,
                        username = line.replace(rMod, '');
                    if(username != config.user){
                        trigger('userJoin',{
                            username: username,
                            mod: rMod.test(line)
                        });
                    }
                    break;

                case 'bye':
                    trigger('userQuit', {
                        username: line
                    });
                    break;

                case 'c+':
                    var parse = line.match(/1(.{12})(.+?)\./),
                    hash = parse[1],
                    username = parse[2];
                    cammers[hash] =  username;
                    trigger('userCamUp', {
                        username: username
                    });
                    break;

                case 'c-':
                    var username = cammers[line] || '';
                    delete cammers[line];
                    trigger('userCamDown', {
                        username: username
                    });
                    break;

                case '':
                    disconnect();
                    trigger('disconnect');
                    break;
            }
        });
    },
    chain = {
        /* command functions */

        connect: function(success, fail){
            if(isConnected)
                error('Already connected.');
            else {
                makeRequest({
                    u: config.user,
                    p: config.apiKey,
                    a: 'join',
                    w: config.room
                }, function(data){
                    isConnected = true;
                    keyedURL = baseURL + '&k=' + data[0];
                    intPing = setInterval(ping, config.pingInterval);
                    success && success.call(chain, data);
                    trigger('connect');
                }, function(data){
                    fail && fail.call(chain, data);
                });
            }
            return this;
        },

        send: function(message, success, fail){
            if(!message)
                error('No message.');
            else if(!isConnected)
                error('Not connected.');
            else {
                makeRequest({
                    a: 'send',
                    w: message
                }, success, fail);
            }
            return this;
        },

        whisper: function(username, message, success, fail){
            return this.send('/msg ' + username + ' ' + message, success, fail);
        },

        pm: function(username, message, success, fail){
            return this.send('/privmsg ' + username + ' ' + message, success, fail);
        },

        /* getter functions */
        /* I'll build these later
        getUsers: function(success, fail){
            return this;
        },

        getIdlers: function(success, fail){
            return this;
        },

        getMods: function(success, fail){
            return this;
        },

        getCammers: function(success, fail){
            return this;
        },
        */

        /* event listener functions */

        on: function(evt, handler){
            evt.split(' ').forEach(function(evt){
                if(!listeners[evt])
                    error('Invalid event type: ' + evt);
                else if(typeof handler != 'function')
                    error('Event handler must be a function.');
                else
                    listeners[evt].push(handler);
            });
            return this;
        },

        off: function(evt, handler){
            evt.split(' ').forEach(function(evt){
                if(!listeners[evt])
                    for(var evt in listeners)
                        listeners[evt] = [];
                else if(!handler)
                    listeners[evt] = [];
                else
                    listeners[evt] = listeners[evt].filter(function(listener){
                        return listener !== handler;
                    });
            });
            return this;
        }
    };

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

var request = require('superagent');

module.exports = function(config){
    for(var param in ({user:1, apiKey:1, room:1}))
        if(!config.hasOwnProperty(param))
            throw 'Missing config parameter: ' + param;

    var DEFAULTS = {
        pingInterval: 2e3,
        pingTimeout: 30,
        autoReconnect: true,
        reconnectInterval: 30e3,
        debug: false
    };
    for(var param in DEFAULTS)
        if(!config.hasOwnProperty(param))
            config[param] = DEFAULTS[param];
    if(config.pingInterval < 2e3)
        throw 'Don\'t be a jerk.';

    /* private variables of interest */
    var apiVersion = 1,
    baseURL = 'http://www.icanhazchat.com/api.ashx?v=' + apiVersion,
    isConnected = false,
    keyedURL = '',
    cammers = {},
    listeners = {
        connect: [],
        disconnect: [],
        ping:[],
        message: [],
        pm: [],
        whisper: [],
        userJoin: [],
        userKick: [],
        userQuit: [],
        userCamUp: [],
        userCamDown: [],
        error: []
    },
    trigger = function(type, data){
        var modifiedData = {
            eventType: type
        };
        for(var x in data)
            if(x != 'eventType')
                modifiedData[x] = data[x];
        (listeners[type] || []).forEach(function(listener){
            listener.call(chain, modifiedData);
        });
    },
    error = function(message){
        if(listeners.error.length){
            trigger('error', {
                message: message
            });
        } else
            throw message;
    },
    makeRequest = function(params, success, fail){
        var url = isConnected ? keyedURL : baseURL;
        for(var param in params)
            url += '&' + param + '=' + params[param];
        request.get(url).end(function(response){
            if(!response.ok){
                error('Request error: ' + response.text);
                fail && fail.call(chain);
                return;
            }
            if(config.debug)
                console.log(url + '\n' + response.text + '\n');
            var lines = response.text.split(/\n/),
                isOK = lines.shift();
            if(isOK != 'OK'){
                fail && fail.call(chain, isOK);
                return;
            }
            success && success.call(chain, lines);
            parseResponse.call(chain, lines);
       });
    },
    pingFailures = 0,
    intPing = -1,
    disconnect = function(){
        isConnected = false;
        clearInterval(intPing);
        keyedURL = '';
        if(config.autoReconnect){
            (function reconnect(){
                chain.connect(null, function(){
                    setTimeout(reconnect, reconnectInterval)
                });
            })();
        }
    },
    ping = function(){
        makeRequest({
            a: 'recv'
        }, function(){
            pingFailures = 0;
            trigger('ping');
        }, function(){
            if(++pingFailures == config.pingTimeout)
                disconnect();
        });
    },
    parseResponse = function(lines){
        lines.forEach(function(line){
            var r = /^\[([^\]]+)\]/,
            eventType = (line.match(/^\[([^\]]+)\]/) || [, 'message'])[1];
            line = line.replace(r, '');
            switch(eventType){
                case 'message':
                    var parse = line.match(/^.+\|(.*?)(\:)?\s(.+)/);
                    if(parse){
                        username = parse[1],
                        message = parse[3];
                        if(username){
                            trigger('message', {
                                username: username,
                                message: message,
                                emote: !!parse[2]
                            });
                        } else {
                            var parseMsg;
                            if(parseMsg = message.match(/(.+?) has kicked (.+?) from the room/)){
                                trigger('userKick', {
                                    username: parseMsg[2],
                                    kickedBy: parseMsg[1]
                                });
                            }
                        }
                    }
                    break;

                case 'msg':
                    var parse = line.match(/^.+\|(.+?)\|.+?\|(.+)/);
                    trigger('whisper', {
                        username: parse[1],
                        message: parse[2]
                    });
                    break;

                case 'priv':
                    var parse = line.match(/^.+\|(.+?)\|(.+)/);
                    trigger('pm', {
                        username: parse[1],
                        message: parse[2]
                    });
                    break;

                case 'hi':
                    var rMod = /\*$/,
                        username = line.replace(rMod, '');
                    if(username != config.user){
                        trigger('userJoin',{
                            username: username,
                            mod: rMod.test(line)
                        });
                    }
                    break;

                case 'bye':
                    trigger('userQuit', {
                        username: line
                    });
                    break;

                case 'c+':
                    var parse = line.match(/1(.{12})(.+?)\./),
                    hash = parse[1],
                    username = parse[2];
                    cammers[hash] =  username;
                    trigger('userCamUp', {
                        username: username
                    });
                    break;

                case 'c-':
                    var username = cammers[line] || '';
                    delete cammers[line];
                    trigger('userCamDown', {
                        username: username
                    });
                    break;

                case '':
                    disconnect();
                    trigger('disconnect');
                    break;
            }
        });
    },
    chain = {
        /* command functions */

        connect: function(success, fail){
            if(isConnected)
                error('Already connected.');
            else {
                makeRequest({
                    u: config.user,
                    p: config.apiKey,
                    a: 'join',
                    w: config.room
                }, function(data){
                    isConnected = true;
                    keyedURL = baseURL + '&k=' + data[0];
                    intPing = setInterval(ping, config.pingInterval);
                    success && success.call(chain, data);
                    trigger('connect');
                }, function(data){
                    fail && fail.call(chain, data);
                });
            }
            return this;
        },

        send: function(message, success, fail){
            if(!message)
                error('No message.');
            else if(!isConnected)
                error('Not connected.');
            else {
                makeRequest({
                    a: 'send',
                    w: message
                }, success, fail);
            }
            return this;
        },

        whisper: function(username, message, success, fail){
            return this.send('/msg ' + username + ' ' + message, success, fail);
        },

        pm: function(username, message, success, fail){
            return this.send('/privmsg ' + username + ' ' + message, success, fail);
        },

        /* getter functions */
        /* I'll build these later
        getUsers: function(success, fail){
            return this;
        },

        getIdlers: function(success, fail){
            return this;
        },

        getMods: function(success, fail){
            return this;
        },

        getCammers: function(success, fail){
            return this;
        },
        */

        /* event listener functions */

        on: function(evt, handler){
            evt.split(' ').forEach(function(evt){
                if(!listeners[evt])
                    error('Invalid event type: ' + evt);
                else if(typeof handler != 'function')
                    error('Event handler must be a function.');
                else
                    listeners[evt].push(handler);
            });
            return this;
        },

        off: function(evt, handler){
            evt.split(' ').forEach(function(evt){
                if(!listeners[evt])
                    for(var evt in listeners)
                        listeners[evt] = [];
                else if(!handler)
                    listeners[evt] = [];
                else
                    listeners[evt] = listeners[evt].filter(function(listener){
                        return listener !== handler;
                    });
            });
            return this;
        }
    };

    return chain;
};<|endoftext|>


<commit_before>import PlUploader from 'ember-plupload/components/pl-uploader';
import config from '../config/environment';

var BASE_URL = config.PLUPLOAD_BASE_URL;

if (BASE_URL == null) {
  if (config.baseURL.slice(-1) === '/') {
    BASE_URL = config.baseURL + 'assets/';
  } else {
    BASE_URL = config.baseURL + '/assets/';
  }
}

export default PlUploader.extend({
  BASE_URL: BASE_URL
});
<commit_msg>fix #73 by removing baseURL, since it's deprecated in Ember 2.x<commit_after>import PlUploader from 'ember-plupload/components/pl-uploader';
import config from '../config/environment';

export default PlUploader.extend({
  BASE_URL: config.PLUPLOAD_BASE_URL
});
<|endoftext|>


<commit_before>import Ember from "ember";

export default Ember.Component.extend({
	tagName: '',
	cy: undefined,
	root_node: undefined,
	cytoscape_data: function() {
		var ret = {
			nodes: [],
			edges: []
		};

		var first = true;
		var self = this;
		this.get("model").forEach(function(node) {
			if(first) {
				first = false;
				self.set("root_node", node.get("id"));

				ret["nodes"].push({
					data: {
						id: node.get("id"),
						name: node.get("title"),
						tooltip: node.get("intro"),
						node_type: node.get("category").get("type")
					},
					position: {
						//x: node.get("position").get("x"),
						y: 0
					}
				});
			} else {
				ret["nodes"].push({
					data: {
						id: node.get("id"),
						name: node.get("title"),
						tooltip: node.get("intro"),
						node_type: node.get("category").get("type")
					}/*,
					position: {
						x: node.get("position").get("x"),
						y: node.get("position").get("y")
					}*/
				});
			}
			node.get("node_parent").forEach(function(parent) {
				ret["edges"].push({
					data: {
						source: parent.get("id"),
						target: node.get("id")
					}
				});
			});
		});

		return ret;
	}.property("model"),
	didInsertElement: function() {
		this._super();
		Ember.run.scheduleOnce('afterRender', this, function(){
			var self = this;
			Ember.$(window).on("window:resize", function() {
		  		self.reposition_graph();
		  	});
			this.reset_graph_panel();
			this.set("cy", cytoscape({
		        container: Ember.$('#cy')[0],
		        elements: this.get("cytoscape_data"),
		        zoom: 1,
		        pan: { x: 0, y: 0 },
		        zoomingEnabled: false,
		        userZoomingEnabled: false,
		        panningEnabled: true,
		        userPanningEnabled: false,
		        autoungrabify: false,
		        ready: function() {
		        	console.log("Graph is ready!");
		        	self.reset_graph_panel();
		        	self.style_graph();
		        	self.reposition_graph();
		        	self.setup_graph_actions();
		        }
		    }));
		});
	},
	reset_graph_panel: function() {
		var graphPanel = document.getElementById("cy");

		graphPanel.style.width = "100%";
		graphPanel.style.height = 800 + "px";
	},
	loadGraph: function(file) {
        var json = null;
        Ember.$.ajax({
            'async': false,
            'global': false,
            'url': file,
            'dataType': 'json',
            'success': function (data) {
                json = data;
            }
        });
        return json;
    },
    reposition_graph: function() {
    	var self = this;
    	this.get("cy").autolock(false);
    	var width = Ember.$("#cy").width();
    	var height = 800;
    	var options = {
			name: 'breadthfirst',
			roots: [self.get("root_node")],
			boundingBox: {
				x1: 0,
				y1: 0,
				w: width,
				h: height
			},
			padding: 5,
			spacingFactor: 1

			/*fit: true, // whether to fit the viewport to the graph
			directed: false, // whether the tree is directed downwards (or edges can point in any direction if false)
			padding: 30, // padding on fit
			circle: false, // put depths in concentric circles if true, put depths top down if false
			spacingFactor: 1.75, // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)
			boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
			avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space
			roots: undefined, // the roots of the trees
			maximalAdjustments: 0, // how many times to try to position the nodes in a maximal way (i.e. no backtracking)
			animate: false, // whether to transition the node positions
			animationDuration: 500, // duration of animation in ms if enabled
			ready: undefined, // callback on layoutready
			stop: undefined // callback on layoutstop*/
		};
		this.get("cy").layout(options);
		this.get("cy").center();
		options.boundingBox.height = this.get("cy").height();
		//this.get("cy").layout(options);
		this.get("cy").autolock(true);
    },
    style_graph: function()  {
    	this.get("cy").style()
            .selector('node')
              .css({
                'width': '125px',
                'height': '125px',
								'background-width': '103px',
              	'background-height': '103px',
								'background-color': 'white',
								'background-opacity': '0',

								'color': 'white',
								'font-size': '14',
								'content': 'data(name)',
        				'text-valign': 'center',
								'text-transform': 'uppercase',
								'text-wrap': 'wrap',
								'text-max-width': '90px',
              })
            .selector('node[node_type = "uvod"]')
              .css({
								'background-image': 'img/nodes/node-start.svg',
								'content': '',
              })
            .selector('node[node_type = "small_p"]')
              .css({
              	'background-image': 'img/nodes/base/node-blue.svg',
              })
            .selector('node[node_type = "small_t"]')
              .css({
              	'background-image': 'img/nodes/base/node-orange.svg',
              })
            .selector('node[node_type = "big"]')
              .css({
              	'background-image': 'img/nodes/base/node-red.svg',
								'background-width': '118px',
              	'background-height': '118px',
              })
            .selector('node[node_type = "bonus"]')
              .css({
              	'background-image': 'img/nodes/base/node-bronze-unknown.svg',
								'content': '',
              })
						.selector('node[node_type = "small_t_p"]')
              .css({
              	'background-image': 'img/nodes/base/node-orange-blue.svg',
              })
						.selector('node[node_type = "small_a"]')
              .css({
              	'background-image': 'img/nodes/base/node-green.svg',
              })
						.selector('node[node_type = "small_a_p"]')
	            .css({
	            	'background-image': 'img/nodes/base/node-green-blue.svg',
	            })
            .selector('edge')
              .css({
                'width': 6,
								'border-color': '#39393a',
                'target-arrow-shape': 'triangle',
                'opacity': 1
              })
            .selector(':selected')
              .css({
                'background-color': 'orange',
                'opacity': 1
              })
            .selector('.faded')
              .css({
                'opacity': 0.0,
                'text-opacity': 0
        	}).update();
        //this.get("cy").style(style);
    },
    setup_graph_actions: function() {
    	var self = this;

    	this.get("cy").on('mousedown','node', function(event){
			var target = event.cyTarget;
	        var id = target.data("id");
	        self.sendAction('assign', id);
		});

		this.get("cy").on('mouseover','node', function(event){
	        /*var target = event.cyTarget;
	        var id = target.data("id");
	        var name = target.data("name");
	        var text = target.data("tooltip") + " Pro detaily podrž pravé tlačítko."; //TODO formatovanie textu

	        var x=event.cyPosition.x;
	        var y=event.cyPosition.y;
	        self.get("cy").$('#' + id).qtip({
	            content: {
	                title: name,
	                text: text
	            },
	            show: {
	                event: false,
	                ready: true,
	                effect:false
	            },
	            position: {
	                my: 'bottom center',
	                at: 'top center',
	                target: [x+3, y+3],
	                adjust: {x:7,y:7}
	            },
	            hide: {
	                fixed: true,
	                event: false,
	                inactive: 1000
	            },
	            style: {
	                classes: 'qtip-bootstrap',
	                tip: {
	                    width: 16,
	                    height: 8
	                }
	            }
	        });*/
	    });
    }
});
<commit_msg>Reposition graph<commit_after>import Ember from "ember";

export default Ember.Component.extend({
	tagName: '',
	cy: undefined,
	root_node: undefined,
	cytoscape_data: function() {
		var ret = {
			nodes: [],
			edges: []
		};

		var first = true;
		var self = this;
		this.get("model").forEach(function(node) {
			if(first) {
				first = false;
				self.set("root_node", node.get("id"));

				ret["nodes"].push({
					data: {
						id: node.get("id"),
						name: node.get("title"),
						tooltip: node.get("intro"),
						node_type: node.get("category").get("type")
					},
					position: {
						//x: node.get("position").get("x"),
						y: 0
					}
				});
			} else {
				ret["nodes"].push({
					data: {
						id: node.get("id"),
						name: node.get("title"),
						tooltip: node.get("intro"),
						node_type: node.get("category").get("type")
					}/*,
					position: {
						x: node.get("position").get("x"),
						y: node.get("position").get("y")
					}*/
				});
			}
			node.get("node_parent").forEach(function(parent) {
				ret["edges"].push({
					data: {
						source: parent.get("id"),
						target: node.get("id")
					}
				});
			});
		});

		return ret;
	}.property("model"),
	didInsertElement: function() {
		this._super();
		Ember.run.scheduleOnce('afterRender', this, function(){
			var self = this;
			Ember.$(window).on("window:resize", function() {
		  		self.reposition_graph();
		  	});
			this.reset_graph_panel();
			this.set("cy", cytoscape({
		        container: Ember.$('#cy')[0],
		        elements: this.get("cytoscape_data"),
		        zoom: 1,
		        pan: { x: 0, y: 0 },
		        zoomingEnabled: false,
		        userZoomingEnabled: false,
		        panningEnabled: true,
		        userPanningEnabled: false,
		        autoungrabify: false,
		        ready: function() {
		        	console.log("Graph is ready!");
		        	self.reset_graph_panel();
		        	self.style_graph();
		        	self.reposition_graph();
		        	self.setup_graph_actions();
		        }
		    }));
		});
	},
	reset_graph_panel: function() {
		var graphPanel = document.getElementById("cy");

		graphPanel.style.width = "100%";
		graphPanel.style.height = 1300 + "px";
	},
	loadGraph: function(file) {
        var json = null;
        Ember.$.ajax({
            'async': false,
            'global': false,
            'url': file,
            'dataType': 'json',
            'success': function (data) {
                json = data;
            }
        });
        return json;
    },
    reposition_graph: function() {
    	var self = this;
    	this.get("cy").autolock(false);
    	var width = Ember.$("#cy").width();
    	var height = 1300;
    	var options = {
			name: 'breadthfirst',
			roots: [self.get("root_node")],
			boundingBox: {
				x1: 0,
				y1: 0,
				w: width,
				h: height
			},
			padding: 5,
			spacingFactor: 1

			/*fit: true, // whether to fit the viewport to the graph
			directed: false, // whether the tree is directed downwards (or edges can point in any direction if false)
			padding: 30, // padding on fit
			circle: false, // put depths in concentric circles if true, put depths top down if false
			spacingFactor: 1.75, // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)
			boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
			avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space
			roots: undefined, // the roots of the trees
			maximalAdjustments: 0, // how many times to try to position the nodes in a maximal way (i.e. no backtracking)
			animate: false, // whether to transition the node positions
			animationDuration: 500, // duration of animation in ms if enabled
			ready: undefined, // callback on layoutready
			stop: undefined // callback on layoutstop*/
		};
		this.get("cy").layout(options);
		this.get("cy").center();
		options.boundingBox.height = this.get("cy").height();
		//this.get("cy").layout(options);
		this.get("cy").autolock(true);
    },
    style_graph: function()  {
    	this.get("cy").style()
            .selector('node')
              .css({
                'width': '125px',
                'height': '125px',
								'background-width': '103px',
              	'background-height': '103px',
								'background-color': 'white',
								'background-opacity': '0',

								'color': 'white',
								'font-size': '14',
								'content': 'data(name)',
        				'text-valign': 'center',
								'text-transform': 'uppercase',
								'text-wrap': 'wrap',
								'text-max-width': '90px',
              })
            .selector('node[node_type = "uvod"]')
              .css({
								'background-image': 'img/nodes/node-start.svg',
								'content': '',
              })
            .selector('node[node_type = "small_p"]')
              .css({
              	'background-image': 'img/nodes/base/node-blue.svg',
              })
            .selector('node[node_type = "small_t"]')
              .css({
              	'background-image': 'img/nodes/base/node-orange.svg',
              })
            .selector('node[node_type = "big"]')
              .css({
              	'background-image': 'img/nodes/base/node-red.svg',
								'background-width': '118px',
              	'background-height': '118px',
              })
            .selector('node[node_type = "bonus"]')
              .css({
              	'background-image': 'img/nodes/base/node-bronze-unknown.svg',
								'content': '',
              })
						.selector('node[node_type = "small_t_p"]')
              .css({
              	'background-image': 'img/nodes/base/node-orange-blue.svg',
              })
						.selector('node[node_type = "small_a"]')
              .css({
              	'background-image': 'img/nodes/base/node-green.svg',
              })
						.selector('node[node_type = "small_a_p"]')
	            .css({
	            	'background-image': 'img/nodes/base/node-green-blue.svg',
	            })
            .selector('edge')
              .css({
                'width': 6,
								'border-color': '#39393a',
                'target-arrow-shape': 'triangle',
                'opacity': 1
              })
            .selector(':selected')
              .css({
                'background-color': 'orange',
                'opacity': 1
              })
            .selector('.faded')
              .css({
                'opacity': 0.0,
                'text-opacity': 0
        	}).update();
        //this.get("cy").style(style);
    },
    setup_graph_actions: function() {
    	var self = this;

    	this.get("cy").on('mousedown','node', function(event){
			var target = event.cyTarget;
	        var id = target.data("id");
	        self.sendAction('assign', id);
		});

		this.get("cy").on('mouseover','node', function(event){
	        /*var target = event.cyTarget;
	        var id = target.data("id");
	        var name = target.data("name");
	        var text = target.data("tooltip") + " Pro detaily podrž pravé tlačítko."; //TODO formatovanie textu

	        var x=event.cyPosition.x;
	        var y=event.cyPosition.y;
	        self.get("cy").$('#' + id).qtip({
	            content: {
	                title: name,
	                text: text
	            },
	            show: {
	                event: false,
	                ready: true,
	                effect:false
	            },
	            position: {
	                my: 'bottom center',
	                at: 'top center',
	                target: [x+3, y+3],
	                adjust: {x:7,y:7}
	            },
	            hide: {
	                fixed: true,
	                event: false,
	                inactive: 1000
	            },
	            style: {
	                classes: 'qtip-bootstrap',
	                tip: {
	                    width: 16,
	                    height: 8
	                }
	            }
	        });*/
	    });
    }
});
<|endoftext|>


<commit_before>angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, $interpolate, assetsService, angularHelper, notificationsService) {

    //$scope.model.value = "";
    //set default value of the model
    //this works by checking to see if there is a model; then cascades to the default model then to an empty fieldset

    var form = angularHelper.getCurrentForm($scope);

    $scope.model.config = $scope.model.config.archetypeConfig;

    $scope.model.value = $scope.model.value || { fieldsets: [getEmptyRenderFieldset($scope.model.config.fieldsets[0])] };

    //ini
    $scope.archetypeRenderModel = {};
    initArchetypeRenderModel();

    //helper to get $eval the labelTemplate
    $scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) {
        var fieldset = $scope.archetypeRenderModel.fieldsets[fieldsetIndex];
        var template = fieldsetConfigModel.labelTemplate;
        var rgx = /{{(.*?)}}*/g;
        var results;
        var parsedTemplate = template;

        while ((results = rgx.exec(template)) !== null) {
            var propertyAlias = results[1];
            var propertyValue = $scope.getPropertyValueByAlias(fieldset, propertyAlias);
            parsedTemplate = parsedTemplate.replace(results[0], propertyValue);
        }

        return parsedTemplate;
    };

    /* add/remove/sort */

    //defines the options for the jquery sortable
    //i used an ng-model="archetypeRenderModel" so the sort updates the right model
    $scope.sortableOptions = {
        axis: 'y',
        cursor: "move",
        handle: ".handle",
        update: function (ev, ui) {

        },
        stop: function (ev, ui) {

        }
    };

    //handles a fieldset add
    $scope.addRow = function (fieldsetAlias, $index) {
        if ($scope.canAdd())
        {
            if ($scope.model.config.fieldsets)
            {
                var newFieldset = getEmptyRenderFieldset($scope.getConfigFieldsetByAlias(fieldsetAlias));

                if (typeof $index != 'undefined')
                {
                    $scope.archetypeRenderModel.fieldsets.splice($index + 1, 0, newFieldset);
                }
                else
                {
                    $scope.archetypeRenderModel.fieldsets.push(newFieldset);
                }
            }
            newFieldset.collapse = true;
            $scope.focusFieldset(newFieldset);
        }
    }

    //rather than splice the archetypeRenderModel, we're hiding this and cleaning onFormSubmitting
    $scope.removeRow = function ($index) {
        if ($scope.canRemove()) {
            if (confirm('Are you sure you want to remove this?')) {
                $scope.archetypeRenderModel.fieldsets[$index].remove = true;
            }
        }
    }

    //helpers for determining if a user can do something
    $scope.canAdd = function ()
    {
        if ($scope.model.config.maxFieldsets)
        {
            return countVisible() < $scope.model.config.maxFieldsets;
        }

        return true;
    }

    //helper that returns if an item can be removed
    $scope.canRemove = function ()
    {
        return countVisible() > 1;
    }

    //helper that returns if an item can be sorted
    $scope.canSort = function ()
    {
        return countVisible() > 1;
    }

    //helper, ini the render model from the server (model.value)
    function initArchetypeRenderModel() {
        $scope.archetypeRenderModel = $scope.model.value;

        _.each($scope.archetypeRenderModel.fieldsets, function (fieldset)
        {
            fieldset.remove = false;
            fieldset.collapse = false;
            fieldset.isValid = true;
        });
    }

    //helper to get the correct fieldset from config
    $scope.getConfigFieldsetByAlias = function(alias) {
        return _.find($scope.model.config.fieldsets, function(fieldset){
            return fieldset.alias == alias;
        });
    }

    //helper to get a property by alias from a fieldset
    $scope.getPropertyValueByAlias = function(fieldset, propertyAlias) {
        var property = _.find(fieldset.properties, function(p) {
            return p.alias == propertyAlias;
        });
        return (typeof property !== 'undefined') ? property.value : '';
    };

    //helper for collapsing
    $scope.focusFieldset = function(fieldset){

        var iniState;

        if(fieldset)
        {
            iniState = fieldset.collapse;
        }

        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            if($scope.archetypeRenderModel.fieldsets.length == 1 && fieldset.remove == false)
            {
                fieldset.collapse = false;
                return;
            }

            fieldset.collapse = true;
        });

        if(iniState)
        {
            fieldset.collapse = !iniState;
        }
    }

    //ini
    $scope.focusFieldset();

    //helper returns valid JS or null
    function getValidJson(variable, json)
    {
        if(!json) return null;

        try {
            return eval("(" + json + ")");
        }
        catch (e) {
            console.log("There was an error while using 'eval' on " + variable);
            console.log(json);
            return null;
        }
    }

    //developerMode helpers
    $scope.archetypeRenderModel.toString = stringify;

    //encapsulate stringify (should be built into browsers, not sure of IE support)
    function stringify() {
        return JSON.stringify(this);
    }

    //watch for changes
    $scope.$watch('archetypeRenderModel', function (v) {
        if ($scope.model.config.developerMode) {
            console.log(v);
            if (typeof v === 'string') {
                $scope.archetypeRenderModel = JSON.parse(v);
                $scope.archetypeRenderModel.toString = stringify;
            }
        }
    });

    //helper to count what is visible
    function countVisible()
    {
        var count = 0;

        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            if (fieldset.remove == false) {
                count++;
            }
        });

        return count;
    }

    //helper to sync the model to the renderModel
    function syncModelToRenderModel()
    {
        $scope.model.value = { fieldsets: [] };

        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            if (typeof fieldset != 'function' && !fieldset.remove){

                //clone and clean
                var tempFieldset = JSON.parse(JSON.stringify(fieldset));
                delete tempFieldset.remove;
                delete tempFieldset.isValid;
                delete tempFieldset.collapse;

                _.each(tempFieldset.properties, function(property){
                    delete property.isValid;
                });

                $scope.model.value.fieldsets.push(tempFieldset);
            }
        });
    }

    //helper to add an empty fieldset
    function getEmptyRenderFieldset (fieldsetModel)
    {
        return eval("({ alias: '" + fieldsetModel.alias + "', remove: false, properties: []})");
    }

    //helper for validation
    function getValidation()
    {
        var validation = {}
        validation.isValid = true;
        validation.requiredAliases = [];
        validation.invalidProperties = [];

        //determine which fields are required
        _.each($scope.model.config.fieldsets, function(fieldset){
            _.each(fieldset.properties, function(property){
                if(property.required)
                {
                    validation.requiredAliases.push(property.alias);
                }
            });
        });

        //if nothing required; let's go
        if(validation.requiredAliases.length == 0)
        {
            return validation;
        }

        //otherwise we need to check the required aliases
        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            fieldset.isValid = true;

            _.each(fieldset.properties, function(property){
                property.isValid = true;

                //if a required field
                if(_.find(validation.requiredAliases, function(alias){ return alias == property.alias }))
                {
                    //TODO: do a better validation test
                    if(property.value == ""){
                        fieldset.isValid = false;
                        property.isValid = false;
                        validation.isValid = false;

                        validation.invalidProperties.push(property);
                    }
                }
            });
        });

        if($scope.model.config.developerMode == '1')
        {
            console.log(validation);
        }

        return validation;
    }

    $scope.getPropertyValidity = function(fieldsetIndex, alias)
    {
        if($scope.archetypeRenderModel.fieldsets[fieldsetIndex])
        {
            var property = _.find($scope.archetypeRenderModel.fieldsets[fieldsetIndex].properties, function(property){
                return property.alias == alias;
            });
        }

        return (typeof property == 'undefined') ? true : property.isValid;
    }

    //sync things up on save
    $scope.$on("formSubmitting", function (ev, args) {

        var validation = getValidation();

        if(!validation.isValid)
        {
            notificationsService.warning("Cannot Save Document", "The document could not be saved because of missing required fields.")
            form.$setValidity("archetypeError", false);
        }
        else
        {
            syncModelToRenderModel();
            form.$setValidity("archetypeError", true);
        }
    });

    //custom js
    if ($scope.model.config.customJsPath) {
        assetsService.loadJs($scope.model.config.customJsPath);
    }

    //archetype css
    assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css");

    //custom css
    if($scope.model.config.customCssPath)
    {
        assetsService.loadCss($scope.model.config.customCssPath);
    }
});
<commit_msg>Remove function no longer used<commit_after>angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, $interpolate, assetsService, angularHelper, notificationsService) {

    //$scope.model.value = "";
    //set default value of the model
    //this works by checking to see if there is a model; then cascades to the default model then to an empty fieldset

    var form = angularHelper.getCurrentForm($scope);

    $scope.model.config = $scope.model.config.archetypeConfig;

    $scope.model.value = $scope.model.value || { fieldsets: [getEmptyRenderFieldset($scope.model.config.fieldsets[0])] };

    //ini
    $scope.archetypeRenderModel = {};
    initArchetypeRenderModel();

    //helper to get $eval the labelTemplate
    $scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) {
        var fieldset = $scope.archetypeRenderModel.fieldsets[fieldsetIndex];
        var template = fieldsetConfigModel.labelTemplate;
        var rgx = /{{(.*?)}}*/g;
        var results;
        var parsedTemplate = template;

        while ((results = rgx.exec(template)) !== null) {
            var propertyAlias = results[1];
            var propertyValue = $scope.getPropertyValueByAlias(fieldset, propertyAlias);
            parsedTemplate = parsedTemplate.replace(results[0], propertyValue);
        }

        return parsedTemplate;
    };

    /* add/remove/sort */

    //defines the options for the jquery sortable
    //i used an ng-model="archetypeRenderModel" so the sort updates the right model
    $scope.sortableOptions = {
        axis: 'y',
        cursor: "move",
        handle: ".handle",
        update: function (ev, ui) {

        },
        stop: function (ev, ui) {

        }
    };

    //handles a fieldset add
    $scope.addRow = function (fieldsetAlias, $index) {
        if ($scope.canAdd())
        {
            if ($scope.model.config.fieldsets)
            {
                var newFieldset = getEmptyRenderFieldset($scope.getConfigFieldsetByAlias(fieldsetAlias));

                if (typeof $index != 'undefined')
                {
                    $scope.archetypeRenderModel.fieldsets.splice($index + 1, 0, newFieldset);
                }
                else
                {
                    $scope.archetypeRenderModel.fieldsets.push(newFieldset);
                }
            }
            newFieldset.collapse = true;
            $scope.focusFieldset(newFieldset);
        }
    }

    //rather than splice the archetypeRenderModel, we're hiding this and cleaning onFormSubmitting
    $scope.removeRow = function ($index) {
        if ($scope.canRemove()) {
            if (confirm('Are you sure you want to remove this?')) {
                $scope.archetypeRenderModel.fieldsets[$index].remove = true;
            }
        }
    }

    //helpers for determining if a user can do something
    $scope.canAdd = function ()
    {
        if ($scope.model.config.maxFieldsets)
        {
            return countVisible() < $scope.model.config.maxFieldsets;
        }

        return true;
    }

    //helper that returns if an item can be removed
    $scope.canRemove = function ()
    {
        return countVisible() > 1;
    }

    //helper that returns if an item can be sorted
    $scope.canSort = function ()
    {
        return countVisible() > 1;
    }

    //helper, ini the render model from the server (model.value)
    function initArchetypeRenderModel() {
        $scope.archetypeRenderModel = $scope.model.value;

        _.each($scope.archetypeRenderModel.fieldsets, function (fieldset)
        {
            fieldset.remove = false;
            fieldset.collapse = false;
            fieldset.isValid = true;
        });
    }

    //helper to get the correct fieldset from config
    $scope.getConfigFieldsetByAlias = function(alias) {
        return _.find($scope.model.config.fieldsets, function(fieldset){
            return fieldset.alias == alias;
        });
    }

    //helper to get a property by alias from a fieldset
    $scope.getPropertyValueByAlias = function(fieldset, propertyAlias) {
        var property = _.find(fieldset.properties, function(p) {
            return p.alias == propertyAlias;
        });
        return (typeof property !== 'undefined') ? property.value : '';
    };

    //helper for collapsing
    $scope.focusFieldset = function(fieldset){

        var iniState;

        if(fieldset)
        {
            iniState = fieldset.collapse;
        }

        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            if($scope.archetypeRenderModel.fieldsets.length == 1 && fieldset.remove == false)
            {
                fieldset.collapse = false;
                return;
            }

            fieldset.collapse = true;
        });

        if(iniState)
        {
            fieldset.collapse = !iniState;
        }
    }

    //ini
    $scope.focusFieldset();

    //developerMode helpers
    $scope.archetypeRenderModel.toString = stringify;

    //encapsulate stringify (should be built into browsers, not sure of IE support)
    function stringify() {
        return JSON.stringify(this);
    }

    //watch for changes
    $scope.$watch('archetypeRenderModel', function (v) {
        if ($scope.model.config.developerMode) {
            console.log(v);
            if (typeof v === 'string') {
                $scope.archetypeRenderModel = JSON.parse(v);
                $scope.archetypeRenderModel.toString = stringify;
            }
        }
    });

    //helper to count what is visible
    function countVisible()
    {
        var count = 0;

        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            if (fieldset.remove == false) {
                count++;
            }
        });

        return count;
    }

    //helper to sync the model to the renderModel
    function syncModelToRenderModel()
    {
        $scope.model.value = { fieldsets: [] };

        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            if (typeof fieldset != 'function' && !fieldset.remove){

                //clone and clean
                var tempFieldset = JSON.parse(JSON.stringify(fieldset));
                delete tempFieldset.remove;
                delete tempFieldset.isValid;
                delete tempFieldset.collapse;

                _.each(tempFieldset.properties, function(property){
                    delete property.isValid;
                });

                $scope.model.value.fieldsets.push(tempFieldset);
            }
        });
    }

    //helper to add an empty fieldset
    function getEmptyRenderFieldset (fieldsetModel)
    {
        return eval("({ alias: '" + fieldsetModel.alias + "', remove: false, properties: []})");
    }

    //helper for validation
    function getValidation()
    {
        var validation = {}
        validation.isValid = true;
        validation.requiredAliases = [];
        validation.invalidProperties = [];

        //determine which fields are required
        _.each($scope.model.config.fieldsets, function(fieldset){
            _.each(fieldset.properties, function(property){
                if(property.required)
                {
                    validation.requiredAliases.push(property.alias);
                }
            });
        });

        //if nothing required; let's go
        if(validation.requiredAliases.length == 0)
        {
            return validation;
        }

        //otherwise we need to check the required aliases
        _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
            fieldset.isValid = true;

            _.each(fieldset.properties, function(property){
                property.isValid = true;

                //if a required field
                if(_.find(validation.requiredAliases, function(alias){ return alias == property.alias }))
                {
                    //TODO: do a better validation test
                    if(property.value == ""){
                        fieldset.isValid = false;
                        property.isValid = false;
                        validation.isValid = false;

                        validation.invalidProperties.push(property);
                    }
                }
            });
        });

        if($scope.model.config.developerMode == '1')
        {
            console.log(validation);
        }

        return validation;
    }

    $scope.getPropertyValidity = function(fieldsetIndex, alias)
    {
        if($scope.archetypeRenderModel.fieldsets[fieldsetIndex])
        {
            var property = _.find($scope.archetypeRenderModel.fieldsets[fieldsetIndex].properties, function(property){
                return property.alias == alias;
            });
        }

        return (typeof property == 'undefined') ? true : property.isValid;
    }

    //sync things up on save
    $scope.$on("formSubmitting", function (ev, args) {

        var validation = getValidation();

        if(!validation.isValid)
        {
            notificationsService.warning("Cannot Save Document", "The document could not be saved because of missing required fields.")
            form.$setValidity("archetypeError", false);
        }
        else
        {
            syncModelToRenderModel();
            form.$setValidity("archetypeError", true);
        }
    });

    //custom js
    if ($scope.model.config.customJsPath) {
        assetsService.loadJs($scope.model.config.customJsPath);
    }

    //archetype css
    assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css");

    //custom css
    if($scope.model.config.customCssPath)
    {
        assetsService.loadCss($scope.model.config.customCssPath);
    }
});
<|endoftext|>


<commit_before>;(function(body, canvas, context, undefined){
    var Point = function(x, y){
	    this.x = x;
	    this.y = y;
    };
    Point.prototype.tr = function(dx, dy){
	    this.x += dx;
	    this.y += dy;
    };

    var Observable = function(){
	    this.o = {};
    };
    Observable.prototype.on = function(event, observer){
	    (this.o[event] = this.o[event] || []).push(observer);
    };
    Observable.prototype.e = function(event){
	    var args = Array.prototype.slice.call(arguments, 1);
	    (this.o[event] || []).forEach(function(observer){
	        observer.apply(undefined, args);
	    });
    };

    var Train = function(position, target){
	    Observable.call(this);
	    this.p =  position || new Point(0, 0);
        this._t = target || new Point(0, 0);
    };
    Train.prototype = Object.create(Observable.prototype);
    Train.prototype.move = function(){
        var x = this.p.x;
        var y = this.p.y;
        var dx = this._t.x - x;
        var dy = this._t.y - y;
	    this.p.tr(dx/100, dy/100);
	    this.e('moved', x, y);
    }
    Train.prototype.target = function(x, y){
        this._t = new Point(x, y);
    }

    function imageData(width, height, scale, color, data){
        scale = scale || 1;
        var canvas = document.createElement('canvas');
        canvas.width = width * scale;
        canvas.height = height * scale;
        var context = canvas.getContext('2d');
        context.beginPath();
        context.moveTo(0, 0);
        data.map(function(d){
            return { x: d[0] * scale, y: d[1] * scale }
        }).forEach(function(point){
            context.lineTo(point.x, point.y);
        });
        context.closePath();
        context.fillStyle = color;
        context.fill();
        return context.getImageData(0, 0, canvas.width, canvas.height);
    }

    function backgroundData(scale){
        return imageData(8, 6, scale, 'white', [
            [8, 0],
            [8, 6],
            [0, 6]
        ]);
    }

    function trainData(scale){
        return imageData(8, 6, scale, 'black', [
            [4, 0],
            [4, 3],
            [6, 3],
            [6, 1],
            [7, 1],
            [7, 3],
            [8, 3],
            [8, 6],
            [7, 6],
            [7, 5],
            [6, 5],
            [6, 6],
            [5, 6],
            [5, 5],
            [4, 5],
            [4, 6],
            [3, 6],
            [3, 5],
            [2, 5],
            [2, 6],
            [1, 6],
            [1, 1],
            [0, 1]
        ]);
    }

    var TrainView = function(model, canvas, context){
	    this.m = model;
	    this.c = context;
	    this.m.on('moved', this.update.bind(this));
        this.b = backgroundData(10);
        this.t = trainData(10);
	    this.update();
    };
    TrainView.prototype.update = function(x, y){
        x = x || 0;
        y = y || 0;
        this.c.putImageData(this.b, x, y);
        this.c.putImageData(this.t, this.m.p.x, this.m.p.y);
    };

    var train = new Train(new Point(50, 50), new Point(150, 100));
    new TrainView(train, canvas, context);

    function animate(){
	    train.move();
	    requestAnimationFrame(animate);
    }
    animate();

    canvas.addEventListener('mousemove', function(e){
        train.target(e.clientX, e.clientY);
    });
})(window.b, window.a, window.c);
<commit_msg>rename emitted events<commit_after>;(function(body, canvas, context, undefined){
    var Point = function(x, y){
	    this.x = x;
	    this.y = y;
    };
    Point.prototype.tr = function(dx, dy){
	    this.x += dx;
	    this.y += dy;
    };

    var Observable = function(){
	    this.o = {};
    };
    Observable.prototype.on = function(event, observer){
	    (this.o[event] = this.o[event] || []).push(observer);
    };
    Observable.prototype.e = function(event){
	    var args = Array.prototype.slice.call(arguments, 1);
	    (this.o[event] || []).forEach(function(observer){
	        observer.apply(undefined, args);
	    });
    };

    var Train = function(position, target){
	    Observable.call(this);
	    this.p =  position || new Point(0, 0);
        this._t = target || new Point(0, 0);
    };
    Train.prototype = Object.create(Observable.prototype);
    Train.prototype.move = function(){
        var x = this.p.x;
        var y = this.p.y;
        var dx = this._t.x - x;
        var dy = this._t.y - y;
	    this.p.tr(dx/100, dy/100);
	    this.e('m', x, y);
    }
    Train.prototype.target = function(x, y){
        this._t = new Point(x, y);
    }

    function imageData(width, height, scale, color, data){
        scale = scale || 1;
        var canvas = document.createElement('canvas');
        canvas.width = width * scale;
        canvas.height = height * scale;
        var context = canvas.getContext('2d');
        context.beginPath();
        context.moveTo(0, 0);
        data.map(function(d){
            return { x: d[0] * scale, y: d[1] * scale }
        }).forEach(function(point){
            context.lineTo(point.x, point.y);
        });
        context.closePath();
        context.fillStyle = color;
        context.fill();
        return context.getImageData(0, 0, canvas.width, canvas.height);
    }

    function backgroundData(scale){
        return imageData(8, 6, scale, 'white', [
            [8, 0],
            [8, 6],
            [0, 6]
        ]);
    }

    function trainData(scale){
        return imageData(8, 6, scale, 'black', [
            [4, 0],
            [4, 3],
            [6, 3],
            [6, 1],
            [7, 1],
            [7, 3],
            [8, 3],
            [8, 6],
            [7, 6],
            [7, 5],
            [6, 5],
            [6, 6],
            [5, 6],
            [5, 5],
            [4, 5],
            [4, 6],
            [3, 6],
            [3, 5],
            [2, 5],
            [2, 6],
            [1, 6],
            [1, 1],
            [0, 1]
        ]);
    }

    var TrainView = function(model, canvas, context){
	    this.m = model;
	    this.c = context;
	    this.m.on('m', this.update.bind(this));
        this.b = backgroundData(10);
        this.t = trainData(10);
	    this.update();
    };
    TrainView.prototype.update = function(x, y){
        x = x || 0;
        y = y || 0;
        this.c.putImageData(this.b, x, y);
        this.c.putImageData(this.t, this.m.p.x, this.m.p.y);
    };

    var train = new Train(new Point(50, 50), new Point(150, 100));
    new TrainView(train, canvas, context);

    function animate(){
	    train.move();
	    requestAnimationFrame(animate);
    }
    animate();

    canvas.addEventListener('mousemove', function(e){
        train.target(e.clientX, e.clientY);
    });
})(window.b, window.a, window.c);
<|endoftext|>


<commit_before>var events = require('events')
    , util = require('util');

try {
    LDAPConnection = require('./build/default/LDAP').LDAPConnection;
} catch(e) {
    LDAPConnection = require('./build/Release/LDAP').LDAPConnection;
}

//have the LDAPConnection class inherit properties like 'emit' from the EventEmitter class
LDAPConnection.prototype.__proto__ = events.EventEmitter.prototype;

function LDAPError(message, msgid) {
    this.name = 'LDAPError';
    this.message = message || 'Default Message';
    this.msgid = msgid;
}
LDAPError.prototype = new Error();
LDAPError.prototype.constructor = LDAPError;

var LDAP = function(opts) {
    var self = this;
    var binding = new LDAPConnection();
    var callbacks = {};
    var reconnecting = false;
    var syncopts = undefined;
    var cookie = undefined;
    var stats = {
        lateresponses: 0,
        reconnects: 0,
        ignored_reconnnects: 0,
        searches: 0,
        binds: 0,
        errors: 0,
        disconnects: 0,
        replays: 0,
        opens: 0,
        backoffs: 0,
        results: 0,
        searchresults: 0
    };

    if (!opts.uri) {
        throw new LDAPError('You must provide a URI');
    }

    opts.timeout = opts.timeout || 5000;
    opts.backoff = -1;
    opts.backoffmax = opts.backoffmax || 30000;

    self.BASE = 0;
    self.ONELEVEL = 1;
    self.SUBTREE = 2;
    self.SUBORDINATE = 3;
    self.DEFAULT = -1;

    self.LDAP_SYNC_PRESENT = 0;
    self.LDAP_SYNC_ADD = 1;
    self.LDAP_SYNC_MODIFY = 2;
    self.LDAP_SYNC_DELETE = 3;
    self.LDAP_SYNC_NEW_COOKIE = 4;

    self.LDAP_SYNC_CAPI_PRESENTS = 16;
    self.LDAP_SYNC_CAPI_DELETES = 19;
    self.LDAP_SYNC_CAPI_PRESENTS_IDSET = 48;
    self.LDAP_SYNC_CAPI_DELETES_IDSET = 51;
    self.LDAP_SYNC_CAPI_DONE = 80;

    function setCallback(msgid, replay, args, fn) {
        if (msgid >= 0) {
            if (typeof(fn) == 'function') {
                callbacks[msgid] =
                    {
                        fn: fn,
                        replay: replay,
                        args: args,
                        tm: setTimeout(function() {
                            delete callbacks[msgid];
                            fn(new LDAPError('Timeout', msgid));
                        }, opts.timeout)
                    }
            }
        } else {
            fn(new Error('LDAP Error', msgid));
        }
        return msgid;
    }

    function handleCallback(msgid, data) {
        if (callbacks[msgid]) {
            if (typeof callbacks[msgid].fn == 'function') {
                var thiscb = callbacks[msgid];
                delete callbacks[msgid];
                clearTimeout(thiscb.tm);
                thiscb.fn(undefined, data);
            }
        } else {
            stats.lateresponses++;
        }
    }

    function replayCallbacks() {
        for (var i in callbacks) {
            var thiscb = callbacks[i];
            delete (callbacks[i]);
            stats.replays++;
            thiscb.replay.apply(null, thiscb.args);
        }
    }

    function open(fn) {
        stats.opens++;
        binding.open(opts.uri, (opts.version || 3));
        return simpleBind(fn); // do an anon bind to get it all ready.
    }

    function backoff() {
        stats.backoffs++;
        opts.backoff++;
        if (opts.backoff > opts.backoffmax)
            opts.backoff = opts.backoffmax;
        return opts.backoff * 1000;
    }

    function reconnect() {
        reconnecting = true;
        binding.close();
        setTimeout(function() {
            var res = open(function(err) {
                if (err) {
                    reconnect();
                } else {
                    stats.reconnects++;
                    opts.backoff = -1;
                    replayCallbacks();
                    reconnecting = false;

                    if (syncopts) {
                        sync(syncopts);
                    }
                }
            });
        }, (backoff()));
    }

    function getStats() {
        stats.inflight = Object.keys(callbacks).length;
        return stats;
    }

    function state2str(state) {
        switch(state) {
        case self.LDAP_SYNC_PRESENT:
            return 'LDAP_SYNC_PRESENT';
        case self.LDAP_SYNC_ADD:
            return 'LDAP_SYNC_ADD';
        case self.LDAP_SYNC_MODIFY:
            return 'LDAP_SYNC_MODIFY';
        case self.LDAP_SYNC_DELETE:
            return 'LDAP_SYNC_DELETE';
        case self.LDAP_SYNC_NEW_COOKIE:
            return 'LDAP_SYNC_NEW_COOKIE';
        default:
            return 'UNKNOWN_STATE (' + state + ')';
        }
    }

    function phase2str(phase) {
        switch(phase) {
        case self.LDAP_SYNC_CAPI_DONE:
            return 'LDAP_SYNC_CAPI_DONE';
        case self.LDAP_SYNC_CAPI_PRESENTS:
            return 'LDAP_SYNC_CAPI_PRESENTS';
        case self.LDAP_SYNC_CAPI_DELETES:
            return 'LDAP_SYNC_CAPI_DELETES';
        case self.LDAP_SYNC_CAPI_PRESENTS_IDSET:
            return 'LDAP_SYNC_CAPI_PRESENTS_IDSET';
        case self.LDAP_SYNC_CAPI_DELETES_IDSET:
            return 'LDAP_SYNC_CAPI_DELETES_IDSET';
        default:
            return 'UNKNOWN_PHASE (' + phase + ')';
        }
    }

    function simpleBind(fn) {
        var msgid;
        if (!opts.binddn) {
            msgid = binding.simpleBind();
        } else {
            msgid = binding.simpleBind(opts.binddn, opts.password);
        }
        stats.binds++;
        return setCallback(msgid, simpleBind, arguments, fn);
    }

    function sync(s) {
        if (typeof s.syncresult == 'function') {
            binding.on('syncresult', s.syncresult);
        }
        if (typeof s.syncentry == 'function') {
            binding.on('syncentry', s.syncentry);
        }
        if (typeof s.syncidset == 'function') {
            binding.on('syncidset', s.syncidset);
        }
        if (typeof s.syncintermediate == 'function') {
            binding.on('syncintermediate', s.syncintermediate);
        }

        if (!s) {
            throw new Error('Options Required');
        }

        if (!s.base) {
            throw new Error('Base required');
        }

        if (!s.rid) {
            throw new Error('3-digit RID Required. Make one up.');
        }

        binding.sync(s.base,
                     s.scope?parseInt(s.scope):self.SUBTREE,
                     s.filter?s.filter:'(objectClass=*)',
                     s.attrs?s.attrs:'*',
                     s.cookie?s.cookie:"rid="+s.rid);
        syncopts = s;
    }

    function search(s_opts, fn) {
        stats.searches++;

        if (!s_opts) {
            throw new Error("Opts required");
        }
        if (!s_opts.base) {
            throw new Error("Base required");
        }

        return setCallback(binding.search(s_opts.base,
                                          s_opts.scope?s_opts.scope:self.SUBTREE,
                                          s_opts.filter?s_opts.filter:'(objectClass=*)',
                                          s_opts.attrs?s_opts.attrs:'*'),
                                          search, arguments, fn);
    }

    binding.on('searchresult', function(msgid, data) {
        stats.searchresults++;
        handleCallback(msgid, data);
    });

    binding.on('result', function(msgid) {
        stats.results++;
        handleCallback(msgid);
    });

    binding.on('newcookie', function(cookie) {
        // this way a reconnect always starts from the last known cookie.
        if (cookie) {
            syncopts.cookie = cookie;
            console.log('Storing new cookie ' + syncopts.cookie);
        }
    });

    binding.on('error', function(err) {
        stats.errors++;
        process.exit();
    });

    binding.on('disconnected', function(err) {
        stats.disconnects++;
        if (!reconnecting) {
            stats.reconnects++;
            reconnect();
        } else {
            stats.ignored_reconnnects++;
        }
    });

    this.open = open;
    this.simpleBind = simpleBind;
    this.search = search;
    this.getStats = getStats;
    this.sync = sync;
    this.state2str = state2str;
    this.phase2str = phase2str;

};

util.inherits(LDAP, events.EventEmitter);

module.exports = LDAP;
<commit_msg>Moved all cookie updates to a separate event. This allows LDAP.js to remain in the loop regarding cookies, as well as proxying the events out to the consumer for persistent storage.<commit_after>var events = require('events')
    , util = require('util');

try {
    LDAPConnection = require('./build/default/LDAP').LDAPConnection;
} catch(e) {
    LDAPConnection = require('./build/Release/LDAP').LDAPConnection;
}

//have the LDAPConnection class inherit properties like 'emit' from the EventEmitter class
LDAPConnection.prototype.__proto__ = events.EventEmitter.prototype;

function LDAPError(message, msgid) {
    this.name = 'LDAPError';
    this.message = message || 'Default Message';
    this.msgid = msgid;
}
LDAPError.prototype = new Error();
LDAPError.prototype.constructor = LDAPError;

var LDAP = function(opts) {
    var self = this;
    var binding = new LDAPConnection();
    var callbacks = {};
    var reconnecting = false;
    var syncopts = undefined;
    var cookie = undefined;
    var stats = {
        lateresponses: 0,
        reconnects: 0,
        ignored_reconnnects: 0,
        searches: 0,
        binds: 0,
        errors: 0,
        disconnects: 0,
        replays: 0,
        opens: 0,
        backoffs: 0,
        results: 0,
        searchresults: 0
    };

    if (!opts.uri) {
        throw new LDAPError('You must provide a URI');
    }

    opts.timeout = opts.timeout || 5000;
    opts.backoff = -1;
    opts.backoffmax = opts.backoffmax || 30000;

    self.BASE = 0;
    self.ONELEVEL = 1;
    self.SUBTREE = 2;
    self.SUBORDINATE = 3;
    self.DEFAULT = -1;

    self.LDAP_SYNC_PRESENT = 0;
    self.LDAP_SYNC_ADD = 1;
    self.LDAP_SYNC_MODIFY = 2;
    self.LDAP_SYNC_DELETE = 3;
    self.LDAP_SYNC_NEW_COOKIE = 4;

    self.LDAP_SYNC_CAPI_PRESENTS = 16;
    self.LDAP_SYNC_CAPI_DELETES = 19;
    self.LDAP_SYNC_CAPI_PRESENTS_IDSET = 48;
    self.LDAP_SYNC_CAPI_DELETES_IDSET = 51;
    self.LDAP_SYNC_CAPI_DONE = 80;

    function setCallback(msgid, replay, args, fn) {
        if (msgid >= 0) {
            if (typeof(fn) == 'function') {
                callbacks[msgid] =
                    {
                        fn: fn,
                        replay: replay,
                        args: args,
                        tm: setTimeout(function() {
                            delete callbacks[msgid];
                            fn(new LDAPError('Timeout', msgid));
                        }, opts.timeout)
                    }
            }
        } else {
            fn(new Error('LDAP Error', msgid));
        }
        return msgid;
    }

    function handleCallback(msgid, data) {
        if (callbacks[msgid]) {
            if (typeof callbacks[msgid].fn == 'function') {
                var thiscb = callbacks[msgid];
                delete callbacks[msgid];
                clearTimeout(thiscb.tm);
                thiscb.fn(undefined, data);
            }
        } else {
            stats.lateresponses++;
        }
    }

    function replayCallbacks() {
        for (var i in callbacks) {
            var thiscb = callbacks[i];
            delete (callbacks[i]);
            stats.replays++;
            thiscb.replay.apply(null, thiscb.args);
        }
    }

    function open(fn) {
        stats.opens++;
        binding.open(opts.uri, (opts.version || 3));
        return simpleBind(fn); // do an anon bind to get it all ready.
    }

    function backoff() {
        stats.backoffs++;
        opts.backoff++;
        if (opts.backoff > opts.backoffmax)
            opts.backoff = opts.backoffmax;
        return opts.backoff * 1000;
    }

    function reconnect() {
        reconnecting = true;
        binding.close();
        setTimeout(function() {
            var res = open(function(err) {
                if (err) {
                    reconnect();
                } else {
                    stats.reconnects++;
                    opts.backoff = -1;
                    replayCallbacks();
                    reconnecting = false;

                    if (syncopts) {
                        sync(syncopts);
                    }
                }
            });
        }, (backoff()));
    }

    function getStats() {
        stats.inflight = Object.keys(callbacks).length;
        return stats;
    }

    function state2str(state) {
        switch(state) {
        case self.LDAP_SYNC_PRESENT:
            return 'LDAP_SYNC_PRESENT';
        case self.LDAP_SYNC_ADD:
            return 'LDAP_SYNC_ADD';
        case self.LDAP_SYNC_MODIFY:
            return 'LDAP_SYNC_MODIFY';
        case self.LDAP_SYNC_DELETE:
            return 'LDAP_SYNC_DELETE';
        case self.LDAP_SYNC_NEW_COOKIE:
            return 'LDAP_SYNC_NEW_COOKIE';
        default:
            return 'UNKNOWN_STATE (' + state + ')';
        }
    }

    function phase2str(phase) {
        switch(phase) {
        case self.LDAP_SYNC_CAPI_DONE:
            return 'LDAP_SYNC_CAPI_DONE';
        case self.LDAP_SYNC_CAPI_PRESENTS:
            return 'LDAP_SYNC_CAPI_PRESENTS';
        case self.LDAP_SYNC_CAPI_DELETES:
            return 'LDAP_SYNC_CAPI_DELETES';
        case self.LDAP_SYNC_CAPI_PRESENTS_IDSET:
            return 'LDAP_SYNC_CAPI_PRESENTS_IDSET';
        case self.LDAP_SYNC_CAPI_DELETES_IDSET:
            return 'LDAP_SYNC_CAPI_DELETES_IDSET';
        default:
            return 'UNKNOWN_PHASE (' + phase + ')';
        }
    }

    function simpleBind(fn) {
        var msgid;
        if (!opts.binddn) {
            msgid = binding.simpleBind();
        } else {
            msgid = binding.simpleBind(opts.binddn, opts.password);
        }
        stats.binds++;
        return setCallback(msgid, simpleBind, arguments, fn);
    }

    function sync(s) {
        if (typeof s.syncresult == 'function') {
            binding.on('syncresult', s.syncresult);
        }
        if (typeof s.syncentry == 'function') {
            binding.on('syncentry', s.syncentry);
        }
        if (typeof s.syncidset == 'function') {
            binding.on('syncidset', s.syncidset);
        }
        if (typeof s.syncintermediate == 'function') {
            binding.on('syncintermediate', s.syncintermediate);
        }
        if (typeof s.newcookie == 'function') {
            self.on('newcookie', s.newcookie);
        }

        if (!s) {
            throw new Error('Options Required');
        }

        if (!s.base) {
            throw new Error('Base required');
        }

        if (!s.rid) {
            throw new Error('3-digit RID Required. Make one up.');
        }

        binding.sync(s.base,
                     s.scope?parseInt(s.scope):self.SUBTREE,
                     s.filter?s.filter:'(objectClass=*)',
                     s.attrs?s.attrs:'*',
                     s.cookie?s.cookie:"rid="+s.rid);
        syncopts = s;
    }

    function search(s_opts, fn) {
        stats.searches++;

        if (!s_opts) {
            throw new Error("Opts required");
        }
        if (!s_opts.base) {
            throw new Error("Base required");
        }

        return setCallback(binding.search(s_opts.base,
                                          s_opts.scope?s_opts.scope:self.SUBTREE,
                                          s_opts.filter?s_opts.filter:'(objectClass=*)',
                                          s_opts.attrs?s_opts.attrs:'*'),
                                          search, arguments, fn);
    }

    binding.on('searchresult', function(msgid, data) {
        stats.searchresults++;
        handleCallback(msgid, data);
    });

    binding.on('result', function(msgid) {
        stats.results++;
        handleCallback(msgid);
    });

    binding.on('newcookie', function(newcookie) {
        // this way a reconnect always starts from the last known cookie.
        if (newcookie && (newcookie != cookie)) {
            cookie = newcookie;
            if (syncopts) syncopts.cookie = newcookie;
            self.emit('newcookie', cookie);
        }
    });

    binding.on('error', function(err) {
        stats.errors++;
        process.exit();
    });

    binding.on('disconnected', function(err) {
        stats.disconnects++;
        if (!reconnecting) {
            stats.reconnects++;
            reconnect();
        } else {
            stats.ignored_reconnnects++;
        }
    });

    this.open = open;
    this.simpleBind = simpleBind;
    this.search = search;
    this.getStats = getStats;
    this.sync = sync;
    this.state2str = state2str;
    this.phase2str = phase2str;

};

util.inherits(LDAP, events.EventEmitter);

module.exports = LDAP;
<|endoftext|>


<commit_before>/* global angular */

console.log(TEST)
<commit_msg>created https request service to get user info using factory function<commit_after>/* global angular */

angular.module('core.user')
  .factory('User', ['$resource',
    function ($resource) {
      return $resource('https://api.github.com/users/:username/repos?access_token=' + TOKEN, {},
        {
          query: {
            method: 'GET',
            params: {username: 'cflatts'}
          }
        })
    }])
<|endoftext|>


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

    angular.module('myApp')
        .directive('googleChart', function($compile){

            return {
                restrict: 'E',
                template: '

',
                controller: 'googleChartController',
                controllerAs: 'vm',
                transclude : true
            }

    });

    angular.module('myApp')
        .controller('googleChartController',function($scope, sharedWeatherData){

            var vm = this;
            vm.prepareData = prepareData;

            vm.obj = {
                "type": "LineChart",
                "displayed": false,
                "data": {
                    "cols": [{
                                "label": "Day",
                                "type": "string"
                            },
                            {
                                "label": "High Temp",
                                "type": "number"
                            },
                            {
                                "label": "Low Temp",
                                "type": "number"
                            }
                        ],
                        // Seven days forecast data module, will be replace when prepareData() get called.
                        "rows": [
                            // {
                            //     "c": [{"v": ""},{"v": 19, "f": ""},{"v": 12, "f": ""}]
                            // }
                        ]
                },
                "options": {
                    "title": "7 Days Forecast",
                    "colors": ["red","blue"],
                    "isStacked": "true",
                    "fill": 20,
                    "displayExactValues": true,
                    "vAxis": {
                        "title": "Temperature °F",
                        "gridlines": {
                            "count": 10
                        }
                    },
                    "hAxis": {
                        "title": "Date"
                    },
                    "tooltip": {
                        "isHtml": true
                    }
                },
                "formatters": {},
                "view": {}
            }

            function prepareData(weatherData){

                var data = weatherData.item.forecast;
                var dataRows = [];

                for(var i=0; i<data.length-3; i++){
                    var day = data[i].day;
                    var highTemp = data[i].high;
                    var lowTemp = data[i].low;
                    var weatherDescription = data[i].text;

                    var highTempTooltip = "↑ " + highTemp + "°F" + ", Low ↓: " + lowTemp + "°F" + ", " + weatherDescription;
                    var lowTempTooltip = "↓ " + lowTemp + "°F" + ", High ↑: " + highTemp + "°F" + ", "+ weatherDescription;

                    var dayObj = {
                        "c": [{"v": day},{"v": highTemp, "f": highTempTooltip},{"v": 12, "f": lowTempTooltip}]
                    };

                    dataRows.push(dayObj);
                }

                // Replace seven day forecast data module.
                vm.obj.data.rows = dataRows;
                $scope.myChartObject = vm.obj;
            }

            $scope.$watch(function () {
                return sharedWeatherData.getWeatherData();
            },function (value) {
                if(value){
                    $scope.weatherData = value;
                    // Data prepare function
                    vm.prepareData($scope.weatherData);
                }
            });
    });

})();
<commit_msg>Fix LowTemp chart-line bug<commit_after>(function () {
    'use strict';

    angular.module('myApp')
        .directive('googleChart', function($compile){

            return {
                restrict: 'E',
                template: '

',
                controller: 'googleChartController',
                controllerAs: 'vm',
                transclude : true
            }

    });

    angular.module('myApp')
        .controller('googleChartController',function($scope, sharedWeatherData){

            var vm = this;
            vm.prepareData = prepareData;

            vm.obj = {
                "type": "LineChart",
                "displayed": false,
                "data": {
                    "cols": [{
                                "label": "Day",
                                "type": "string"
                            },
                            {
                                "label": "High Temp",
                                "type": "number"
                            },
                            {
                                "label": "Low Temp",
                                "type": "number"
                            }
                        ],
                        // Seven days forecast data module, will be replace when prepareData() get called.
                        "rows": [
                            // {
                            //     "c": [{"v": ""},{"v": 19, "f": ""},{"v": 12, "f": ""}]
                            // }
                        ]
                },
                "options": {
                    "title": "7 Days Forecast",
                    "colors": ["red","blue"],
                    "isStacked": "true",
                    "fill": 20,
                    "displayExactValues": true,
                    "vAxis": {
                        "title": "Temperature °F",
                        "gridlines": {
                            "count": 10
                        }
                    },
                    "hAxis": {
                        "title": "Date"
                    },
                    "tooltip": {
                        "isHtml": true
                    }
                },
                "formatters": {},
                "view": {}
            }

            function prepareData(weatherData){

                var data = weatherData.item.forecast;
                var dataRows = [];

                for(var i=0; i<data.length-3; i++){
                    var day = data[i].day;
                    var highTemp = data[i].high;
                    var lowTemp = data[i].low;
                    var weatherDescription = data[i].text;

                    var highTempTooltip = "↑ " + highTemp + "°F" + ", Low ↓: " + lowTemp + "°F" + ", " + weatherDescription;
                    var lowTempTooltip = "↓ " + lowTemp + "°F" + ", High ↑: " + highTemp + "°F" + ", "+ weatherDescription;

                    var dayObj = {
                        "c": [{"v": day},{"v": highTemp, "f": highTempTooltip},{"v": lowTemp, "f": lowTempTooltip}]
                    };

                    dataRows.push(dayObj);
                }

                // Replace seven day forecast data module.
                vm.obj.data.rows = dataRows;
                $scope.myChartObject = vm.obj;
            }

            $scope.$watch(function () {
                return sharedWeatherData.getWeatherData();
            },function (value) {
                if(value){
                    $scope.weatherData = value;
                    // Data prepare function
                    vm.prepareData($scope.weatherData);
                }
            });
    });

})();
<|endoftext|>


<commit_before>'use strict';

const mongo = require('mongodb');

class CollectionBase {
	constructor(collectionName, documentModelName, db, config) {
		if (collectionName == null || documentModelName == null || db == null || config == null) {
			throw new Error('missing arguments');
		}

		this.collectionName = collectionName;
		this.documentModelName = documentModelName;
		this.db = db;
		this._config = config;
	}

	async createAsync(data) {
		if (data == null) {
			throw new Error('missing arguments');
		}

		const result = await this.db.dbProvider.createAsync(this.collectionName, data);

		return new (require(this.documentModelName))(result, this.db, this._config);
	}

	async findAsync(query) {
		if (query == null) {
			throw new Error('missing arguments');
		}

		const document = await this.db.dbProvider.findAsync(this.collectionName, query);

		if (document == null) {
			return null;
		}

		return new (require(this.documentModelName))(document, this.db, this._config);
	}

	async findByIdAsync(id) {
		if (id == null) {
			throw new Error('missing arguments');
		}

		let parsedId = id;

		try {
			if (typeof id == 'string') {
				parsedId = mongo.ObjectId(id);
			}
		}
		catch(e) {
			console.log(e.trace);
			throw new Error('object id parse error');
		}

		return await this.findAsync({_id: parsedId});
	}

	async findArrayAsync(query, sortOption, limit) {
		if (query == null) {
			throw new Error('missing arguments');
		}

		const documents = await this.db.dbProvider.findArrayAsync(this.collectionName, query, sortOption, limit);

		if (documents == null || documents.length === 0) {
			return null;
		}

		const res = [];
		documents.forEach(document => {
			res.push(new (require(this.documentModelName))(document, this.db, this._config));
		});

		return res;
	}

	async updateAsync(query, data, options) {
		if (query == null || data == null) {
			throw new Error('missing arguments');
		}

		return (await this.db.dbProvider.updateAsync(this.collectionName, query, data, options)).result;
	}

	upsertAsync(query, data, options) {
		options = options || {};
		options.upsert = true;

		return this.updateAsync(query, data, options);
	}

	updateByIdAsync(id, data, options) {
		if (id == null) {
			throw new Error('missing arguments');
		}

		let parsedId = id;

		try {
			if (typeof id == 'string') {
				parsedId = mongo.ObjectId(id);
			}
		}
		catch(e) {
			console.log(e.trace);
			throw new Error('object id parse error');
		}

		return this.updateAsync({_id: parsedId}, data, options);
	}

	upsertByIdAsync(id, data, options) {
		options = options || {};
		options.upsert = true;

		return this.updateByIdAsync(id, data, options);
	}

	async removeAsync(query) {
		if (query == null) {
			throw new Error('missing arguments');
		}

		return await this.db.dbProvider.removeAsync(this.collectionName, query);
	}

	removeByIdAsync(id) {
		if (id == null) {
			throw new Error('missing arguments');
		}

		let parsedId = id;

		try {
			if (typeof id == 'string') {
				parsedId = mongo.ObjectId(id);
			}
		}
		catch(e) {
			console.log(e.trace);
			throw new Error('object id parse error');
		}

		return this.removeAsync();
	}
}
module.exports = CollectionBase;
<commit_msg>update loops<commit_after>'use strict';

const mongo = require('mongodb');

class CollectionBase {
	constructor(collectionName, documentModelName, db, config) {
		if (collectionName == null || documentModelName == null || db == null || config == null) {
			throw new Error('missing arguments');
		}

		this.collectionName = collectionName;
		this.documentModelName = documentModelName;
		this.db = db;
		this._config = config;
	}

	async createAsync(data) {
		if (data == null) {
			throw new Error('missing arguments');
		}

		const result = await this.db.dbProvider.createAsync(this.collectionName, data);

		return new (require(this.documentModelName))(result, this.db, this._config);
	}

	async findAsync(query) {
		if (query == null) {
			throw new Error('missing arguments');
		}

		const document = await this.db.dbProvider.findAsync(this.collectionName, query);

		if (document == null) {
			return null;
		}

		return new (require(this.documentModelName))(document, this.db, this._config);
	}

	async findByIdAsync(id) {
		if (id == null) {
			throw new Error('missing arguments');
		}

		let parsedId = id;

		try {
			if (typeof id == 'string') {
				parsedId = mongo.ObjectId(id);
			}
		}
		catch(e) {
			console.log(e.trace);
			throw new Error('object id parse error');
		}

		return await this.findAsync({_id: parsedId});
	}

	async findArrayAsync(query, sortOption, limit) {
		if (query == null) {
			throw new Error('missing arguments');
		}

		const documents = await this.db.dbProvider.findArrayAsync(this.collectionName, query, sortOption, limit);

		if (documents == null || documents.length === 0) {
			return null;
		}

		const res = [];
		for (const document of documents) {
			res.push(new (require(this.documentModelName))(document, this.db, this._config));
		}

		return res;
	}

	async updateAsync(query, data, options) {
		if (query == null || data == null) {
			throw new Error('missing arguments');
		}

		return (await this.db.dbProvider.updateAsync(this.collectionName, query, data, options)).result;
	}

	upsertAsync(query, data, options) {
		options = options || {};
		options.upsert = true;

		return this.updateAsync(query, data, options);
	}

	updateByIdAsync(id, data, options) {
		if (id == null) {
			throw new Error('missing arguments');
		}

		let parsedId = id;

		try {
			if (typeof id == 'string') {
				parsedId = mongo.ObjectId(id);
			}
		}
		catch(e) {
			console.log(e.trace);
			throw new Error('object id parse error');
		}

		return this.updateAsync({_id: parsedId}, data, options);
	}

	upsertByIdAsync(id, data, options) {
		options = options || {};
		options.upsert = true;

		return this.updateByIdAsync(id, data, options);
	}

	async removeAsync(query) {
		if (query == null) {
			throw new Error('missing arguments');
		}

		return await this.db.dbProvider.removeAsync(this.collectionName, query);
	}

	removeByIdAsync(id) {
		if (id == null) {
			throw new Error('missing arguments');
		}

		let parsedId = id;

		try {
			if (typeof id == 'string') {
				parsedId = mongo.ObjectId(id);
			}
		}
		catch(e) {
			console.log(e.trace);
			throw new Error('object id parse error');
		}

		return this.removeAsync();
	}
}
module.exports = CollectionBase;
<|endoftext|>