<commit_before>"use babel";

import { createStore, combineReducers } from "redux";

const assign = (...items) => Object.assign.apply(Object, [{}].concat(items));

function updateArrayItem(array, index, o) {
	return array.slice(0, index).concat(
		assign(array[index], o),
		array.slice(index + 1)
	);
}

function stacktrace(state = [], action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return [];

		case "UPDATE_STACKTRACE":
			// attempt to copy the variables over to the new stacktrace
			return action.stacktrace.map((stack) => {
				const existingStack = state.find((st) => st.pc === stack.pc);
				if (!stack.variables && existingStack) {
					stack.variables = existingStack.variables;
				}
				return stack;
			});

		case "UPDATE_VARIABLES":
			var variables = state[action.index].variables;
			if (action.path) {
				// update the variable at "path" to loaded
				variables = assign(variables, {
					[action.path]: assign(variables[action.path], { loaded: true })
				});
			}

			// TODO: update each variable in action.variables on its own? probably...
			variables = assign(variables, action.variables);
			return updateArrayItem(state, action.index, { variables: variables });
	}
	return state;
}
function goroutines(state = [], action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return [];

		case "UPDATE_GOROUTINES":
			return action.goroutines;
	}
	return state;
}
function breakpoints(state = [], action) {
	const { bp } = action;
	const { file, line } = bp || {};
	const index = indexOfBreakpoint(state, file, line);
	switch (action.type) {
		case "ADD_BREAKPOINT":
			if (index === -1) {
				return state.concat(bp).sort((a, b) => {
					const s =  a.file.localeCompare(b.file);
					return s !== 0 ? s : (a.line - b.line);
				});
			}
			return updateArrayItem(state, index, bp);

		case "REMOVE_BREAKPOINT":
			if (bp.state !== "busy") {
				return index === -1 ? state : state.slice(0, index).concat(state.slice(index + 1));
			}
			return updateArrayItem(state, index, bp);

		case "UPDATE_BREAKPOINT_LINE":
			if (index !== -1) {
				return updateArrayItem(state, index, { line: action.newLine });
			}
			return state;

		case "STOP":
			return state.map(({ file, line }) => {
				return { file, line, state: "notStarted" };
			});
	}

	return state;
}
function state(state = "notStarted", action) {
	switch (action.type) {
		case "STOP":
			return "notStarted";

		case "RESTART":
			return "started";

		case "SET_STATE":
			return action.state;

		case "SET_SELECTED_GOROUTINE":
			return action.state;
	}
	return state;
}
function selectedStacktrace(state = 0, action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return 0;

		case "SET_SELECTED_STACKTRACE":
			return action.index;

		case "UPDATE_STACKTRACE":
			return 0; // set back to the first function on each update
	}
	return state;
}
function selectedGoroutine(state = 0, action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return 0;

		case "SET_SELECTED_GOROUTINE":
			return action.id;
	}
	return state;
}
function args(state = "", action) {
	if (action.type === "UPDATE_ARGS") {
		return action.args;
	}
	return state;
}
function path(state = "", action) {
	if (action.type === "SET_DLV_PATH") {
		return action.path;
	}
	return state;
}

const delve = combineReducers({
	stacktrace,
	goroutines,
	breakpoints,
	state,
	selectedStacktrace,
	selectedGoroutine,
	args,
	path
});

function editors(state = {}, action) {
	void action;
	return state;
}
function panel(state, action) {
	if (!state) {
		state = { visible: atom.config.get("go-debug.panelInitialVisible") };
	}
	switch (action.type) {
		case "TOGGLE_PANEL":
			return assign(state, { visible: "visible" in action ? action.visible : !state.visible });

		case "SET_PANEL_WIDTH":
			return assign(state, { width: action.width });
	}
	return state;
}
const defaultOutput = {
	messages: [],
	visible: false,
	filters: { delve: true, output: true }
};
function output(state = defaultOutput, action) {
	switch (action.type) {
		case "TOGGLE_OUTPUT":
			return assign(state, { visible: "visible" in action ? action.visible : !state.visible });

		case "CLEAN_OUTPUT":
			return assign(state, { messages: [] });

		case "ADD_OUTPUT_MESSAGE": {
			const messages = state.messages.concat({ message: action.message, type: action.messageType });
			return assign(state, { messages: messages });
		}

		case "TOGGLE_OUTPUT_FILTER":
			return assign(state, {
				filters: assign(state.filters, {
					[action.filter]: !state.filters[action.filter]
				})
			});
	}
	return state;
}
function variables(state = { expanded: {} }, action) {
	switch (action.type) {
		case "TOGGLE_VARIABLE":
			var expanded = assign(state.expanded, {
				[action.path]: "expanded" in action ? action.expanded : !state.expanded[action.path]
			});
			return assign(state, { expanded });
	}
	return state;
}

export let store;

export function init(state) {
	if (state.breakpoints) {
		state.delve = { breakpoints: state.breakpoints };
		delete state.breakpoints;
	}

	store = createStore(combineReducers({
		editors,
		panel,
		delve,
		output,
		variables
	}), state);
}
export function dispose() {
	store = null;
}

export function serialize() {
	const state = store.getState();
	return {
		panel: state.panel,
		delve: {
			breakpoints: state.delve.breakpoints.map(({ file, line }) => { return { file, line }; }),
			args: state.delve.args
		}
	};
}

export function indexOfBreakpoint(bps, file, line) {
	return bps.findIndex((bp) => bp.file === file && bp.line === line);
}
export function getBreakpoint(file, line) {
	const bps = store.getState().delve.breakpoints;
	const index = indexOfBreakpoint(bps, file, line);
	return index === -1 ? null : bps[index];
}
export function getBreakpoints(file) {
	const bps = store.getState().delve.breakpoints;
	return !file ? bps : bps.filter((bp) => bp.file === file);
}
<commit_msg>fixed #25: fixed rare case where the panel has no visible prop and causes exceptions when resizing the panel<commit_after>"use babel";

import { createStore, combineReducers } from "redux";

const assign = (...items) => Object.assign.apply(Object, [{}].concat(items));

function updateArrayItem(array, index, o) {
	return array.slice(0, index).concat(
		assign(array[index], o),
		array.slice(index + 1)
	);
}

function stacktrace(state = [], action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return [];

		case "UPDATE_STACKTRACE":
			// attempt to copy the variables over to the new stacktrace
			return action.stacktrace.map((stack) => {
				const existingStack = state.find((st) => st.pc === stack.pc);
				if (!stack.variables && existingStack) {
					stack.variables = existingStack.variables;
				}
				return stack;
			});

		case "UPDATE_VARIABLES":
			var variables = state[action.index].variables;
			if (action.path) {
				// update the variable at "path" to loaded
				variables = assign(variables, {
					[action.path]: assign(variables[action.path], { loaded: true })
				});
			}

			// TODO: update each variable in action.variables on its own? probably...
			variables = assign(variables, action.variables);
			return updateArrayItem(state, action.index, { variables: variables });
	}
	return state;
}
function goroutines(state = [], action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return [];

		case "UPDATE_GOROUTINES":
			return action.goroutines;
	}
	return state;
}
function breakpoints(state = [], action) {
	const { bp } = action;
	const { file, line } = bp || {};
	const index = indexOfBreakpoint(state, file, line);
	switch (action.type) {
		case "ADD_BREAKPOINT":
			if (index === -1) {
				return state.concat(bp).sort((a, b) => {
					const s =  a.file.localeCompare(b.file);
					return s !== 0 ? s : (a.line - b.line);
				});
			}
			return updateArrayItem(state, index, bp);

		case "REMOVE_BREAKPOINT":
			if (bp.state !== "busy") {
				return index === -1 ? state : state.slice(0, index).concat(state.slice(index + 1));
			}
			return updateArrayItem(state, index, bp);

		case "UPDATE_BREAKPOINT_LINE":
			if (index !== -1) {
				return updateArrayItem(state, index, { line: action.newLine });
			}
			return state;

		case "STOP":
			return state.map(({ file, line }) => {
				return { file, line, state: "notStarted" };
			});
	}

	return state;
}
function state(state = "notStarted", action) {
	switch (action.type) {
		case "STOP":
			return "notStarted";

		case "RESTART":
			return "started";

		case "SET_STATE":
			return action.state;

		case "SET_SELECTED_GOROUTINE":
			return action.state;
	}
	return state;
}
function selectedStacktrace(state = 0, action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return 0;

		case "SET_SELECTED_STACKTRACE":
			return action.index;

		case "UPDATE_STACKTRACE":
			return 0; // set back to the first function on each update
	}
	return state;
}
function selectedGoroutine(state = 0, action) {
	switch (action.type) {
		case "RESTART":
		case "STOP":
			return 0;

		case "SET_SELECTED_GOROUTINE":
			return action.id;
	}
	return state;
}
function args(state = "", action) {
	if (action.type === "UPDATE_ARGS") {
		return action.args;
	}
	return state;
}
function path(state = "", action) {
	if (action.type === "SET_DLV_PATH") {
		return action.path;
	}
	return state;
}

const delve = combineReducers({
	stacktrace,
	goroutines,
	breakpoints,
	state,
	selectedStacktrace,
	selectedGoroutine,
	args,
	path
});

function editors(state = {}, action) {
	void action;
	return state;
}
const getDefaultPanel = () => {
	return { visible: atom.config.get("go-debug.panelInitialVisible") };
};
function panel(state, action) {
	if (!state) {
		state = getDefaultPanel();
	}
	switch (action.type) {
		case "TOGGLE_PANEL":
			return assign(state, { visible: "visible" in action ? action.visible : !state.visible });

		case "SET_PANEL_WIDTH":
			return assign(state, { width: action.width });
	}
	return state;
}
const defaultOutput = {
	messages: [],
	visible: false,
	filters: { delve: true, output: true }
};
function output(state = defaultOutput, action) {
	switch (action.type) {
		case "TOGGLE_OUTPUT":
			return assign(state, { visible: "visible" in action ? action.visible : !state.visible });

		case "CLEAN_OUTPUT":
			return assign(state, { messages: [] });

		case "ADD_OUTPUT_MESSAGE": {
			const messages = state.messages.concat({ message: action.message, type: action.messageType });
			return assign(state, { messages: messages });
		}

		case "TOGGLE_OUTPUT_FILTER":
			return assign(state, {
				filters: assign(state.filters, {
					[action.filter]: !state.filters[action.filter]
				})
			});
	}
	return state;
}
function variables(state = { expanded: {} }, action) {
	switch (action.type) {
		case "TOGGLE_VARIABLE":
			var expanded = assign(state.expanded, {
				[action.path]: "expanded" in action ? action.expanded : !state.expanded[action.path]
			});
			return assign(state, { expanded });
	}
	return state;
}

export let store;

export function init(state) {
	if (state.breakpoints) {
		state.delve = { breakpoints: state.breakpoints };
		delete state.breakpoints;
	}
	state.panel = assign(getDefaultPanel(), state.panel);

	store = createStore(combineReducers({
		editors,
		panel,
		delve,
		output,
		variables
	}), state);
}
export function dispose() {
	store = null;
}

export function serialize() {
	const state = store.getState();
	return {
		panel: state.panel,
		delve: {
			breakpoints: state.delve.breakpoints.map(({ file, line }) => { return { file, line }; }),
			args: state.delve.args
		}
	};
}

export function indexOfBreakpoint(bps, file, line) {
	return bps.findIndex((bp) => bp.file === file && bp.line === line);
}
export function getBreakpoint(file, line) {
	const bps = store.getState().delve.breakpoints;
	const index = indexOfBreakpoint(bps, file, line);
	return index === -1 ? null : bps[index];
}
export function getBreakpoints(file) {
	const bps = store.getState().delve.breakpoints;
	return !file ? bps : bps.filter((bp) => bp.file === file);
}
<|endoftext|>


<commit_before>(function(exports) {
  var debug;
  if (typeof require !== "undefined") {
    var sys = require("sys");
    debug = function() {
      sys.puts(sys.inspect(arguments));
    };
  } else if (window.console && window.console.log) {
    debug = console.log;
  }

  var carena = {
    applyProperties : function(obj, props){
      for (var i in props) {
        if (props.hasOwnProperty(i)) {
          Object.defineProperty(obj, i, Object.getOwnPropertyDescriptor(props, i));
        }
      }
      return obj;
    },

    // Build a reusable factory
    Design : function(obj, features, options) {
      if (arguments.length === 2 && options && options.length) {
        features = options;
      }

      features = features || [];
      var i        = 0,
          len      = features.length;

      return function(_obj, _features, _options) {
        features.push.apply(features, _features || []);
        return carena.Build(_obj, features, _options);
      };
    },
    _nodeId : 0,
    // Build an actual reference
    Build  : function(obj, features, options) {
      carena._nodeId+=1;
      obj = obj || {};
      var i        = 0,
          features = features || [],
          len      = features.length;

      // Based on the incomming parts array, build out self.
      for (i=0; i<len; i+=1) {
        features[i](obj, options);
      }
      obj.myId = carena._nodeId;
      return obj;
    }
  };

  // Default available features
  carena.feature = {
    Node : function(obj, options) {
      options = options || {}; //carena.mixin({}, options);

      var safe = {
        coords   : { x:0, y:0, z:0 },
        size     : { width:0, height:0 },
        bounds   : { x:0, y:0, width:0, height:0, dirty: false },
        children : [],
        parent   : null,
        dirty    : false
      };

      return carena.applyProperties(obj, {
        // Calculate bounds and return an object {x,y,width,height}
        get bounds() {
          if (safe.dirty) {
            safe.bounds.x      = safe.coords.x;
            safe.bounds.y      = safe.coords.y;
            safe.bounds.width  = safe.size.width;
            safe.bounds.height = safe.size.height;

            var len    = obj.children.length,
                i      = 0,
                bounds = safe.bounds,
                node;

            // recursively calculate the bounding box
            for (i; i<len; i++) {
              if (obj.children[i].dirty === false) { continue; }
              node = obj.children[i].bounds;

              bounds.x      = (node.x < bounds.x) ? node.x : bounds.x;
              bounds.y      = (node.y < bounds.y) ? node.y : bounds.y;

              bounds.width  = (node.x + node.width > bounds.width) ?
                               node.x + node.width                 :
                               bounds.width;

              bounds.height = (node.y + node.height > bounds.y) ?
                               node.y + node.height             :
                               bounds.height;
            }
            safe.dirty = false;
          }

          // return the cached result
          return safe.bounds;
        },

        containsPoint : function(x,y,bounding) {
          var c = {};
          if (bounding) {
            c  = obj.bounds;
          } else {
            c = safe.coords;
            c.width = safe.size.width;
            c.height = safe.size.height;
          }
          // simply AABB
          if (c.x <= x && c.x+c.width  >= x &&
              c.y <= y && c.y+c.height >= y)
          {
            console.log("here");
            return true;
          }
          return false;
        },

        get x() { return safe.coords.x; },
        set x(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.x", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.coords.x = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get y() { return safe.coords.y; },
        set y(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.y", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.coords.y = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get z() { return safe.coords.z; },
        set z(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.z", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.coords.z = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get height() { return safe.size.height; },
        set height(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.height", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.size.height = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get width() { return safe.size.width; },
        set width(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.width", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.size.width = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get children() { return safe.children; },
        get parent()   { return safe.parent; },
        set parent(value) {
          if (safe.parent) {
            safe.parent.dirty = true;
            safe.parent.remove(this);
          }

          safe.parent = value;
          safe.dirty = true;
        },

        get dirty() { return safe.dirty; },
        set dirty(value) {
          if (obj.event) {
             obj.event.trigger("node.dirty", {node : obj, oldValue: safe.dirty, value: value});
          }
          safe.dirty = value || false;
          obj.ascend(function(node) {
            if (node !== obj) {
              node.dirty = value;
            }
          });
        },

        // Functions
        clean : function() {
          safe.dirty = false;
          return obj;
        },

        add : function(child) {
          child.parent = this;
          safe.children.push(child);
          safe.dirty = true;
          return obj;
        },

        child : function(idx) {
          return safe.children[idx] || null;
        },

        remove : function(child) {
          var i = 0; len = safe.children.length;
          for (i; i<len; i++)
          {
            if (safe.children[i] === child) {
              safe.children.splice(i,1);
              break;
            }
          }
          safe.dirty = true;
          return obj;
        },

        walk : function(map, callback, depth) {
          var levels   = (depth) ? depth-1 : null,
              fnResult, // false means stop!
              walker   = {
                _stopped : false,
                stop     : function() {
                  walker._stopped = true;
                },
                stopped  : function() {
                  return walker._stopped;
                },
                nodesWalked : 1,
              };

          if (typeof callback === "function") {
            fnResult = callback(this, walker);
          }

          if (fnResult !== false &&
              (levels === null || levels >= 0) &&
              walker.stopped() === false)
          {
            try {
              map(obj, function(currentNode) {
                var result = currentNode.walk(map, callback, levels);
                if (result.stopped() === true) {
                  throw result;
                }
                walker.nodesWalked += result.nodesWalked;
              });

            // stop mapping if the walker was stopped
            } catch (e) {
              walker.nodesWalked += e.nodesWalked;
            }
          }
          return walker;
        },

        ascend  : function(fn, depth) {
          return obj.walk(function(node, callback) {
            if (node && node.parent) {
              callback(node.parent);
            }
          },fn, depth);
        },

        descend : function(fn, depth) {
          return obj.walk(function(node, callback) {
            var l=node.children.length, i=0, result;
            for (i; i<l; i++) {
              callback(node.child(i));
            }
          }, fn, depth);
        }
      });
    },

    // Provides the ability to bind/trigger external events
    Eventable : function(obj, options) {
      var safe = {
        binds : {}
      };

      var queryBinds = function(name, foundFn) {
        var i=0,  l,  results = [], bindParts,
            nameParts = name.split("."), found, last;

        for (var bind in safe.binds) {
          found = true;
          // catch all
          if (bind !== "*" ) {
            bindParts = bind.split(".");
             for (i=0; i<nameParts.length; i++) {
              if (bindParts[i]) {
                if (nameParts[i] !== bindParts[i] && bindParts[i] !== "*" && nameParts[i] !== "*") {
                  found = false;
                  break
                }
                last = bindParts[i];
              }
            }
          }

          if (found) {
            l = safe.binds[bind].length;
            for (i=l-1; i>=0; i--) {
              foundFn(bind, i);
            }
          }
        }
      };

      obj.event = {};
      carena.applyProperties(obj.event, {
        bind : function (name, fn) {
          if (!safe.binds[name]) {
            safe.binds[name] = [];
          }
          safe.binds[name].push(fn);
          return obj;
        },

        unbind : function (name, fn) {
          // slice a callback off
          if (name) {
            queryBinds(name, function(resolvedName, index) {
              if (!fn || safe.binds[resolvedName][index] === fn) {
                safe.binds[resolvedName].splice(index,1);
              }
            });
          } else {
            safe.binds[name] = [];
          }
          return obj;
        },

        trigger : function (name, data) {
          queryBinds(name, function(resolvedName, index) {
            var bind = safe.binds[resolvedName][index];
            bind(name, data);
          });

          // bubbling
          if (obj.parent && obj.parent.event) {
            obj.parent.event.trigger(name, data);
          }
          return obj;
        }
      });
      return obj;
    },

    Renderer : function(obj, options) {
      var safe = {
        canvas  : null,
        context : null
      };

      if (!options.canvas) {
        throw new Error("Renderer requires an options.canvas");
      }

      safe.context = options.canvas.getContext("2d");

      carena.applyProperties(obj, {
        get context() {  return safe.context; },
        get canvas() { return options.canvas; }
      });

      obj.x = 0;
      obj.y = 0;
      obj.width = options.canvas.width;
      obj.height = options.canvas.height;
      return obj;
    },

    Camera : function(obj, options) {
      var safe = {
        target : null,
        mouse  : {x:0, y:0},
        oldMouseMoveTarget : null // TODO: odd way of caching.. might want to reconsider this
      };

      if (!options.renderer) {
        throw new Error("Creating a canvas requires an options.renderer (carena.features.Renderer)");
      }

      // TODO: this might not always be on a document *winky wink*
      document.addEventListener("mousemove", function(ev) {
        safe.mouse.x = ev.clientX - (options.renderer.canvas.offsetLeft - window.pageXOffset);
        safe.mouse.y = ev.clientY - (options.renderer.canvas.offsetTop  - window.pageYOffset);
        var target = obj.nodeByPoint(safe.mouse.x, safe.mouse.y);
        if (target && target.event) {
          console.log("found node");
          if (safe.oldMouseMoveTarget && safe.oldMouseMoveTarget !== target) {
            safe.oldMouseMoveTarget.event.trigger("mouse.out");
            safe.oldMouseMoveTarget = null;
          }

          if (!safe.oldMouseMoveTarget) {
            safe.oldMouseMoveTarget = target;
            target.event.trigger("mouse.in", {target: target});
          }

          target.event.trigger("mouse.move", {target: target});
        } else if (safe.oldMouseMoveTarget) {
          safe.oldMouseMoveTarget.event.trigger("mouse.out");
          safe.oldMouseMoveTarget = null;
        }
      });

      // TODO: this might not always be on a document *winky wink*
      document.addEventListener("mousedown", function(ev) {
        if (safe.oldMouseMoveTarget) {
          safe.oldMouseMoveTarget.event.trigger("mouse.down");
        }
      });

      document.addEventListener("mouseup", function(ev) {
        if (safe.oldMouseMoveTarget) {
          safe.oldMouseMoveTarget.event.trigger("mouse.up");
        }
      });

      return carena.applyProperties(obj, {
        get target() { return safe.target; },
        set target(value) {
          safe.target = value;
        },
        nodeByPoint : function(x, y) {
          var found = null;

          if (safe.target) {
            safe.target.walk(function(node, callback) {
              var l=node.children.length, i=l-1;
              for (i; i>0; i--) {
                callback(node.child(i));
              }
            }, function(node, walker) {
              if (node.containsPoint(x, y)) {
                found = node;
              } else if (!found) {
                return false; // don't continue down this branch
              }
            });
          }

          return found;
        }
      });
    }
  };
  exports.carena = carena;
})(window || exports);<commit_msg>removed debug, added more data to events<commit_after>(function(exports) {
  var debug;
  if (typeof require !== "undefined") {
    var sys = require("sys");
    debug = function() {
      sys.puts(sys.inspect(arguments));
    };
  } else if (window.console && window.console.log) {
    debug = console.log;
  }

  var carena = {
    applyProperties : function(obj, props){
      for (var i in props) {
        if (props.hasOwnProperty(i)) {
          Object.defineProperty(obj, i, Object.getOwnPropertyDescriptor(props, i));
        }
      }
      return obj;
    },

    // Build a reusable factory
    Design : function(obj, features, options) {
      if (arguments.length === 2 && options && options.length) {
        features = options;
      }

      features = features || [];
      var i        = 0,
          len      = features.length;

      return function(_obj, _features, _options) {
        features.push.apply(features, _features || []);
        return carena.Build(_obj, features, _options);
      };
    },
    _nodeId : 0,
    // Build an actual reference
    Build  : function(obj, features, options) {
      carena._nodeId+=1;
      obj = obj || {};
      var i        = 0,
          features = features || [],
          len      = features.length;

      // Based on the incomming parts array, build out self.
      for (i=0; i<len; i+=1) {
        features[i](obj, options);
      }
      obj.myId = carena._nodeId;
      return obj;
    }
  };

  // Default available features
  carena.feature = {
    Node : function(obj, options) {
      options = options || {}; //carena.mixin({}, options);

      var safe = {
        coords   : { x:0, y:0, z:0 },
        size     : { width:0, height:0 },
        bounds   : { x:0, y:0, width:0, height:0, dirty: false },
        children : [],
        parent   : null,
        dirty    : false
      };

      return carena.applyProperties(obj, {
        // Calculate bounds and return an object {x,y,width,height}
        get bounds() {
          if (safe.dirty) {
            safe.bounds.x      = safe.coords.x;
            safe.bounds.y      = safe.coords.y;
            safe.bounds.width  = safe.size.width;
            safe.bounds.height = safe.size.height;

            var len    = obj.children.length,
                i      = 0,
                bounds = safe.bounds,
                node;

            // recursively calculate the bounding box
            for (i; i<len; i++) {
              if (obj.children[i].dirty === false) { continue; }
              node = obj.children[i].bounds;

              bounds.x      = (node.x < bounds.x) ? node.x : bounds.x;
              bounds.y      = (node.y < bounds.y) ? node.y : bounds.y;

              bounds.width  = (node.x + node.width > bounds.width) ?
                               node.x + node.width                 :
                               bounds.width;

              bounds.height = (node.y + node.height > bounds.y) ?
                               node.y + node.height             :
                               bounds.height;
            }
            safe.dirty = false;
          }

          // return the cached result
          return safe.bounds;
        },

        containsPoint : function(x,y,bounding) {
          var c = {};
          if (bounding) {
            c  = obj.bounds;
          } else {
            c = safe.coords;
            c.width = safe.size.width;
            c.height = safe.size.height;
          }
          // simply AABB
          if (c.x <= x && c.x+c.width  >= x &&
              c.y <= y && c.y+c.height >= y)
          {
            return true;
          }
          return false;
        },

        get x() { return safe.coords.x; },
        set x(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.x", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.coords.x = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get y() { return safe.coords.y; },
        set y(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.y", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.coords.y = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get z() { return safe.coords.z; },
        set z(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.z", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.coords.z = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get height() { return safe.size.height; },
        set height(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.height", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.size.height = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get width() { return safe.size.width; },
        set width(value) {
          if (obj.event && typeof obj.event.trigger === "function") {
             obj.event.trigger("node.width", {node : obj, oldValue: safe.coords.x, value: value});
          }
          safe.size.width = value;
          safe.bounds.dirty = true;
          obj.dirty = true;
        },

        get children() { return safe.children; },
        get parent()   { return safe.parent; },
        set parent(value) {
          if (safe.parent) {
            safe.parent.dirty = true;
            safe.parent.remove(this);
          }

          safe.parent = value;
          safe.dirty = true;
        },

        get dirty() { return safe.dirty; },
        set dirty(value) {
          if (obj.event) {
             obj.event.trigger("node.dirty", {node : obj, oldValue: safe.dirty, value: value});
          }
          safe.dirty = value || false;
          obj.ascend(function(node) {
            if (node !== obj) {
              node.dirty = value;
            }
          });
        },

        // Functions
        clean : function() {
          safe.dirty = false;
          return obj;
        },

        add : function(child) {
          child.parent = this;
          safe.children.push(child);
          safe.dirty = true;
          return obj;
        },

        child : function(idx) {
          return safe.children[idx] || null;
        },

        remove : function(child) {
          var i = 0; len = safe.children.length;
          for (i; i<len; i++)
          {
            if (safe.children[i] === child) {
              safe.children.splice(i,1);
              break;
            }
          }
          safe.dirty = true;
          return obj;
        },

        walk : function(map, callback, depth) {
          var levels   = (depth) ? depth-1 : null,
              fnResult, // false means stop!
              walker   = {
                _stopped : false,
                stop     : function() {
                  walker._stopped = true;
                },
                stopped  : function() {
                  return walker._stopped;
                },
                nodesWalked : 1,
              };

          if (typeof callback === "function") {
            fnResult = callback(this, walker);
          }

          if (fnResult !== false &&
              (levels === null || levels >= 0) &&
              walker.stopped() === false)
          {
            try {
              map(obj, function(currentNode) {
                var result = currentNode.walk(map, callback, levels);
                if (result.stopped() === true) {
                  throw result;
                }
                walker.nodesWalked += result.nodesWalked;
              });

            // stop mapping if the walker was stopped
            } catch (e) {
              walker.nodesWalked += e.nodesWalked;
            }
          }
          return walker;
        },

        ascend  : function(fn, depth) {
          return obj.walk(function(node, callback) {
            if (node && node.parent) {
              callback(node.parent);
            }
          },fn, depth);
        },

        descend : function(fn, depth) {
          return obj.walk(function(node, callback) {
            var l=node.children.length, i=0, result;
            for (i; i<l; i++) {
              callback(node.child(i));
            }
          }, fn, depth);
        }
      });
    },

    // Provides the ability to bind/trigger external events
    Eventable : function(obj, options) {
      var safe = {
        binds : {}
      };

      var queryBinds = function(name, foundFn) {
        var i=0,  l,  results = [], bindParts,
            nameParts = name.split("."), found, last;

        for (var bind in safe.binds) {
          found = true;
          // catch all
          if (bind !== "*" ) {
            bindParts = bind.split(".");
             for (i=0; i<nameParts.length; i++) {
              if (bindParts[i]) {
                if (nameParts[i] !== bindParts[i] && bindParts[i] !== "*" && nameParts[i] !== "*") {
                  found = false;
                  break
                }
                last = bindParts[i];
              }
            }
          }

          if (found) {
            l = safe.binds[bind].length;
            for (i=l-1; i>=0; i--) {
              foundFn(bind, i);
            }
          }
        }
      };

      obj.event = {};
      carena.applyProperties(obj.event, {
        bind : function (name, fn) {
          if (!safe.binds[name]) {
            safe.binds[name] = [];
          }
          safe.binds[name].push(fn);
          return obj;
        },

        unbind : function (name, fn) {
          // slice a callback off
          if (name) {
            queryBinds(name, function(resolvedName, index) {
              if (!fn || safe.binds[resolvedName][index] === fn) {
                safe.binds[resolvedName].splice(index,1);
              }
            });
          } else {
            safe.binds[name] = [];
          }
          return obj;
        },

        trigger : function (name, data) {
          queryBinds(name, function(resolvedName, index) {
            var bind = safe.binds[resolvedName][index];
            bind(name, data);
          });

          // bubbling
          if (obj.parent && obj.parent.event) {
            obj.parent.event.trigger(name, data);
          }
          return obj;
        }
      });
      return obj;
    },

    Renderer : function(obj, options) {
      var safe = {
        canvas  : null,
        context : null
      };

      if (!options.canvas) {
        throw new Error("Renderer requires an options.canvas");
      }

      safe.context = options.canvas.getContext("2d");

      carena.applyProperties(obj, {
        get context() {  return safe.context; },
        get canvas() { return options.canvas; }
      });

      obj.x = 0;
      obj.y = 0;
      obj.width = options.canvas.width;
      obj.height = options.canvas.height;
      return obj;
    },

    Camera : function(obj, options) {
      var safe = {
        target : null,
        mouse  : {x:0, y:0},
        oldMouseMoveTarget : null // TODO: odd way of caching.. might want to reconsider this
      };

      if (!options.renderer) {
        throw new Error("Creating a canvas requires an options.renderer (carena.features.Renderer)");
      }

      // TODO: this might not always be on a document *winky wink*
      document.addEventListener("mousemove", function(ev) {
        safe.mouse.x = ev.clientX - (options.renderer.canvas.offsetLeft - window.pageXOffset);
        safe.mouse.y = ev.clientY - (options.renderer.canvas.offsetTop  - window.pageYOffset);
        var target = obj.nodeByPoint(safe.mouse.x, safe.mouse.y);
        if (target && target.event) {
          if (safe.oldMouseMoveTarget && safe.oldMouseMoveTarget !== target) {
            safe.oldMouseMoveTarget.event.trigger("mouse.out", {target: target, mouse: safe.mouse});
            safe.oldMouseMoveTarget = null;
          }

          if (!safe.oldMouseMoveTarget) {
            safe.oldMouseMoveTarget = target;
            target.event.trigger("mouse.in", {
              target: safe.oldMouseMoveTarget,
              mouse: safe.mouse
            });
          }

          target.event.trigger("mouse.move", {target: target, mouse: safe.mouse});
        } else if (safe.oldMouseMoveTarget) {
          safe.oldMouseMoveTarget.event.trigger("mouse.out", {
            target: safe.oldMouseMoveTarget,
            mouse: safe.mouse
          });
          safe.oldMouseMoveTarget = null;
        }
      });

      // TODO: this might not always be on a document *winky wink*
      document.addEventListener("mousedown", function(ev) {
        if (safe.oldMouseMoveTarget) {
          safe.oldMouseMoveTarget.event.trigger("mouse.down", {
            target: safe.oldMouseMoveTarget,
            mouse: safe.mouse
          });
        }
      });

      document.addEventListener("mouseup", function(ev) {
        if (safe.oldMouseMoveTarget) {
          safe.oldMouseMoveTarget.event.trigger("mouse.up", {
            target: self.oldMouseMoveTarget,
            mouse: safe.mouse
          });
        }
      });

      return carena.applyProperties(obj, {
        get target() { return safe.target; },
        set target(value) {
          safe.target = value;
        },
        nodeByPoint : function(x, y) {
          var found = null;

          if (safe.target) {
            safe.target.walk(function(node, callback) {
              var l=node.children.length, i=l-1;
              for (i; i>0; i--) {
                callback(node.child(i));
              }
            }, function(node, walker) {
              if (node.containsPoint(x, y)) {
                found = node;
              } else if (!found) {
                return false; // don't continue down this branch
              }
            });
          }

          return found;
        }
      });
    }
  };
  exports.carena = carena;
})(window || exports);<|endoftext|>


<commit_before>var urlParser = require('url'),
  defaultConfig = require('../conf/defaultConfig'),
  dateFormat = require('dateformat'),
  fs = require('fs-extra'),
  path = require('path');

exports.setupConfiguration = function(config) {

  // to be able to run sitespeed.io you need to specify a file, a URL or a file
  if ((!config.url) && (!config.file) && (!config.sites)) {
    console.log('You must specify either a URL to test or a file with URL:s');
    process.exit(1);
  }

  // if we have default values not set in the config
  // add them from the default config
  Object.keys(defaultConfig).forEach(function(key) {
    if (!config.hasOwnProperty(key)) {
      config[key] = defaultConfig[key];
    }
  });

  // to make it easy later on, we add:
  // config.browertime = the browser(s) that will be run in browsertime (not phantomjs)
  // config.phantomjs - boolean to run phantomjs for timings or not
  if (config.browser) {
    var b = config.browser.split(','),
      configuredBrowsers = b.filter(function(browser) {
        return defaultConfig.supportedBrowsers.indexOf(browser.toLowerCase()) > -1;
      });

    if (configuredBrowsers.indexOf('phantomjs') > -1) {
      config.phantomjs = true;
      if (configuredBrowsers.length > 1) {
        var i = configuredBrowsers.indexOf('phantomjs');
        configuredBrowsers.splice(i, 1);
        config.browsertime = configuredBrowsers;
      }
    } else {
      config.browsertime = configuredBrowsers;
    }
  }

  // If we supply a configuration file, then it will ovveride all current conf, meaning
  // we can easily use the same conf over and over again
  if (config.configFile) {
    config = JSON.parse(fs.readFileSync(config.configFile));
  }

  // should we test YSlow rules, default is true
  config.runYslow = config.noYslow ? false : true;

  // The run always has a fresh date
  config.run = {};
  config.run.date = new Date();

  // Setup the absolute result dir
  var startPath = (config.resultBaseDir.charAt(0) === path.sep) ? config.resultBaseDir : path.join(__dirname, '../',
    config.resultBaseDir);

  if (!config.outputFolderName) {
    config.startFolder = dateFormat(config.run.date, 'yyyy-mm-dd-HH-MM-ss');
  } else {
    config.startFolder = config.outputFolderName;
  }

  if (config.url) {
    config.urlObject = urlParser.parse(config.url);
    config.run.absResultDir = path.join(startPath, config.urlObject.hostname, config.startFolder);
  } else if (config.file) {
    // TODO handle the file name in a good way if it contains chars that will not fit in a dir
    // Only take the filename, excluding dirs
    config.run.absResultDir = path.join(startPath, path.basename(config.file), config.startFolder);
  } else if (config.sites) {
    // The log file will end up here
    config.run.absResultDir = path.join(startPath, 'sites', config.startFolder);
  }

  // Parse the proxy info as a real URL
  if (config.proxy) {
    config.urlProxyObject = urlParser.parse(config.proxy);
  }

  // decide which rules to use ...
  if (config.profile === 'mobile') {
    config.rules = require('../conf/mobileRules.json');
    config.ruleSet = 'sitespeed.io-mobile';
    config.userAgent =
      'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25';
    config.viewPort = '320x444';
  } else {
    if (config.limitFile) {
      config.rules = require(config.limitFile);
    } else {
      config.rules = require('../conf/desktopRules.json');
    }
    // The rest use the default/configured one, will that work? :)
  }

  config.summaryBoxes = ['ruleScore'];

  config.sitesColumns = ['requests', 'criticalPathScore', 'pageWeight', 'cacheTime', 'ruleScore'];

  if (config.runYslow) {
    config.pageColumns = ['yslow.assets.js', 'yslow.assets.css', 'yslow.assets.img', 'yslow.requests',
      'rules.expiresmod.items', 'yslow.pageWeight', 'rules.avoidscalingimages.items', 'rules.criticalpath'
    ];
  }
  if (config.columns) {
    config.pageColumns = config.columns[0].split(',');
  }

  if (config.gpsiKey) {
    config.summaryBoxes.push('gpsi.gscore');
    config.sitesColumns.push('gpsi.gscore');
    config.pageColumns.push('gpsi.gscore');
  }
  config.summaryBoxes.push('criticalPathScore', 'jsSyncInHead',
    'jsPerPage', 'cssPerPage', 'cssImagesPerPage', 'fontsPerPage',
    'imagesPerPage', 'requests', 'requestsWithoutExpires', 'requestsWithoutGzip',
    'docWeight', 'jsWeightPerPage', 'cssWeightPerPage', 'imageWeightPerPage',
    'pageWeight', 'browserScaledImages', 'spofPerPage', 'numberOfDomains',
    'singleDomainRequests', 'redirectsPerPage', 'cacheTime', 'timeSinceLastMod');

  if (config.wptUrl) {
    config.summaryBoxes.push('wpt.firstViewTTFB', 'wpt.firstViewSpeedIndex',
      'wpt.repeatViewSpeedIndex',
      'wpt.firstViewVisualComplete', 'wpt.repeatViewVisualComplete');
    config.sitesColumns.push('wpt.firstView.SpeedIndex', 'wpt.repeatView.SpeedIndex');
    config.pageColumns.push('wpt.firstView.SpeedIndex');
  }

  if (config.browsertime)  {
    config.summaryBoxes.push('serverResponseTime', 'backEndTime', 'frontEndTime', 'domContentLoadedTime',
      'pageLoadTime', 'firstPaintTime');
    config.sitesColumns.push('serverResponseTime', 'domContentLoadedTime');
    config.pageColumns.push('timings.serverResponseTime.median', 'timings.domContentLoadedTime.median');
  } // only show real browsers data if we configured both of them
  else if (config.phantomjs) {
    config.summaryBoxes.push('domContentLoadedTimePhantomJS', 'pageLoadTimePhantomJS');
    config.sitesColumns.push('domContentLoadedTimePhantomJS');
    config.pageColumns.push('phantomjs.domContentLoadedTime.median');
  }

  if (config.boxes) {
    if (config.boxes[0].indexOf('+') === 0) {
      config.boxes[0].split(',').forEach(function(box) {
        if (box.indexOf('+') === 0) {
          config.summaryBoxes.push(box.substring(1));
        } else {
          config.summaryBoxes.push(box);
        }
      });
    } else {
      config.summaryBoxes = config.boxes[0].split(',');
    }
  }

  config.dataDir = 'data';

  config.supportedBrowsers = defaultConfig.supportedBrowsers;

  return config;
};<commit_msg>make it possible to run without fetching yslow rules<commit_after>var urlParser = require('url'),
  defaultConfig = require('../conf/defaultConfig'),
  dateFormat = require('dateformat'),
  fs = require('fs-extra'),
  path = require('path');

exports.setupConfiguration = function(config) {

  // to be able to run sitespeed.io you need to specify a file, a URL or a file
  if ((!config.url) && (!config.file) && (!config.sites)) {
    console.log('You must specify either a URL to test or a file with URL:s');
    process.exit(1);
  }

  // if we have default values not set in the config
  // add them from the default config
  Object.keys(defaultConfig).forEach(function(key) {
    if (!config.hasOwnProperty(key)) {
      config[key] = defaultConfig[key];
    }
  });

  // to make it easy later on, we add:
  // config.browertime = the browser(s) that will be run in browsertime (not phantomjs)
  // config.phantomjs - boolean to run phantomjs for timings or not
  if (config.browser) {
    var b = config.browser.split(','),
      configuredBrowsers = b.filter(function(browser) {
        return defaultConfig.supportedBrowsers.indexOf(browser.toLowerCase()) > -1;
      });

    if (configuredBrowsers.indexOf('phantomjs') > -1) {
      config.phantomjs = true;
      if (configuredBrowsers.length > 1) {
        var i = configuredBrowsers.indexOf('phantomjs');
        configuredBrowsers.splice(i, 1);
        config.browsertime = configuredBrowsers;
      }
    } else {
      config.browsertime = configuredBrowsers;
    }
  }

  // If we supply a configuration file, then it will ovveride all current conf, meaning
  // we can easily use the same conf over and over again
  if (config.configFile) {
    config = JSON.parse(fs.readFileSync(config.configFile));
  }

  // should we test YSlow rules, default is true
  config.runYslow = config.noYslow ? false : true;

  // The run always has a fresh date
  config.run = {};
  config.run.date = new Date();

  // Setup the absolute result dir
  var startPath = (config.resultBaseDir.charAt(0) === path.sep) ? config.resultBaseDir : path.join(__dirname, '../',
    config.resultBaseDir);

  if (!config.outputFolderName) {
    config.startFolder = dateFormat(config.run.date, 'yyyy-mm-dd-HH-MM-ss');
  } else {
    config.startFolder = config.outputFolderName;
  }

  if (config.url) {
    config.urlObject = urlParser.parse(config.url);
    config.run.absResultDir = path.join(startPath, config.urlObject.hostname, config.startFolder);
  } else if (config.file) {
    // TODO handle the file name in a good way if it contains chars that will not fit in a dir
    // Only take the filename, excluding dirs
    config.run.absResultDir = path.join(startPath, path.basename(config.file), config.startFolder);
  } else if (config.sites) {
    // The log file will end up here
    config.run.absResultDir = path.join(startPath, 'sites', config.startFolder);
  }

  // Parse the proxy info as a real URL
  if (config.proxy) {
    config.urlProxyObject = urlParser.parse(config.proxy);
  }

  // decide which rules to use ...
  if (config.profile === 'mobile') {
    config.rules = require('../conf/mobileRules.json');
    config.ruleSet = 'sitespeed.io-mobile';
    config.userAgent =
      'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25';
    config.viewPort = '320x444';
  } else {
    if (config.limitFile) {
      config.rules = require(config.limitFile);
    } else {
      config.rules = require('../conf/desktopRules.json');
    }
    // The rest use the default/configured one, will that work? :)
  }

  if (config.runYslow) {
    config.summaryBoxes = ['ruleScore'];
    config.sitesColumns = ['requests', 'criticalPathScore', 'pageWeight', 'cacheTime', 'ruleScore'];
    config.pageColumns = ['yslow.assets.js', 'yslow.assets.css', 'yslow.assets.img', 'yslow.requests',
      'rules.expiresmod.items', 'yslow.pageWeight', 'rules.avoidscalingimages.items', 'rules.criticalpath'
    ];
  } else {
    config.summaryBoxes = [];
    config.sitesColumns = [];
    config.pageColumns = [];
  }

  if (config.columns) {
    config.pageColumns = config.columns[0].split(',');
  }

  if (config.gpsiKey) {
    config.summaryBoxes.push('gpsi.gscore');
    config.sitesColumns.push('gpsi.gscore');
    config.pageColumns.push('gpsi.gscore');
  }
  config.summaryBoxes.push('criticalPathScore', 'jsSyncInHead',
    'jsPerPage', 'cssPerPage', 'cssImagesPerPage', 'fontsPerPage',
    'imagesPerPage', 'requests', 'requestsWithoutExpires', 'requestsWithoutGzip',
    'docWeight', 'jsWeightPerPage', 'cssWeightPerPage', 'imageWeightPerPage',
    'pageWeight', 'browserScaledImages', 'spofPerPage', 'numberOfDomains',
    'singleDomainRequests', 'redirectsPerPage', 'cacheTime', 'timeSinceLastMod');

  if (config.wptUrl) {
    config.summaryBoxes.push('wpt.firstViewTTFB', 'wpt.firstViewSpeedIndex',
      'wpt.repeatViewSpeedIndex',
      'wpt.firstViewVisualComplete', 'wpt.repeatViewVisualComplete');
    config.sitesColumns.push('wpt.firstView.SpeedIndex', 'wpt.repeatView.SpeedIndex');
    config.pageColumns.push('wpt.firstView.SpeedIndex');
  }

  if (config.browsertime)  {
    config.summaryBoxes.push('serverResponseTime', 'backEndTime', 'frontEndTime', 'domContentLoadedTime',
      'pageLoadTime', 'firstPaintTime');
    config.sitesColumns.push('serverResponseTime', 'domContentLoadedTime');
    config.pageColumns.push('timings.serverResponseTime.median', 'timings.domContentLoadedTime.median');
  } // only show real browsers data if we configured both of them
  else if (config.phantomjs) {
    config.summaryBoxes.push('domContentLoadedTimePhantomJS', 'pageLoadTimePhantomJS');
    config.sitesColumns.push('domContentLoadedTimePhantomJS');
    config.pageColumns.push('phantomjs.domContentLoadedTime.median');
  }

  if (config.boxes) {
    if (config.boxes[0].indexOf('+') === 0) {
      config.boxes[0].split(',').forEach(function(box) {
        if (box.indexOf('+') === 0) {
          config.summaryBoxes.push(box.substring(1));
        } else {
          config.summaryBoxes.push(box);
        }
      });
    } else {
      config.summaryBoxes = config.boxes[0].split(',');
    }
  }

  config.dataDir = 'data';

  config.supportedBrowsers = defaultConfig.supportedBrowsers;

  return config;
};<|endoftext|>


<commit_before>/*jshint -W097 */
'use strict';
/*jshint unused: false */

var React = require('react');
var Link = require('react-router').Link;

var Spinner = require('./Spinner').Spinner;

var Navbar = React.createClass({
    render: function() {
        /*jshint ignore:start */
        return

                    <button type="button"
                        className="navbar-toggle collapsed"
                        data-toggle="collapse"
                        data-target=".navbar-collapse">
                        Toggle navigation

                    </button>
                    <Link className="navbar-brand" to="/">
                        Edaemon ADMIN
                    </Link>

                        <button className="btn btn-default dropdown-toggle"
                            data-toggle="dropdown"
                            ref={(c) => { $(c).dropdown(); }}>

                        </button>

<Link to="/changes/new">Izmaiņas</Link>

                            <Link to="/changes/all">
                                Visas izmaiņas
                            </Link>

                            <Spinner />

        ;
        /*jshint ignore:end */
    }
});

module.exports = { Navbar: Navbar };
<commit_msg>add timetable entry in navbar<commit_after>/*jshint -W097 */
'use strict';
/*jshint unused: false */

var React = require('react');
var Link = require('react-router').Link;

var Spinner = require('./Spinner').Spinner;

var Navbar = React.createClass({
    render: function() {
        /*jshint ignore:start */
        return

                    <button type="button"
                        className="navbar-toggle collapsed"
                        data-toggle="collapse"
                        data-target=".navbar-collapse">
                        Toggle navigation

                    </button>
                    <Link className="navbar-brand" to="/">
                        Edaemon ADMIN
                    </Link>

                        <button className="btn btn-default dropdown-toggle"
                            data-toggle="dropdown"
                            ref={(c) => { $(c).dropdown(); }}>

                        </button>

<Link to="/changes/new">Izmaiņas</Link>

<Link to="/timetables/new">Stundu sarakstu</Link>

                            <Link to="/changes/all">
                                Visas izmaiņas
                            </Link>

                            <Spinner />

        ;
        /*jshint ignore:end */
    }
});

module.exports = { Navbar: Navbar };
<|endoftext|>


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

var Result = require(__dirname + '/result');
var utils = require(__dirname + '/utils');

var Query = function(config, values, callback) {
  // use of "new" optional
  if(!(this instanceof Query)) { return new Query(config, values, callback); }

  config = utils.normalizeQueryConfig(config, values, callback);

  this.text = config.text;
  this.values = config.values;
  this.rows = config.rows;
  this.types = config.types;
  this.name = config.name;
  this.binary = config.binary;
  this.stream = config.stream;
  //use unique portal name each time
  this.portal = config.portal || "";
  this.callback = config.callback;
  this._fieldNames = [];
  this._fieldConverters = [];
  this._result = new Result(config.rowMode);
  this.isPreparedStatement = false;
  this._canceledDueToError = false;
  EventEmitter.call(this);
};

util.inherits(Query, EventEmitter);

Query.prototype.requiresPreparation = function() {
  //named queries must always be prepared
  if(this.name) { return true; }
  //always prepare if there are max number of rows expected per
  //portal execution
  if(this.rows) { return true; }
  //don't prepare empty text queries
  if(!this.text) { return false; }
  //binary should be prepared to specify results should be in binary
  //unless there are no parameters
  if(this.binary && !this.values) { return false; }
  //prepare if there are values
  return (this.values || 0).length > 0;
};

var noParse = function(val) {
  return val;
};

//associates row metadata from the supplied
//message with this query object
//metadata used when parsing row results
Query.prototype.handleRowDescription = function(msg) {
  this._result.addFields(msg.fields);
};

Query.prototype.handleDataRow = function(msg) {
  var row = this._result.parseRow(msg.fields);
  this.emit('row', row, this._result);

  //if there is a callback collect rows
  if(this.callback) {
    this._result.addRow(row);
  }
};

Query.prototype.handleCommandComplete = function(msg, con) {
  this._result.addCommandComplete(msg);
  //need to sync after each command complete of a prepared statement
  if(this.isPreparedStatement) {
    con.sync();
  }
};

Query.prototype.handleReadyForQuery = function() {
  if(this._canceledDueToError) {
    return this.handleError(this._canceledDueToError);
  }
  if(this.callback) {
    this.callback(null, this._result);
  }
  this.emit('end', this._result);
};

Query.prototype.handleError = function(err, connection) {
  //need to sync after error during a prepared statement
  if(this.isPreparedStatement) {
    connection.sync();
  }
  if(this._canceledDueToError) {
    err = this._canceledDueToError;
    this._canceledDueToError = false;
  }
  //if callback supplied do not emit error event as uncaught error
  //events will bubble up to node process
  if(this.callback) {
    this.callback(err);
  } else {
    this.emit('error', err);
  }
  this.emit('end');
};

Query.prototype.submit = function(connection) {
  var self = this;
  if(this.requiresPreparation()) {
    this.prepare(connection);
  } else {
    connection.query(this.text);
  }
};

Query.prototype.hasBeenParsed = function(connection) {
  return this.name && connection.parsedStatements[this.name];
};

Query.prototype.handlePortalSuspended = function(connection) {
  this._getRows(connection, this.rows);
};

Query.prototype._getRows = function(connection, rows) {
  connection.execute({
    portal: this.portalName,
    rows: rows
  }, true);
  connection.flush();
};

Query.prototype.prepare = function(connection) {
  var self = this;
  //prepared statements need sync to be called after each command
  //complete or when an error is encountered
  this.isPreparedStatement = true;
  //TODO refactor this poor encapsulation
  if(!this.hasBeenParsed(connection)) {
    connection.parse({
      text: self.text,
      name: self.name,
      types: self.types
    }, true);
    if(this.name) {
      connection.parsedStatements[this.name] = true;
    }
  }

  //TODO is there some better way to prepare values for the database?
  if(self.values) {
    for(var i = 0, len = self.values.length; i < len; i++) {
      self.values[i] = utils.prepareValue(self.values[i]);
    }
  }

  //http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
  connection.bind({
    portal: self.portalName,
    statement: self.name,
    values: self.values,
    binary: self.binary
  }, true);

  connection.describe({
    type: 'P',
    name: self.portalName || ""
  }, true);

  this._getRows(connection, this.rows);
};

Query.prototype.handleCopyInResponse = function (connection) {
  if(this.stream) this.stream.startStreamingToConnection(connection);
  else connection.sendCopyFail('No source stream defined');
};

Query.prototype.handleCopyData = function (msg, connection) {
  var chunk = msg.chunk;
  if(this.stream) {
    this.stream.handleChunk(chunk);
  }
  //if there are no stream (for example when copy to query was sent by
  //query method instead of copyTo) error will be handled
  //on copyOutResponse event, so silently ignore this error here
};
module.exports = Query;
<commit_msg>query: remove dead type-parsing code path<commit_after>var EventEmitter = require('events').EventEmitter;
var util = require('util');

var Result = require(__dirname + '/result');
var utils = require(__dirname + '/utils');

var Query = function(config, values, callback) {
  // use of "new" optional
  if(!(this instanceof Query)) { return new Query(config, values, callback); }

  config = utils.normalizeQueryConfig(config, values, callback);

  this.text = config.text;
  this.values = config.values;
  this.rows = config.rows;
  this.types = config.types;
  this.name = config.name;
  this.binary = config.binary;
  this.stream = config.stream;
  //use unique portal name each time
  this.portal = config.portal || "";
  this.callback = config.callback;
  this._fieldNames = [];
  this._fieldConverters = [];
  this._result = new Result(config.rowMode);
  this.isPreparedStatement = false;
  this._canceledDueToError = false;
  EventEmitter.call(this);
};

util.inherits(Query, EventEmitter);

Query.prototype.requiresPreparation = function() {
  //named queries must always be prepared
  if(this.name) { return true; }
  //always prepare if there are max number of rows expected per
  //portal execution
  if(this.rows) { return true; }
  //don't prepare empty text queries
  if(!this.text) { return false; }
  //binary should be prepared to specify results should be in binary
  //unless there are no parameters
  if(this.binary && !this.values) { return false; }
  //prepare if there are values
  return (this.values || 0).length > 0;
};

//associates row metadata from the supplied
//message with this query object
//metadata used when parsing row results
Query.prototype.handleRowDescription = function(msg) {
  this._result.addFields(msg.fields);
};

Query.prototype.handleDataRow = function(msg) {
  var row = this._result.parseRow(msg.fields);
  this.emit('row', row, this._result);

  //if there is a callback collect rows
  if(this.callback) {
    this._result.addRow(row);
  }
};

Query.prototype.handleCommandComplete = function(msg, con) {
  this._result.addCommandComplete(msg);
  //need to sync after each command complete of a prepared statement
  if(this.isPreparedStatement) {
    con.sync();
  }
};

Query.prototype.handleReadyForQuery = function() {
  if(this._canceledDueToError) {
    return this.handleError(this._canceledDueToError);
  }
  if(this.callback) {
    this.callback(null, this._result);
  }
  this.emit('end', this._result);
};

Query.prototype.handleError = function(err, connection) {
  //need to sync after error during a prepared statement
  if(this.isPreparedStatement) {
    connection.sync();
  }
  if(this._canceledDueToError) {
    err = this._canceledDueToError;
    this._canceledDueToError = false;
  }
  //if callback supplied do not emit error event as uncaught error
  //events will bubble up to node process
  if(this.callback) {
    this.callback(err);
  } else {
    this.emit('error', err);
  }
  this.emit('end');
};

Query.prototype.submit = function(connection) {
  var self = this;
  if(this.requiresPreparation()) {
    this.prepare(connection);
  } else {
    connection.query(this.text);
  }
};

Query.prototype.hasBeenParsed = function(connection) {
  return this.name && connection.parsedStatements[this.name];
};

Query.prototype.handlePortalSuspended = function(connection) {
  this._getRows(connection, this.rows);
};

Query.prototype._getRows = function(connection, rows) {
  connection.execute({
    portal: this.portalName,
    rows: rows
  }, true);
  connection.flush();
};

Query.prototype.prepare = function(connection) {
  var self = this;
  //prepared statements need sync to be called after each command
  //complete or when an error is encountered
  this.isPreparedStatement = true;
  //TODO refactor this poor encapsulation
  if(!this.hasBeenParsed(connection)) {
    connection.parse({
      text: self.text,
      name: self.name,
      types: self.types
    }, true);
    if(this.name) {
      connection.parsedStatements[this.name] = true;
    }
  }

  //TODO is there some better way to prepare values for the database?
  if(self.values) {
    for(var i = 0, len = self.values.length; i < len; i++) {
      self.values[i] = utils.prepareValue(self.values[i]);
    }
  }

  //http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
  connection.bind({
    portal: self.portalName,
    statement: self.name,
    values: self.values,
    binary: self.binary
  }, true);

  connection.describe({
    type: 'P',
    name: self.portalName || ""
  }, true);

  this._getRows(connection, this.rows);
};

Query.prototype.handleCopyInResponse = function (connection) {
  if(this.stream) this.stream.startStreamingToConnection(connection);
  else connection.sendCopyFail('No source stream defined');
};

Query.prototype.handleCopyData = function (msg, connection) {
  var chunk = msg.chunk;
  if(this.stream) {
    this.stream.handleChunk(chunk);
  }
  //if there are no stream (for example when copy to query was sent by
  //query method instead of copyTo) error will be handled
  //on copyOutResponse event, so silently ignore this error here
};
module.exports = Query;
<|endoftext|>


<commit_before>'use strict';

var yaml = require('js-yaml'),
    fs = require('fs'),
    path = require('path'),
    merge = require('merge');

var defaults = yaml.safeLoad(fs.readFileSync(path.join(__dirname, 'config', 'sass-lint.yml'), 'utf8'));

var findFile = function findFile (configPath, filename) {
  var HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE,
      dirname,
      parentDirname;

  configPath = configPath || path.join(process.cwd(), filename);

  if (fs.existsSync(configPath)) {
    return fs.realpathSync(configPath);
  }

  dirname = path.dirname(configPath);
  parentDirname = path.dirname(dirname);

  if (dirname === HOME || dirname === parentDirname) {
    return null;
  }

  configPath = path.join(parentDirname, filename);

  return findFile(configPath, filename);
};

module.exports = function (options, configPath) {
  var meta,
      metaPath,
      config,
      finalConfig = {};

  if (!configPath) {
    metaPath = findFile(null, 'package.json');
    meta = require(metaPath);

    if (meta.sasslintConfig) {
      configPath = path.resolve(path.dirname(metaPath), meta.sasslintConfig);
    }
    else {
      configPath = findFile(null, '.sass-lint.yml');
    }
  }
  else {
    configPath = path.resolve(process.cwd(), configPath);
  }

  if (fs.existsSync(configPath)) {
    config = yaml.safeLoad(fs.readFileSync(configPath, 'utf8'));
    finalConfig = merge.recursive(defaults, config);
  }

  if (options) {
    finalConfig = merge.recursive(defaults, options);
  }

  return finalConfig;
};
<commit_msg>:bug: Fix null config when only using defaults<commit_after>'use strict';

var yaml = require('js-yaml'),
    fs = require('fs'),
    path = require('path'),
    merge = require('merge');

var defaults = yaml.safeLoad(fs.readFileSync(path.join(__dirname, 'config', 'sass-lint.yml'), 'utf8'));

var findFile = function findFile (configPath, filename) {
  var HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE,
      dirname,
      parentDirname;

  configPath = configPath || path.join(process.cwd(), filename);

  if (fs.existsSync(configPath)) {
    return fs.realpathSync(configPath);
  }

  dirname = path.dirname(configPath);
  parentDirname = path.dirname(dirname);

  if (dirname === HOME || dirname === parentDirname) {
    return null;
  }

  configPath = path.join(parentDirname, filename);

  return findFile(configPath, filename);
};

module.exports = function (options, configPath) {
  var meta,
      metaPath,
      config = {},
      finalConfig = {};

  if (!configPath) {
    metaPath = findFile(false, 'package.json');
    meta = require(metaPath);

    if (meta.sasslintConfig) {

      configPath = path.resolve(path.dirname(metaPath), meta.sasslintConfig);
    }
    else {
      configPath = findFile(false, '.sass-lint.yml');
    }
  }
  else {
    configPath = path.resolve(process.cwd(), configPath);
  }

  if (configPath) {
    if (fs.existsSync(configPath)) {
      config = yaml.safeLoad(fs.readFileSync(configPath, 'utf8'));
    }
  }

  finalConfig = merge.recursive(defaults, config);

  if (options) {
    finalConfig = merge.recursive(defaults, options);
  }

  return finalConfig;
};
<|endoftext|>


<commit_before>/**
 * provides a queue that can run schedule jobs, respecting concurrency
 * @param opts options to configure "concurrency" and "interval"
 * @param cb
 * @returns {{id: (*|NodeJS.Timer), concurrency: (*|config.concurrency|concurrency|q.concurrency), tasks: Array, running: Array, schedule: schedule, kill: kill}}
 */
module.exports = function(opts, cb) {
	var q = {
		id: setInterval(function() {
			if (q.running.length >= q.concurrency) return;
			q.tasks.forEach(function(task) {
				// make sure the task is allowed to run
				if (q.running.length >= q.concurrency) return;
				if (task.running) return;
				if (task.time > new Date().getTime()) return;
				// if we got until here, the task qualifies for execution
				task.running = true;
				q.running.push(task);
				cb(task.task, function(err) {
					// remove the task
					q.running.splice(q.running.indexOf(task), 1);
					q.tasks.splice(q.tasks.indexOf(task), 1);
				});
			});
		}, opts && opts.interval ? opts.interval : 100),
		concurrency: opts && opts.concurrency ? opts.concurrency : 10,
		tasks: [],
		running: [],
		schedule: function(offset, task) {
			q.tasks.push({ time: new Date().getTime() + offset, task: task, running: false });
		},
		kill: function() {
			clearInterval(q.id);
			tasks = [];
		}
	}
	return q;
}<commit_msg>fixed a bug in queue module<commit_after>/**
 * provides a queue that can run schedule jobs, respecting concurrency
 * @param opts options to configure "concurrency" and "interval"
 * @param cb
 * @returns {{id: (*|NodeJS.Timer), concurrency: (*|config.concurrency|concurrency|q.concurrency), tasks: Array, running: Array, schedule: schedule, kill: kill}}
 */
module.exports = function(opts, cb) {
	var q = {
		id: setInterval(function() {
			if (q.running.length >= q.concurrency) return;
			q.tasks.forEach(function(task) {
				// make sure the task is allowed to run
				if (q.running.length >= q.concurrency) return;
				if (task.running) return;
				if (task.time > new Date().getTime()) return;
				// if we got until here, the task qualifies for execution
				task.running = true;
				q.running.push(task);
				cb(task.task, function(err) {
					// remove the task
					q.running.splice(q.running.indexOf(task), 1);
					q.tasks.splice(q.tasks.indexOf(task), 1);
				});
			});
		}, opts && opts.interval ? opts.interval : 100),
		concurrency: opts && opts.concurrency ? opts.concurrency : 10,
		tasks: [],
		running: [],
		schedule: function(offset, task) {
			q.tasks.push({ time: new Date().getTime() + offset, task: task, running: false });
		},
		kill: function() {
			clearInterval(q.id);
			q.tasks = [];
		}
	}
	return q;
}<|endoftext|>


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

var tail = require('./lib/tail').tail,
    analyse = require('./lib/analyse').analyse,
    mp = require('./lib/measurement-protocol'),
    configuration = require('./lib/configuration'),
    context = mp.context(configuration.tid);

for (i in configuration.tail) {
  tail(configuration.tail[i],
    function (line) {
      var analysis = analyse(line);
      context.post(mp.convert(analysis));
    });
}
<commit_msg>minor cleanups<commit_after>#!/usr/bin/env nodejs

var tail = require('./lib/tail').tail,
    analyse = require('./lib/analyse').analyse,
    mp = require('./lib/measurement-protocol'),
    configuration = require('./lib/configuration'),
    context = mp.context(configuration.tid);

configuration.tail.forEach(function(value) {
  tail(value,
    function (line) {
      var analysis = analyse(line);
      context.post(mp.convert(analysis));
    });
});
<|endoftext|>


<commit_before>var protocol = require('./Inspector.json');
var util = require('util');
var events = require('events');
var http = require('http');
var WebSocket = require('ws');

var Chrome = function (options, notifier) {
    var self = this;
    self.host = options.host;
    self.port = options.port;
    self.chooseTab = options.chooseTab;
    self.notifier = notifier;
    self.callbacks = {};
    self.nextCommandId = 1;
    addCommandShorthands.call(self);
    connectToChrome.call(self);
};

util.inherits(Chrome, events.EventEmitter);

Chrome.prototype.send = function (method, params, callback) {
    var self = this;
    var id = self.nextCommandId++;
    if (typeof params === 'function') {
        callback = params;
        params = undefined;
    }
    var message = {'id': id, 'method': method, 'params': params};
    self.ws.send(JSON.stringify(message));
    // register command response callback
    if (typeof callback === 'function') {
        self.callbacks[id] = callback;
    }
};

Chrome.prototype.listTabs = function (callback) {
    var self = this;
    var options = {'host': self.host, 'port': self.port, 'path': '/json'};
    var request = http.get(options, function (response) {
        var data = '';
        response.on('data', function (chunk) {
            data += chunk;
        });
        response.on('end', function () {
            var tabs = JSON.parse(data);
            callback(null, tabs);
        });
    });
    request.on('error', function (error) {
        callback(error);
    });
};

Chrome.prototype.close = function () {
    var self = this;
    self.ws.removeAllListeners();
    self.ws.close();
};

function addCommand(domainName, command) {
    var self = this;
    Chrome.prototype[domainName][command.name] = function (params, callback) {
        self.send(domainName + '.' + command.name, params, callback);
    };
    Chrome.prototype[domainName][command.name].help = command;
}

function addEvent(domainName, event) {
    var self = this;
    Chrome.prototype[domainName][event.name] = function (handler) {
        self.on(domainName + '.' + event.name, handler);
    };
    Chrome.prototype[domainName][event.name].help = event;
}

function addType(domainName, type) {
    var self = this;
    Chrome.prototype[domainName][type.id] = type;
}

function addCommandShorthands() {
    var self = this;
    for (var domainIdx in protocol.domains) {
        var domain = protocol.domains[domainIdx];
        var domainName = domain.domain;
        Chrome.prototype[domainName] = {};
        // add commands
        var commands = domain.commands;
        if (commands) {
            for (var commandIdx in commands) {
                var command = commands[commandIdx];
                addCommand.call(self, domainName, command);
            }
        }
        // add events
        var events = domain.events;
        if (events) {
            for (var eventIdx in events) {
                var event = events[eventIdx];
                addEvent.call(self, domainName, event);
            }
        }
        // add types
        var types = domain.types;
        if (types) {
            for (var typeIdx in types) {
                var type = types[typeIdx];
                addType.call(self, domainName, type);
            }
        }
    }
}

function connectToChrome() {
    var self = this;
    self.listTabs(function (err, tabs) {
        if (err) {
            self.notifier.emit('error', err);
        } else {
            var tabError;
            var tab = tabs[self.chooseTab(tabs)];
            if (tab) {
                var tabDebuggerUrl = tab.webSocketDebuggerUrl;
                if (tabDebuggerUrl) {
                    connectToWebSocket.call(self, tabDebuggerUrl);
                } else {
                    // a WebSocket is already connected to this tab?
                    tabError = new Error('Unable to connect to the WebSocket');
                    self.notifier.emit('error', tabError);
                }
            } else {
                tabError = new Error('Invalid tab index');
                self.notifier.emit('error', tabError);
            }
        }
    });
}

function connectToWebSocket(url) {
    var self = this;
    self.ws = new WebSocket(url);
    self.ws.on('open', function () {
        self.notifier.emit('connect', self);
    });
    self.ws.on('message', function (data) {
        var message = JSON.parse(data);
        // command response
        if (message.id) {
            var callback = self.callbacks[message.id];
            if (callback) {
                if (message.result) {
                    callback(false, message.result);
                } else if (message.error) {
                    callback(true, message.error);
                }
                // unregister command response callback
                delete self.callbacks[message.id];
            }
        }
        // event
        else if (message.method) {
            self.emit('event', message);
            self.emit(message.method, message.params);
        }
    });
    self.ws.on('error', function (error) {
        self.notifier.emit('error', error);
    });
}

module.exports = Chrome;
<commit_msg>Change the error message if inspection is not available<commit_after>var protocol = require('./Inspector.json');
var util = require('util');
var events = require('events');
var http = require('http');
var WebSocket = require('ws');

var Chrome = function (options, notifier) {
    var self = this;
    self.host = options.host;
    self.port = options.port;
    self.chooseTab = options.chooseTab;
    self.notifier = notifier;
    self.callbacks = {};
    self.nextCommandId = 1;
    addCommandShorthands.call(self);
    connectToChrome.call(self);
};

util.inherits(Chrome, events.EventEmitter);

Chrome.prototype.send = function (method, params, callback) {
    var self = this;
    var id = self.nextCommandId++;
    if (typeof params === 'function') {
        callback = params;
        params = undefined;
    }
    var message = {'id': id, 'method': method, 'params': params};
    self.ws.send(JSON.stringify(message));
    // register command response callback
    if (typeof callback === 'function') {
        self.callbacks[id] = callback;
    }
};

Chrome.prototype.listTabs = function (callback) {
    var self = this;
    var options = {'host': self.host, 'port': self.port, 'path': '/json'};
    var request = http.get(options, function (response) {
        var data = '';
        response.on('data', function (chunk) {
            data += chunk;
        });
        response.on('end', function () {
            var tabs = JSON.parse(data);
            callback(null, tabs);
        });
    });
    request.on('error', function (error) {
        callback(error);
    });
};

Chrome.prototype.close = function () {
    var self = this;
    self.ws.removeAllListeners();
    self.ws.close();
};

function addCommand(domainName, command) {
    var self = this;
    Chrome.prototype[domainName][command.name] = function (params, callback) {
        self.send(domainName + '.' + command.name, params, callback);
    };
    Chrome.prototype[domainName][command.name].help = command;
}

function addEvent(domainName, event) {
    var self = this;
    Chrome.prototype[domainName][event.name] = function (handler) {
        self.on(domainName + '.' + event.name, handler);
    };
    Chrome.prototype[domainName][event.name].help = event;
}

function addType(domainName, type) {
    var self = this;
    Chrome.prototype[domainName][type.id] = type;
}

function addCommandShorthands() {
    var self = this;
    for (var domainIdx in protocol.domains) {
        var domain = protocol.domains[domainIdx];
        var domainName = domain.domain;
        Chrome.prototype[domainName] = {};
        // add commands
        var commands = domain.commands;
        if (commands) {
            for (var commandIdx in commands) {
                var command = commands[commandIdx];
                addCommand.call(self, domainName, command);
            }
        }
        // add events
        var events = domain.events;
        if (events) {
            for (var eventIdx in events) {
                var event = events[eventIdx];
                addEvent.call(self, domainName, event);
            }
        }
        // add types
        var types = domain.types;
        if (types) {
            for (var typeIdx in types) {
                var type = types[typeIdx];
                addType.call(self, domainName, type);
            }
        }
    }
}

function connectToChrome() {
    var self = this;
    self.listTabs(function (err, tabs) {
        if (err) {
            self.notifier.emit('error', err);
        } else {
            var tabError;
            var tab = tabs[self.chooseTab(tabs)];
            if (tab) {
                var tabDebuggerUrl = tab.webSocketDebuggerUrl;
                if (tabDebuggerUrl) {
                    connectToWebSocket.call(self, tabDebuggerUrl);
                } else {
                    // a WebSocket is already connected to this tab?
                    tabError = new Error('Chosen tab does not support inspection');
                    self.notifier.emit('error', tabError);
                }
            } else {
                tabError = new Error('Invalid tab index');
                self.notifier.emit('error', tabError);
            }
        }
    });
}

function connectToWebSocket(url) {
    var self = this;
    self.ws = new WebSocket(url);
    self.ws.on('open', function () {
        self.notifier.emit('connect', self);
    });
    self.ws.on('message', function (data) {
        var message = JSON.parse(data);
        // command response
        if (message.id) {
            var callback = self.callbacks[message.id];
            if (callback) {
                if (message.result) {
                    callback(false, message.result);
                } else if (message.error) {
                    callback(true, message.error);
                }
                // unregister command response callback
                delete self.callbacks[message.id];
            }
        }
        // event
        else if (message.method) {
            self.emit('event', message);
            self.emit(message.method, message.params);
        }
    });
    self.ws.on('error', function (error) {
        self.notifier.emit('error', error);
    });
}

module.exports = Chrome;
<|endoftext|>


<commit_before>var SugarClient = require('sugar-client');
var JSONAPIClient = require('json-api-client');
var auth = require('./auth');
var config = require('./config');

if (typeof window !== 'undefined') {
  SugarClient.Primus = require('sugar-client/primus');
  SugarClient.host = config.sugarHost;

  var sugarApiClient = new JSONAPIClient(config.sugarHost, {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  });

  var sugarClient = new SugarClient();

  auth.listen('change', function() {
    auth.checkCurrent()
      .then(function(user) {
        if (user && auth._bearerToken) {
          sugarClient.userId = user.id;
          sugarClient.authToken = auth._bearerToken;

          if (process.env.NODE_ENV !== 'production') {
            sugarClient.on('response', function() {
              var args = Array.prototype.slice.call(arguments);
              console.log.apply(console, ['[SUGAR RESPONSE]'].concat(args));
            });
          }

          sugarClient.connect();
        } else {
          sugarClient.disconnect();
        }
      })
      .catch(function(e) {
        throw new Error('Failed to checkCurrent auth from sugar client');
      });
  });

  module.exports = {
    sugarClient: sugarClient,
    sugarApiClient: sugarApiClient,
  };
}
<commit_msg>Sugar needs a navigator<commit_after>var SugarClient = require('sugar-client');
var JSONAPIClient = require('json-api-client');
var auth = require('./auth');
var config = require('./config');

if (typeof navigator !== 'undefined') {
  SugarClient.Primus = require('sugar-client/primus');
  SugarClient.host = config.sugarHost;

  var sugarApiClient = new JSONAPIClient(config.sugarHost, {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  });

  var sugarClient = new SugarClient();

  auth.listen('change', function() {
    auth.checkCurrent()
      .then(function(user) {
        if (user && auth._bearerToken) {
          sugarClient.userId = user.id;
          sugarClient.authToken = auth._bearerToken;

          if (process.env.NODE_ENV !== 'production') {
            sugarClient.on('response', function() {
              var args = Array.prototype.slice.call(arguments);
              console.log.apply(console, ['[SUGAR RESPONSE]'].concat(args));
            });
          }

          sugarClient.connect();
        } else {
          sugarClient.disconnect();
        }
      })
      .catch(function(e) {
        throw new Error('Failed to checkCurrent auth from sugar client');
      });
  });

  module.exports = {
    sugarClient: sugarClient,
    sugarApiClient: sugarApiClient,
  };
}
<|endoftext|>


<commit_before>'use strict';
const nconf = require('nconf'),
      os = require('os');

nconf
    .argv()
    .env()
    .add('configfile-default', {
        type: 'literal',
        conf: '/etc/fritz.json'
    })
    .file({file: nconf.get('conf')})
    .defaults({
        listen: {
            host: '127.0.0.1',
            port: 5555,
            // clients which send messages larger than this value will be dropped
            maxMessageLength: 1024 * 1024, // 1 MB
        },
        forward: {
            // required 'host'
            port: 5555,
            minFlushBufferSize: 10 * 1024,
            maxBufferSize: 10 * 1024 * 1024,
            maxFlushInterval: 1000,
            flushTimeout: 60000,
            reconnectTimeout: 1000,
        },
        log: {
            level: 'warn', // one of { error,  warn,  info,  verbose,  debug,  silly }
            file: '/var/log/fritz.log', // omit file to disable logging to file
            console: 'color' // one of {color, no-color}, omit to disable console logging
        },
        hostname: os.hostname()
    });

const required = ['forward:host'];
for (const key of required) {
    if (typeof nconf.get(key) === 'undefined') {
        throw new Error('Config error: key ' + key + ' not supplied');
    }
}

module.exports = {nconf};
<commit_msg>pass riemann host as env arg in addition<commit_after>'use strict';
const nconf = require('nconf'),
      os = require('os');

nconf
    .argv()
    .env()
    .add('configfile-default', {
        type: 'literal',
        conf: '/etc/fritz.json'
    })
    .file({file: nconf.get('conf')})
    .defaults({
        listen: {
            host: '127.0.0.1',
            port: 5555,
            // clients which send messages larger than this value will be dropped
            maxMessageLength: 1024 * 1024, // 1 MB
        },
        forward: {
            host: nconf.get('RIEMANN_HOST'),
            port: 5555,
            minFlushBufferSize: 10 * 1024,
            maxBufferSize: 10 * 1024 * 1024,
            maxFlushInterval: 1000,
            flushTimeout: 60000,
            reconnectTimeout: 1000,
        },
        log: {
            level: 'warn', // one of { error,  warn,  info,  verbose,  debug,  silly }
            file: '/var/log/fritz.log', // omit file to disable logging to file
            console: 'color' // one of {color, no-color}, omit to disable console logging
        },
        hostname: os.hostname()
    });

const required = ['forward:host'];
for (const key of required) {
    if (typeof nconf.get(key) === 'undefined') {
        throw new Error('Config error: key ' + key + ' not supplied');
    }
}

module.exports = {nconf};
<|endoftext|>


<commit_before>"use strict";

const Queue = require("promise-queue");
const config = require('config');
const _ = require('underscore');
const moment = require('moment');
const pace = require('pace')(1);

const cacheHelper = require('./helpers/cache');
const request = require('./request');
const taskManager = require('./taskManager');
const taskHelper = require('./helpers/task');
const log = require("./helpers/logger");
const requestFactory = require("./requestFactory").requestFactory;

const maxConcurrent = process.env.MAX_PARALLEL_TASKS ||
    (config.has('app.max_parallel_tasks') ? config.get('app.max_parallel_tasks') : 3);
const maxQueue = Infinity;
const queue = new Queue(maxConcurrent, maxQueue);

/**
 *
 * Pull results from different response formats
 *
 * @param api_resource - analyze or task
 * @param response - the response object
 * @returns {*}
 */
const normalizeResponse = function normalizeResponse(api_resource, response){

    switch (api_resource) {
        case "analyze":
            log.trace("Returning normalised result for /analyze", JSON.stringify(response.analysis.results, undefined, 4));
            return response.analysis.results;
        case "task":
            log.trace("Returning normalised result for /task", JSON.stringify(response.result.analysis.results, undefined, 4));
            return response.result.analysis.results;
    }
};

/**
 * @param {normalizedTask} - the normalizedTask obj that generated the response
 * @param {response} - the response obj from the request
 * @returns {*}
 */
const responseHandler = function(normalizedTask, response){

    let normalizedResponse = normalizeResponse(normalizedTask.api_resource, response);

    //log.trace("PROCESSING normalizedTask:", JSON.stringify(normalizedTask, undefined, 4));
    //log.trace("PROCESSING RESPONSE:", JSON.stringify(normalizedTask, undefined, 4));

    if (_.has(normalizedTask, 'then')) {

        let nextTasks = taskManager.buildNextTasks(normalizedTask, normalizedResponse);

        //Add new tasks to queue. Return a promise that will resolve
        //only once all the items in array have resolved.
        return Promise.all(nextTasks.map(function(each) {

            const requestObject = requestFactory(each);
            return queueRequest(requestObject, each);

        })).then(function(p){
            log.trace("Response handler returning with compact objects...");

            // remove undefined and nulls caused by unresolved
            // promises due to recursion
            return taskHelper.compact(p);
        });
    }

    //convert any timeSeries results from unix to human
    normalizedResponse = taskHelper.resUnixTsToHuman(normalizedTask.analysis_type, normalizedResponse);

    if (_.has(normalizedTask, 'cache')) {

        log.trace("Response requestObj has CACHE object");
        cacheHelper.addData(normalizedTask.cache.cacheId, normalizedTask.cache.mergeKey, normalizedResponse);

        let cacheData = cacheHelper.get(normalizedTask.cache.cacheId);

        if (cacheData.remainingTasks === 0) {
            log.trace("Response handler returning with remaining tasks = 0...");

            delete cacheData.remainingTasks;
            return [cacheData]; //format as array of objects for csv parser

        } else {
            log.trace("Response handler returning with remaining tasks > 0...");
            return;
        }
    }

    if (_.has(normalizedTask, 'then') === false && _.has(normalizedTask, 'cache') === false) {
        log.trace("Response handler returning with no THEN or CACHE objects...");
        return normalizedResponse;
    }
};

/**
 * queueRequest - add request obj to queue and pass
 * the results to the responseHandler()
 *
 * @param requestObj - a request object
 * @returns {LocalPromise}
 */
const queueRequest = function queueRequest(requestObj, normalizedTask) {
    return queue.add(function () {

        return request.make(requestObj);
    }).then(response => {

        return response;
    }).then(response => {

/*
        console.log("=============================================");
        console.log("requestObj", JSON.stringify(requestObj, undefined, 4));
        console.log("=============================================");
        console.log("response", JSON.stringify(response, undefined, 4));
        console.log("=============================================");
        console.log("normalizedTask", JSON.stringify(normalizedTask, undefined, 4));
        console.log("=============================================");
*/

        if(normalizedTask.api_resource === "analyze"){

            log.trace("Handling response from /analyze..");

            return responseHandler(normalizedTask, response);

        } else {

            log.trace("Polling for response from /task...");

            return request.recursivePoll(normalizedTask, response);

        }

    }).catch(function (err) {

        if(err.error && err.error.error){
            log.error(err.statusCode, err.error.error);
        } else {
            log.error(err);
        }

        log.info(JSON.stringify(requestObj, undefined, 4));
        process.exit(1);
    });
};

exports.queueRequest = queueRequest;
exports.responseHandler = responseHandler;
<commit_msg>Better debugging on error. Disable process kill on error.<commit_after>"use strict";

const Queue = require("promise-queue");
const config = require('config');
const _ = require('underscore');
const moment = require('moment');
const pace = require('pace')(1);

const cacheHelper = require('./helpers/cache');
const request = require('./request');
const taskManager = require('./taskManager');
const taskHelper = require('./helpers/task');
const log = require("./helpers/logger");
const requestFactory = require("./requestFactory").requestFactory;

const maxConcurrent = process.env.MAX_PARALLEL_TASKS ||
    (config.has('app.max_parallel_tasks') ? config.get('app.max_parallel_tasks') : 3);
const maxQueue = Infinity;
const queue = new Queue(maxConcurrent, maxQueue);

/**
 *
 * Pull results from different response formats
 *
 * @param api_resource - analyze or task
 * @param response - the response object
 * @returns {*}
 */
const normalizeResponse = function normalizeResponse(api_resource, response){

    switch (api_resource) {
        case "analyze":
            log.trace("Returning normalised result for /analyze", JSON.stringify(response.analysis.results, undefined, 4));
            return response.analysis.results;
        case "task":
            log.trace("Returning normalised result for /task", JSON.stringify(response.result.analysis.results, undefined, 4));
            return response.result.analysis.results;
    }
};

/**
 * @param {normalizedTask} - the normalizedTask obj that generated the response
 * @param {response} - the response obj from the request
 * @returns {*}
 */
const responseHandler = function(normalizedTask, response){

    let normalizedResponse = normalizeResponse(normalizedTask.api_resource, response);

    //log.trace("PROCESSING normalizedTask:", JSON.stringify(normalizedTask, undefined, 4));
    //log.trace("PROCESSING RESPONSE:", JSON.stringify(normalizedTask, undefined, 4));

    if (_.has(normalizedTask, 'then')) {

        let nextTasks = taskManager.buildNextTasks(normalizedTask, normalizedResponse);

        //Add new tasks to queue. Return a promise that will resolve
        //only once all the items in array have resolved.
        return Promise.all(nextTasks.map(function(each) {

            const requestObject = requestFactory(each);
            return queueRequest(requestObject, each);

        })).then(function(p){
            log.trace("Response handler returning with compact objects...");

            // remove undefined and nulls caused by unresolved
            // promises due to recursion
            return taskHelper.compact(p);
        });
    }

    //convert any timeSeries results from unix to human
    normalizedResponse = taskHelper.resUnixTsToHuman(normalizedTask.analysis_type, normalizedResponse);

    if (_.has(normalizedTask, 'cache')) {

        log.trace("Response requestObj has CACHE object");
        cacheHelper.addData(normalizedTask.cache.cacheId, normalizedTask.cache.mergeKey, normalizedResponse);

        let cacheData = cacheHelper.get(normalizedTask.cache.cacheId);

        if (cacheData.remainingTasks === 0) {
            log.trace("Response handler returning with remaining tasks = 0...");

            delete cacheData.remainingTasks;
            return [cacheData]; //format as array of objects for csv parser

        } else {
            log.trace("Response handler returning with remaining tasks > 0...");
            return;
        }
    }

    if (_.has(normalizedTask, 'then') === false && _.has(normalizedTask, 'cache') === false) {
        log.trace("Response handler returning with no THEN or CACHE objects...");
        return normalizedResponse;
    }
};

/**
 * queueRequest - add request obj to queue and pass
 * the results to the responseHandler()
 *
 * @param requestObj - a request object
 * @returns {LocalPromise}
 */
const queueRequest = function queueRequest(requestObj, normalizedTask) {
    return queue.add(function () {

        return request.make(requestObj);
    }).then(response => {

        return response;
    }).then(response => {

/*
        console.log("=============================================");
        console.log("requestObj", JSON.stringify(requestObj, undefined, 4));
        console.log("=============================================");
        console.log("response", JSON.stringify(response, undefined, 4));
        console.log("=============================================");
        console.log("normalizedTask", JSON.stringify(normalizedTask, undefined, 4));
        console.log("=============================================");
*/

        if(normalizedTask.api_resource === "analyze"){

            log.trace("Handling response from /analyze..");

            return responseHandler(normalizedTask, response);

        } else {

            log.trace("Polling for response from /task...");

            return request.recursivePoll(normalizedTask, response);

        }

    }).catch(function (err) {

        if(err.error && err.error.error){
            log.error("MESSAGE:", err.error.error);
            log.error("CODE:", err.statusCode);
            log.error("REQUEST:",JSON.stringify(requestObj, undefined, 4));
        } else {
            log.error(err);
        }

        //process.exit(1);

    });
};

exports.queueRequest = queueRequest;
exports.responseHandler = responseHandler;
<|endoftext|>