<commit_before>/* DOM Level2 Events implemented as described here:
 *
 * http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
 *
 */
var core = require("./core").dom.level2.core,
    utils = require("../utils"),
    sys = require("sys");

// modify cloned instance for more info check: https://github.com/tmpvar/jsdom/issues/325
core = Object.create(core);

var events = {};

events.EventException = function() {
    if (arguments.length > 0) {
        this._code = arguments[0];
    } else {
        this._code = 0;
    }
    if (arguments.length > 1) {
        this._message = arguments[1];
    } else {
        this._message = "Unspecified event type";
    }
    Error.call(this, this._message);
    if (Error.captureStackTrace) {
        Error.captureStackTrace(this, events.EventException);
    }
};
events.EventException.prototype = {
  UNSPECIFIED_EVENT_TYPE_ERR : 0,
  get code() { return this._code;}
};
events.EventException.prototype.__proto__ = Error.prototype;

events.Event = function(eventType) {
    this._eventType = eventType;
    this._type = null;
    this._bubbles = null;
    this._cancelable = null;
    this._target = null;
    this._currentTarget = null;
    this._eventPhase = null;
    this._timeStamp = null;
    this._preventDefault = false;
    this._stopPropagation = false;
};
events.Event.prototype = {
    initEvent: function(type, bubbles, cancelable) {
        this._type = type;
        this._bubbles = bubbles;
        this._cancelable = cancelable;
    },
    preventDefault: function() {
        if (this._cancelable) {
            this._preventDefault = true;
        }
    },
    stopPropagation: function() {
        this._stopPropagation = true;
    },
    CAPTURING_PHASE : 1,
    AT_TARGET       : 2,
    BUBBLING_PHASE  : 3,
    get eventType() { return this._eventType; },
    get type() { return this._type; },
    get bubbles() { return this._bubbles; },
    get cancelable() { return this._cancelable; },
    get target() { return this._target; },
    get currentTarget() { return this._currentTarget; },
    get eventPhase() { return this._eventPhase; },
    get timeStamp() { return this._timeStamp; }
};

events.HTMLEvent = function(eventType) {
    events.Event.call(this, eventType);
};
events.HTMLEvent.prototype.__proto__ = events.Event.prototype;

events.UIEvent = function(eventType) {
    events.Event.call(this, eventType);
    this.view = null;
    this.detail = null;
};
events.UIEvent.prototype = {
    initUIEvent: function(type, bubbles, cancelable, view, detail) {
        this.initEvent(type, bubbles, cancelable);
        this.view = view;
        this.detail = detail;
    },
};
events.UIEvent.prototype.__proto__ = events.Event.prototype;

events.MouseEvent = function(eventType) {
    events.UIEvent.call(this, eventType);
    this.screenX = null;
    this.screenY = null;
    this.clientX = null;
    this.clientY = null;
    this.ctrlKey = null;
    this.shiftKey = null;
    this.altKey = null;
    this.metaKey = null;
    this.button = null;
    this.relatedTarget = null;
};
events.MouseEvent.prototype = {
    initMouseEvent:   function(type,
                               bubbles,
                               cancelable,
                               view,
                               detail,
                               screenX,
                               screenY,
                               clientX,
                               clientY,
                               ctrlKey,
                               altKey,
                               shiftKey,
                               metaKey,
                               button,
                               relatedTarget) {
        this.initUIEvent(type, bubbles, cancelable, view, detail);
        this.screenX  = screenX
        this.screenY  = screenY
        this.clientX  = clientX
        this.clientY  = clientY
        this.ctrlKey  = ctrlKey
        this.shiftKey  = shiftKey
        this.altKey  = altKey
        this.metaKey  = metaKey
        this.button  = button
        this.relatedTarget  = relatedTarget
    }
};
events.MouseEvent.prototype.__proto__ = events.UIEvent.prototype;

events.MutationEvent = function(eventType) {
    events.Event.call(this, eventType);
    this.relatedNode = null;
    this.prevValue = null;
    this.newValue = null;
    this.attrName = null;
    this.attrChange = null;
};
events.MutationEvent.prototype = {
    initMutationEvent:   function(type,
                                  bubbles,
                                  cancelable,
                                  relatedNode,
                                  prevValue,
                                  newValue,
                                  attrName,
                                  attrChange) {
        this.initEvent(type, bubbles, cancelable);
        this.relatedNode = relatedNode;
        this.prevValue = prevValue;
        this.newValue = newValue;
        this.attrName = attrName;
        this.attrChange = attrChange;
    },
    MODIFICATION : 1,
    ADDITION     : 2,
    REMOVAL      : 3
};
events.MutationEvent.prototype.__proto__ = events.Event.prototype;

events.EventTarget = function() {};

events.EventTarget.getListeners = function getListeners(target, type, capturing) {
    var listeners = target._listeners
            && target._listeners[type]
            && target._listeners[type][capturing];
    if (listeners && listeners.length) {
        return listeners;
    }
    return [];
};

events.EventTarget.dispatch = function dispatch(event, iterator, capturing) {
    var listeners,
        currentListener,
        target = iterator();

    while (target && !event._stopPropagation) {
        listeners = events.EventTarget.getListeners(target, event._type, capturing);
        currentListener = listeners.length;
        while (currentListener--) {
            event._currentTarget = target;
            try {
              listeners[currentListener].call(target, event);
            } catch (e) {
              target.raise(
                'error', "Dispatching event '" + event._type + "' failed",
                {error: e, event: event}
              );
            }
        }
        target = iterator();
    }
    return !event._stopPropagation;
};

events.EventTarget.forwardIterator = function forwardIterator(list) {
  var i = 0, len = list.length;
  return function iterator() { return i < len ? list[i++] : null };
};

events.EventTarget.backwardIterator = function backwardIterator(list) {
  var i = list.length;
  return function iterator() { return i >=0 ? list[--i] : null };
};

events.EventTarget.singleIterator = function singleIterator(obj) {
  var i = 1;
  return function iterator() { return i-- ? obj : null };
};

events.EventTarget.prototype = {
    addEventListener: function(type, listener, capturing) {
        this._listeners = this._listeners || {};
        var listeners = this._listeners[type] || {};
        capturing = (capturing === true);
        var capturingListeners = listeners[capturing] || [];
        for (var i=0; i < capturingListeners.length; i++) {
            if (capturingListeners[i] === listener) {
                return;
            }
        }
        capturingListeners.push(listener);
        listeners[capturing] = capturingListeners;
        this._listeners[type] = listeners;
    },

    removeEventListener: function(type, listener, capturing) {
        var listeners  = this._listeners && this._listeners[type];
        if (!listeners) return;
        var capturingListeners = listeners[(capturing === true)];
        if (!capturingListeners) return;
        for (var i=0; i < capturingListeners.length; i++) {
            if (capturingListeners[i] === listener) {
                capturingListeners.splice(i, 1);
                return;
            }
        }
    },

    dispatchEvent: function(event) {
        if (event == null) {
            throw new events.EventException(0, "Null event");
        }
        if (event._type == null || event._type == "") {
            throw new events.EventException(0, "Uninitialized event");
        }

        var targetList = [];

        event._target = this;

        //per the spec we gather the list of targets first to ensure
        //against dom modifications during actual event dispatch
        var target = this,
            targetParent = target._parentNode;
        while (targetParent) {
            targetList.push(targetParent);
            target = targetParent;
            targetParent = target._parentNode;
        }
        targetParent = target._parentWindow;
        if (targetParent) {
            targetList.push(targetParent);
        }

        var iterator = events.EventTarget.backwardIterator(targetList);

        event._eventPhase = event.CAPTURING_PHASE;
        if (!events.EventTarget.dispatch(event, iterator, true)) return event._preventDefault;

        iterator = events.EventTarget.singleIterator(event._target);
        event._eventPhase = event.AT_TARGET;
        if (!events.EventTarget.dispatch(event, iterator, false)) return event._preventDefault;

        var traditionalHandler = this["on" + event._type];
        var implementation;

        if (this._ownerDocument) {
          implementation = this._ownerDocument.implementation;
        } else {
          implementation = this.document.implementation;
        }

        if (traditionalHandler && implementation.hasFeature('ProcessExternalResources', 'script')) {
          try {
            if (traditionalHandler(event) === false) {
              return true;
            }
          }
          catch (e) {
            event._target.raise(
              'error', "Dispatching event '" + event._type + "' failed.",
              {error: e, event: event}
            );
          }
        }

        if (event._bubbles && !event._stopPropagation) {
            var i = 0;
            iterator = events.EventTarget.forwardIterator(targetList);
            event._eventPhase = event.BUBBLING_PHASE;
            events.EventTarget.dispatch(event, iterator, false);
        }

        return event._preventDefault;
    }

};

core.Node.prototype.__proto__ = events.EventTarget.prototype;

function getDocument(el) {
  return el.nodeType == core.Node.DOCUMENT_NODE ? el : el._ownerDocument;
}

function mutationEventsEnabled(el) {
  return el.nodeType != core.Node.ATTRIBUTE_NODE &&
         getDocument(el).implementation.hasFeature('MutationEvents');
}

utils.intercept(core.Node, 'insertBefore', function(_super, args, newChild, refChild) {
  var ret = _super.apply(this, args);
  if (mutationEventsEnabled(this)) {
    var doc = getDocument(this),
        ev = doc.createEvent("MutationEvents");

    ev.initMutationEvent("DOMNodeInserted", true, false, this, null, null, null, null);
    newChild.dispatchEvent(ev);
    if (this.nodeType == core.Node.DOCUMENT_NODE || this._attachedToDocument) {
      ev = doc.createEvent("MutationEvents");
      ev.initMutationEvent("DOMNodeInsertedIntoDocument", false, false, null, null, null, null, null);
      core.visitTree(newChild, function(el) {
        if (el.nodeType == core.Node.ELEMENT_NODE) {
          el.dispatchEvent(ev);
          el._attachedToDocument = true;
        }
      });
    }
  }
  return ret;
});

utils.intercept(core.Node, 'removeChild', function (_super, args, oldChild) {
  if (mutationEventsEnabled(this)) {
    var doc = getDocument(this),
        ev = doc.createEvent("MutationEvents");

    ev.initMutationEvent("DOMNodeRemoved", true, false, this, null, null, null, null);
    oldChild.dispatchEvent(ev);

    ev = doc.createEvent("MutationEvents");
    ev.initMutationEvent("DOMNodeRemovedFromDocument", false, false, null, null, null, null, null);
    core.visitTree(oldChild, function(el) {
      if (el.nodeType == core.Node.ELEMENT_NODE) {
        el.dispatchEvent(ev);
        el._attachedToDocument = false;
      }
    });
  }
  return _super.apply(this, args);
});

function dispatchAttrEvent(change) {
  return function(_super, args, node) {
    var target = this._parentNode,
        prev = _super.apply(this, args);

    if (mutationEventsEnabled(target)) {
      var doc = target._ownerDocument,
          attrChange = events.MutationEvent.prototype[change],
          attrName = prev && prev.name || node.name,
          prevVal = prev && prev.value || null,
          newVal = change == 'ADDITION' ? node.value : null,
          ev;

      if (!newVal || newVal != prevVal) {
        ev = doc.createEvent("MutationEvents");
        ev.initMutationEvent("DOMAttrModified", true, false, target, prevVal, newVal, attrName, attrChange);
        target.dispatchEvent(ev);
      }
    }
    return prev;
  }
}

utils.intercept(core.AttrNodeMap, 'removeNamedItem', dispatchAttrEvent('REMOVAL'));
utils.intercept(core.AttrNodeMap, 'setNamedItem', dispatchAttrEvent('ADDITION'));

core.CharacterData.prototype.__defineGetter__("_nodeValue", function() {
  return this.__nodeValue;
});
core.CharacterData.prototype.__defineSetter__("_nodeValue", function(value) {
  var oldValue = this.__nodeValue;
  this.__nodeValue = value;
  if (this._ownerDocument && this._parentNode && mutationEventsEnabled(this)) {
    var ev = this._ownerDocument.createEvent("MutationEvents")
    ev.initMutationEvent("DOMCharacterDataModified", true, false, this, oldValue, value, null, null);
    this.dispatchEvent(ev);
  }
});

core.Document.prototype.createEvent = function(eventType) {
    switch (eventType) {
        case "MutationEvents": return new events.MutationEvent(eventType);
        case "UIEvents": return new events.UIEvent(eventType);
        case "MouseEvents": return new events.MouseEvent(eventType);
        case "HTMLEvents": return new events.HTMLEvent(eventType);
    }
    return new events.Event(eventType);
};

exports.dom =
{
  level2 : {
    core   : core,
    events : events
  }
};

<commit_msg>Fix for attribute handlers in bubbling phase.<commit_after>/* DOM Level2 Events implemented as described here:
 *
 * http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
 *
 */
var core = require("./core").dom.level2.core,
    utils = require("../utils"),
    sys = require("sys");

// modify cloned instance for more info check: https://github.com/tmpvar/jsdom/issues/325
core = Object.create(core);

var events = {};

events.EventException = function() {
    if (arguments.length > 0) {
        this._code = arguments[0];
    } else {
        this._code = 0;
    }
    if (arguments.length > 1) {
        this._message = arguments[1];
    } else {
        this._message = "Unspecified event type";
    }
    Error.call(this, this._message);
    if (Error.captureStackTrace) {
        Error.captureStackTrace(this, events.EventException);
    }
};
events.EventException.prototype = {
  UNSPECIFIED_EVENT_TYPE_ERR : 0,
  get code() { return this._code;}
};
events.EventException.prototype.__proto__ = Error.prototype;

events.Event = function(eventType) {
    this._eventType = eventType;
    this._type = null;
    this._bubbles = null;
    this._cancelable = null;
    this._target = null;
    this._currentTarget = null;
    this._eventPhase = null;
    this._timeStamp = null;
    this._preventDefault = false;
    this._stopPropagation = false;
};
events.Event.prototype = {
    initEvent: function(type, bubbles, cancelable) {
        this._type = type;
        this._bubbles = bubbles;
        this._cancelable = cancelable;
    },
    preventDefault: function() {
        if (this._cancelable) {
            this._preventDefault = true;
        }
    },
    stopPropagation: function() {
        this._stopPropagation = true;
    },
    CAPTURING_PHASE : 1,
    AT_TARGET       : 2,
    BUBBLING_PHASE  : 3,
    get eventType() { return this._eventType; },
    get type() { return this._type; },
    get bubbles() { return this._bubbles; },
    get cancelable() { return this._cancelable; },
    get target() { return this._target; },
    get currentTarget() { return this._currentTarget; },
    get eventPhase() { return this._eventPhase; },
    get timeStamp() { return this._timeStamp; }
};

events.HTMLEvent = function(eventType) {
    events.Event.call(this, eventType);
};
events.HTMLEvent.prototype.__proto__ = events.Event.prototype;

events.UIEvent = function(eventType) {
    events.Event.call(this, eventType);
    this.view = null;
    this.detail = null;
};
events.UIEvent.prototype = {
    initUIEvent: function(type, bubbles, cancelable, view, detail) {
        this.initEvent(type, bubbles, cancelable);
        this.view = view;
        this.detail = detail;
    },
};
events.UIEvent.prototype.__proto__ = events.Event.prototype;

events.MouseEvent = function(eventType) {
    events.UIEvent.call(this, eventType);
    this.screenX = null;
    this.screenY = null;
    this.clientX = null;
    this.clientY = null;
    this.ctrlKey = null;
    this.shiftKey = null;
    this.altKey = null;
    this.metaKey = null;
    this.button = null;
    this.relatedTarget = null;
};
events.MouseEvent.prototype = {
    initMouseEvent:   function(type,
                               bubbles,
                               cancelable,
                               view,
                               detail,
                               screenX,
                               screenY,
                               clientX,
                               clientY,
                               ctrlKey,
                               altKey,
                               shiftKey,
                               metaKey,
                               button,
                               relatedTarget) {
        this.initUIEvent(type, bubbles, cancelable, view, detail);
        this.screenX  = screenX
        this.screenY  = screenY
        this.clientX  = clientX
        this.clientY  = clientY
        this.ctrlKey  = ctrlKey
        this.shiftKey  = shiftKey
        this.altKey  = altKey
        this.metaKey  = metaKey
        this.button  = button
        this.relatedTarget  = relatedTarget
    }
};
events.MouseEvent.prototype.__proto__ = events.UIEvent.prototype;

events.MutationEvent = function(eventType) {
    events.Event.call(this, eventType);
    this.relatedNode = null;
    this.prevValue = null;
    this.newValue = null;
    this.attrName = null;
    this.attrChange = null;
};
events.MutationEvent.prototype = {
    initMutationEvent:   function(type,
                                  bubbles,
                                  cancelable,
                                  relatedNode,
                                  prevValue,
                                  newValue,
                                  attrName,
                                  attrChange) {
        this.initEvent(type, bubbles, cancelable);
        this.relatedNode = relatedNode;
        this.prevValue = prevValue;
        this.newValue = newValue;
        this.attrName = attrName;
        this.attrChange = attrChange;
    },
    MODIFICATION : 1,
    ADDITION     : 2,
    REMOVAL      : 3
};
events.MutationEvent.prototype.__proto__ = events.Event.prototype;

events.EventTarget = function() {};

events.EventTarget.getListeners = function getListeners(target, type, capturing) {
    var listeners = target._listeners
            && target._listeners[type]
            && target._listeners[type][capturing] || [];
    if (!capturing) {
        var traditionalHandler = target['on' + type];
        if (traditionalHandler) {
            var implementation = (target._ownerDocument ? target._ownerDocument.implementation
                                                        : target.document.implementation);

            if (implementation.hasFeature('ProcessExternalResources', 'script')) {
                listeners.push(traditionalHandler);
            }
        }
    }
    return listeners;
};

events.EventTarget.dispatch = function dispatch(event, iterator, capturing) {
    var listeners,
        currentListener,
        target = iterator();

    while (target && !event._stopPropagation) {
        listeners = events.EventTarget.getListeners(target, event._type, capturing);
        currentListener = listeners.length;
        while (currentListener--) {
            event._currentTarget = target;
            try {
              listeners[currentListener].call(target, event);
            } catch (e) {
              target.raise(
                'error', "Dispatching event '" + event._type + "' failed",
                {error: e, event: event}
              );
            }
        }
        target = iterator();
    }
    return !event._stopPropagation;
};

events.EventTarget.forwardIterator = function forwardIterator(list) {
  var i = 0, len = list.length;
  return function iterator() { return i < len ? list[i++] : null };
};

events.EventTarget.backwardIterator = function backwardIterator(list) {
  var i = list.length;
  return function iterator() { return i >=0 ? list[--i] : null };
};

events.EventTarget.singleIterator = function singleIterator(obj) {
  var i = 1;
  return function iterator() { return i-- ? obj : null };
};

events.EventTarget.prototype = {
    addEventListener: function(type, listener, capturing) {
        this._listeners = this._listeners || {};
        var listeners = this._listeners[type] || {};
        capturing = (capturing === true);
        var capturingListeners = listeners[capturing] || [];
        for (var i=0; i < capturingListeners.length; i++) {
            if (capturingListeners[i] === listener) {
                return;
            }
        }
        capturingListeners.push(listener);
        listeners[capturing] = capturingListeners;
        this._listeners[type] = listeners;
    },

    removeEventListener: function(type, listener, capturing) {
        var listeners  = this._listeners && this._listeners[type];
        if (!listeners) return;
        var capturingListeners = listeners[(capturing === true)];
        if (!capturingListeners) return;
        for (var i=0; i < capturingListeners.length; i++) {
            if (capturingListeners[i] === listener) {
                capturingListeners.splice(i, 1);
                return;
            }
        }
    },

    dispatchEvent: function(event) {
        if (event == null) {
            throw new events.EventException(0, "Null event");
        }
        if (event._type == null || event._type == "") {
            throw new events.EventException(0, "Uninitialized event");
        }

        var targetList = [];

        event._target = this;

        //per the spec we gather the list of targets first to ensure
        //against dom modifications during actual event dispatch
        var target = this,
            targetParent = target._parentNode;
        while (targetParent) {
            targetList.push(targetParent);
            target = targetParent;
            targetParent = target._parentNode;
        }
        targetParent = target._parentWindow;
        if (targetParent) {
            targetList.push(targetParent);
        }

        var iterator = events.EventTarget.backwardIterator(targetList);

        event._eventPhase = event.CAPTURING_PHASE;
        if (!events.EventTarget.dispatch(event, iterator, true)) return event._preventDefault;

        iterator = events.EventTarget.singleIterator(event._target);
        event._eventPhase = event.AT_TARGET;
        if (!events.EventTarget.dispatch(event, iterator, false)) return event._preventDefault;

        if (event._bubbles && !event._stopPropagation) {
            var i = 0;
            iterator = events.EventTarget.forwardIterator(targetList);
            event._eventPhase = event.BUBBLING_PHASE;
            events.EventTarget.dispatch(event, iterator, false);
        }

        return event._preventDefault;
    }

};

core.Node.prototype.__proto__ = events.EventTarget.prototype;

function getDocument(el) {
  return el.nodeType == core.Node.DOCUMENT_NODE ? el : el._ownerDocument;
}

function mutationEventsEnabled(el) {
  return el.nodeType != core.Node.ATTRIBUTE_NODE &&
         getDocument(el).implementation.hasFeature('MutationEvents');
}

utils.intercept(core.Node, 'insertBefore', function(_super, args, newChild, refChild) {
  var ret = _super.apply(this, args);
  if (mutationEventsEnabled(this)) {
    var doc = getDocument(this),
        ev = doc.createEvent("MutationEvents");

    ev.initMutationEvent("DOMNodeInserted", true, false, this, null, null, null, null);
    newChild.dispatchEvent(ev);
    if (this.nodeType == core.Node.DOCUMENT_NODE || this._attachedToDocument) {
      ev = doc.createEvent("MutationEvents");
      ev.initMutationEvent("DOMNodeInsertedIntoDocument", false, false, null, null, null, null, null);
      core.visitTree(newChild, function(el) {
        if (el.nodeType == core.Node.ELEMENT_NODE) {
          el.dispatchEvent(ev);
          el._attachedToDocument = true;
        }
      });
    }
  }
  return ret;
});

utils.intercept(core.Node, 'removeChild', function (_super, args, oldChild) {
  if (mutationEventsEnabled(this)) {
    var doc = getDocument(this),
        ev = doc.createEvent("MutationEvents");

    ev.initMutationEvent("DOMNodeRemoved", true, false, this, null, null, null, null);
    oldChild.dispatchEvent(ev);

    ev = doc.createEvent("MutationEvents");
    ev.initMutationEvent("DOMNodeRemovedFromDocument", false, false, null, null, null, null, null);
    core.visitTree(oldChild, function(el) {
      if (el.nodeType == core.Node.ELEMENT_NODE) {
        el.dispatchEvent(ev);
        el._attachedToDocument = false;
      }
    });
  }
  return _super.apply(this, args);
});

function dispatchAttrEvent(change) {
  return function(_super, args, node) {
    var target = this._parentNode,
        prev = _super.apply(this, args);

    if (mutationEventsEnabled(target)) {
      var doc = target._ownerDocument,
          attrChange = events.MutationEvent.prototype[change],
          attrName = prev && prev.name || node.name,
          prevVal = prev && prev.value || null,
          newVal = change == 'ADDITION' ? node.value : null,
          ev;

      if (!newVal || newVal != prevVal) {
        ev = doc.createEvent("MutationEvents");
        ev.initMutationEvent("DOMAttrModified", true, false, target, prevVal, newVal, attrName, attrChange);
        target.dispatchEvent(ev);
      }
    }
    return prev;
  }
}

utils.intercept(core.AttrNodeMap, 'removeNamedItem', dispatchAttrEvent('REMOVAL'));
utils.intercept(core.AttrNodeMap, 'setNamedItem', dispatchAttrEvent('ADDITION'));

core.CharacterData.prototype.__defineGetter__("_nodeValue", function() {
  return this.__nodeValue;
});
core.CharacterData.prototype.__defineSetter__("_nodeValue", function(value) {
  var oldValue = this.__nodeValue;
  this.__nodeValue = value;
  if (this._ownerDocument && this._parentNode && mutationEventsEnabled(this)) {
    var ev = this._ownerDocument.createEvent("MutationEvents")
    ev.initMutationEvent("DOMCharacterDataModified", true, false, this, oldValue, value, null, null);
    this.dispatchEvent(ev);
  }
});

core.Document.prototype.createEvent = function(eventType) {
    switch (eventType) {
        case "MutationEvents": return new events.MutationEvent(eventType);
        case "UIEvents": return new events.UIEvent(eventType);
        case "MouseEvents": return new events.MouseEvent(eventType);
        case "HTMLEvents": return new events.HTMLEvent(eventType);
    }
    return new events.Event(eventType);
};

exports.dom =
{
  level2 : {
    core   : core,
    events : events
  }
};

<|endoftext|>


<commit_before>/**
 * GulpFlow provides a [gulp](https://gulpjs.com) plugin for [Flow](http://flowtype.org).
 *
 * @module GulpFlow
 * @main GulpFlow
 */

var _ = require("underscore");
var Class = require("yajscf");
var through = require("through2");
var gutil = require("gulp-util");
var PluginError = gutil.PluginError;
var execFile = require("child_process").execFileSync;
var flow = require("flow-bin");

module.exports = Class.extend(
{
    /**
     * GulpFlow is a Gulp plugin for type-checking code with `flow`.
     *
     * @class GulpFlow
     * @constructor
     */
    init: function()
    {
        /**
         * Options to pass to the `flow` binary.
         *
         * @property options
         * @type string[]
         * @private
         */
        this.options = [
            "--json"
        ];

        /**
         * Name of this plugin.
         *
         * @property PLUGIN_NAME
         * @type string
         */
        this.PLUGIN_NAME = "gulp-flowcheck";
    },

    /**
     * Check for type errors and store them in `this.results`.
     * Only compatible with buffers at the moment.
     *
     * @method check
     * @return {Object} A gulp-compatible stream.
     */
    check: function()
    {
        var me = this;
        this.results = {};
        return through.obj(function(file, encoding, callback)
        {
            if(file.isNull())
            {
                callback();
                return;
            }

            if(file.isStream())
            {
                this.emit("error", new PluginError(me.PLUGIN_NAME, "streams are not supported (yet?)"));
            }

            var output;
            try
            {
                output = execFile(flow, _.union(["check-contents"], me.options), {
                    input: file.contents.toString(encoding)
                });
            }
            catch(e)
            {
                // flow normally exits with a non-zero status if errors are found
                output = e.stdout;
            }
            file.contents = output;
            callback(null, file);
        });
    },

    /**
     * Dump the results of the type check to the command line.
     *
     * @method reporter
     * @return {Object} A gulp-compatible stream.
     */
    reporter: function()
    {
        return through.obj(function(file, encoding, callback)
        {
            var contents = file.contents.toString(encoding);
            //console.dir(contents);
            var errors = JSON.parse(contents).errors;
            _.forEach(errors, gutil.log);
            callback(null, file);
        });
    }
});
<commit_msg>Not using results anymore<commit_after>/**
 * GulpFlow provides a [gulp](https://gulpjs.com) plugin for [Flow](http://flowtype.org).
 *
 * @module GulpFlow
 * @main GulpFlow
 */

var _ = require("underscore");
var Class = require("yajscf");
var through = require("through2");
var gutil = require("gulp-util");
var PluginError = gutil.PluginError;
var execFile = require("child_process").execFileSync;
var flow = require("flow-bin");

module.exports = Class.extend(
{
    /**
     * GulpFlow is a Gulp plugin for type-checking code with `flow`.
     *
     * @class GulpFlow
     * @constructor
     */
    init: function()
    {
        /**
         * Options to pass to the `flow` binary.
         *
         * @property options
         * @type string[]
         * @private
         */
        this.options = [
            "--json"
        ];

        /**
         * Name of this plugin.
         *
         * @property PLUGIN_NAME
         * @type string
         */
        this.PLUGIN_NAME = "gulp-flowcheck";
    },

    /**
     * Check for type errors and store them in `this.results`.
     * Only compatible with buffers at the moment.
     *
     * @method check
     * @return {Object} A gulp-compatible stream.
     */
    check: function()
    {
        var me = this;
        return through.obj(function(file, encoding, callback)
        {
            if(file.isNull())
            {
                callback();
                return;
            }

            if(file.isStream())
            {
                this.emit("error", new PluginError(me.PLUGIN_NAME, "streams are not supported (yet?)"));
            }

            var output;
            try
            {
                output = execFile(flow, _.union(["check-contents"], me.options), {
                    input: file.contents.toString(encoding)
                });
            }
            catch(e)
            {
                // flow normally exits with a non-zero status if errors are found
                output = e.stdout;
            }
            file.contents = output;
            callback(null, file);
        });
    },

    /**
     * Dump the results of the type check to the command line.
     *
     * @method reporter
     * @return {Object} A gulp-compatible stream.
     */
    reporter: function()
    {
        return through.obj(function(file, encoding, callback)
        {
            var contents = file.contents.toString(encoding);
            //console.dir(contents);
            var errors = JSON.parse(contents).errors;
            _.forEach(errors, gutil.log);
            callback(null, file);
        });
    }
});
<|endoftext|>


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

var concat = require('gulp-concat');
var concatSourcemap = require('gulp-concat-sourcemap');
var uglify = require('gulp-uglify');
var imagemin = require('gulp-imagemin');
var sass = require('gulp-sass');
var livereload = require('gulp-livereload');
var changed = require('gulp-changed');
var rename = require('gulp-rename');
var cmq = require('gulp-combine-media-queries');
var uncss = require('gulp-uncss');
var cssmin = require('gulp-cssmin');
var zopfli = require("gulp-zopfli");

var paths = {
  scripts: 'js/**/*.js',
  styles: 'scss/**/*.scss',
  images: 'img/**/*'
};

gulp.task('styles', function() {
    return gulp.src(paths.styles)
      .pipe(sass({
        errLogToConsole: true,
        sourceComments: 'map',
        outputStyle: 'expanded'
      }))
      .pipe(gulp.dest('assets/css'));
});

gulp.task('scripts', function() {
  return gulp.src(paths.scripts)
    .pipe(concatSourcemap('scripts.js', {
      sourcesContent: true
    }))
    .pipe(gulp.dest('assets/js'));
});

gulp.task('styles-build', function() {
  return gulp.src(paths.styles)
    .pipe(rename({suffix: '.min'}))
    .pipe(sass({
      errLogToConsole: true,
      outputStyle: 'compressed'
    }))
    .pipe(cmq({ log: true }))
    .pipe(uncss({
        html: [
          'http://127.0.0.1:13834/',
          'http://127.0.0.1:13834/styleguide',
          'http://127.0.0.1:13834/portfolio',
          'http://127.0.0.1:13834/contact',
          'http://127.0.0.1:13834/how-to-implement-url-redirection-in-ghost-0-3/'
        ]
    }))
    .pipe(cssmin())
    .pipe(zopfli())
    .pipe(gulp.dest('assets/css'));
})

gulp.task('scripts-build', function() {
  return gulp.src(paths.scripts)
    .pipe(concat('scripts.min.js'))
    .pipe(uglify())
    .pipe(zopfli())
    .pipe(gulp.dest('assets/js'));
});

gulp.task('images', function() {
 return gulp.src(paths.images)
    .pipe(imagemin({
      progressive: true,
      interlaced: true,
      optimizationLevel: 5
    }))
    .pipe(gulp.dest('assets/img'));
});

// Rerun the task when a file changes
gulp.task('watch', function() {
  var server = livereload();

  gulp.watch(paths.scripts, ['scripts']);
  gulp.watch(paths.styles, ['styles']);
  gulp.watch(paths.images, ['images']);

  gulp.watch('assets/**').on('change', function(file) {
      server.changed(file.path);
  });
});

// The default task (called when you run `gulp` from cli)
gulp.task('default', ['styles', 'scripts', 'images']);

// Run this before deploy
gulp.task('build', ['styles-build', 'scripts-build', 'images']);
<commit_msg>Moar image compression on Gulp<commit_after>var gulp = require('gulp');

var concat = require('gulp-concat');
var concatSourcemap = require('gulp-concat-sourcemap');
var uglify = require('gulp-uglify');
var imagemin = require('gulp-imagemin');
var sass = require('gulp-sass');
var livereload = require('gulp-livereload');
var changed = require('gulp-changed');
var rename = require('gulp-rename');
var cmq = require('gulp-combine-media-queries');
var uncss = require('gulp-uncss');
var cssmin = require('gulp-cssmin');
var zopfli = require("gulp-zopfli");

var paths = {
  scripts: 'js/**/*.js',
  styles: 'scss/**/*.scss',
  images: 'img/**/*'
};

gulp.task('styles', function() {
    return gulp.src(paths.styles)
      .pipe(sass({
        errLogToConsole: true,
        sourceComments: 'map',
        outputStyle: 'expanded'
      }))
      .pipe(gulp.dest('assets/css'));
});

gulp.task('scripts', function() {
  return gulp.src(paths.scripts)
    .pipe(concatSourcemap('scripts.js', {
      sourcesContent: true
    }))
    .pipe(gulp.dest('assets/js'));
});

gulp.task('styles-build', function() {
  return gulp.src(paths.styles)
    .pipe(rename({suffix: '.min'}))
    .pipe(sass({
      errLogToConsole: true,
      outputStyle: 'compressed'
    }))
    .pipe(cmq({ log: true }))
    .pipe(uncss({
        html: [
          'http://127.0.0.1:13834/',
          'http://127.0.0.1:13834/styleguide',
          'http://127.0.0.1:13834/portfolio',
          'http://127.0.0.1:13834/contact',
          'http://127.0.0.1:13834/how-to-implement-url-redirection-in-ghost-0-3/'
        ]
    }))
    .pipe(cssmin())
    .pipe(zopfli())
    .pipe(gulp.dest('assets/css'));
})

gulp.task('scripts-build', function() {
  return gulp.src(paths.scripts)
    .pipe(concat('scripts.min.js'))
    .pipe(uglify())
    .pipe(zopfli())
    .pipe(gulp.dest('assets/js'));
});

gulp.task('images', function() {
 return gulp.src(paths.images)
    .pipe(imagemin({
      progressive: true,
      interlaced: true,
      optimizationLevel: 7
    }))
    .pipe(gulp.dest('assets/img'));
});

// Rerun the task when a file changes
gulp.task('watch', function() {
  var server = livereload();

  gulp.watch(paths.scripts, ['scripts']);
  gulp.watch(paths.styles, ['styles']);
  gulp.watch(paths.images, ['images']);

  gulp.watch('assets/**').on('change', function(file) {
      server.changed(file.path);
  });
});

// The default task (called when you run `gulp` from cli)
gulp.task('default', ['styles', 'scripts', 'images']);

// Run this before deploy
gulp.task('build', ['styles-build', 'scripts-build', 'images']);
<|endoftext|>


<commit_before>//
// Build
//
var browserify = require('browserify'),
    buffer = require('vinyl-buffer'),
    gulp  = require('gulp'),
    gutil = require('gulp-util'),
    jshint = require('gulp-jshint'),
    mainBower = require('main-bower-files'),
    rimraf = require('rimraf'),
    source = require('vinyl-source-stream'),
    uglify = require('gulp-uglify');

var watch = [
    './app/js/*.js',
    './app/*.html',
    './app/**/*.html'
];

// front-end assets handled by Bower
var bower_base = './bower_components/';

// lighthouse and lighthouse-client live at the same filesystem level
var staticRoot = '../lighthouse/static/';
var appRoot = './app/js/app.js';
var isProd = false;

// TL;DR Default task
gulp.task('default', ['prod', 'build']);

//
// Tasks
//
// sets up development build context
gulp.task('dev', function () {
    isProd = false;
});

// sets up production build context
gulp.task('prod', function () {
    isProd = true;
});

// Build app and assets
gulp.task('build', ['jshint', 'browserify', 'views', 'vendor']);

// JSHint
gulp.task('jshint', function () {
    gulp.src('./app/js/**/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

// Browserify task for js assets
// -- This will package our app into a single file for distribution
gulp.task('browserify', function() {
    browserify(appRoot, {
        debug: !isProd,
        // modules with no require() deps
        noparse: ['lodash'],
        transform: ['partialify'],
    })
    .bundle()
    .pipe(source('app.js'))
    // minify source, skip on dev build
    .pipe(isProd ? buffer() : gutil.noop())
    .pipe(isProd ? uglify() : gutil.noop())
    .pipe(gulp.dest(staticRoot + 'js/'));
});

// add vendor assets from Bower
gulp.task('vendor', function() {
    gulp.src(mainBower(), { base: bower_base })
        .pipe(gulp.dest(staticRoot + 'vendor/'));
});

// View task for html assets
gulp.task('views', function () {
    gulp.src('./app/*.html')
    .pipe(gulp.dest(staticRoot));
});

// Watch for source updates, will use dev build
gulp.task('watch', ['dev'], function() {
    gulp.watch(watch, ['browserify', 'views']);
});

// Clean build artifacts
gulp.task('clean', function () {
    rimraf(staticRoot, function (er) {
        if (er) {
            console.log(er);
        }
    });

    rimraf(staticRoot, function (er) {
        if (er) {
            console.log(er);
        }
    });
});
<commit_msg>Build to lighthouse repo in gopath<commit_after>//
// Build
//
var browserify = require('browserify'),
    buffer = require('vinyl-buffer'),
    gulp  = require('gulp'),
    gutil = require('gulp-util'),
    jshint = require('gulp-jshint'),
    mainBower = require('main-bower-files'),
    rimraf = require('rimraf'),
    source = require('vinyl-source-stream'),
    uglify = require('gulp-uglify');

var watch = [
    './app/js/*.js',
    './app/*.html',
    './app/**/*.html'
];

// front-end assets handled by Bower
var bower_base = './bower_components/';

// build to lighthouse repo in gopath
var staticRoot = (function (enviroment) {
    if (typeof enviroment.GOPATH === 'undefined') {
        return '../lighthouse/static/';
    }
    return enviroment.GOPATH + '/src/github.com/lighthouse/lighthouse/static/';
})(process.env);

var appRoot = './app/js/app.js';
var isProd = false;

// TL;DR Default task
gulp.task('default', ['prod', 'build']);

//
// Tasks
//
// sets up development build context
gulp.task('dev', function () {
    isProd = false;
});

// sets up production build context
gulp.task('prod', function () {
    isProd = true;
});

// Build app and assets
gulp.task('build', ['jshint', 'browserify', 'views', 'vendor']);

// JSHint
gulp.task('jshint', function () {
    gulp.src('./app/js/**/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

// Browserify task for js assets
// -- This will package our app into a single file for distribution
gulp.task('browserify', function() {
    browserify(appRoot, {
        debug: !isProd,
        // modules with no require() deps
        noparse: ['lodash'],
        transform: ['partialify'],
    })
    .bundle()
    .pipe(source('app.js'))
    // minify source, skip on dev build
    .pipe(isProd ? buffer() : gutil.noop())
    .pipe(isProd ? uglify() : gutil.noop())
    .pipe(gulp.dest(staticRoot + 'js/'));
});

// add vendor assets from Bower
gulp.task('vendor', function() {
    gulp.src(mainBower(), { base: bower_base })
        .pipe(gulp.dest(staticRoot + 'vendor/'));
});

// View task for html assets
gulp.task('views', function () {
    gulp.src('./app/*.html')
    .pipe(gulp.dest(staticRoot));
});

// Watch for source updates, will use dev build
gulp.task('watch', ['dev'], function() {
    gulp.watch(watch, ['browserify', 'views']);
});

// Clean build artifacts
gulp.task('clean', function () {
    rimraf(staticRoot, function (er) {
        if (er) {
            console.log(er);
        }
    });

    rimraf(staticRoot, function (er) {
        if (er) {
            console.log(er);
        }
    });
});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var del = require('del');
var zip = require('gulp-zip');

gulp.task('clean', function(cb){
  del(['./build'], cb);
});

gulp.task('copy', ['clean'], function(){
  return gulp.src('./**/*')
    .pipe(gulp.dest('./build'));
});

gulp.task('thin', ['copy'], function(cb){
  del([
    './build/update.sh',
    './build/Gulpfile.js',
    './build/package.json',
    './build/node_modules',
    './build/mqtt.zip'
  ], cb);
})

gulp.task('compress', ['thin'], function () {
  return gulp.src('build/**/*')
    .pipe(zip('mqtt.zip'))
    .pipe(gulp.dest('./'));
});

gulp.task('default', ['compress']);
<commit_msg>ignore new file<commit_after>var gulp = require('gulp');
var del = require('del');
var zip = require('gulp-zip');

gulp.task('clean', function(cb){
  del(['./build'], cb);
});

gulp.task('copy', ['clean'], function(){
  return gulp.src('./**/*')
    .pipe(gulp.dest('./build'));
});

gulp.task('thin', ['copy'], function(cb){
  del([
    './build/update.sh',
    './build/Gulpfile.js',
    './build/package.json',
    './build/node_modules',
    './build/mqtt.zip',
    './build/CMakeLists.txt'
  ], cb);
})

gulp.task('compress', ['thin'], function () {
  return gulp.src('build/**/*')
    .pipe(zip('mqtt.zip'))
    .pipe(gulp.dest('./'));
});

gulp.task('default', ['compress']);
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var gutil = require('gulp-util');
var path = require('path');
var run = require('gulp-run');
var gulpif = require('gulp-if');
var template = require('gulp-template');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var watchify = require('watchify');
var sourcemaps = require('gulp-sourcemaps');
var mergeStream = require('merge-stream');
var objectAssign = require('object-assign');
var browserify = require('browserify');
var reactify = require('reactify');
var envify = require('envify');
var stripify = require('stripify');
//var streamify = require('gulp-streamify'); AJF: removed as can't find it being used
var uglify = require('gulp-uglify');
var concat = require('gulp-concat'),
    livereload = require('gulp-livereload'),
    dest = 'dist',
    lvPort = 35729;
var realFs = require('fs');
var gracefulFs = require('graceful-fs');

var cssGlobs = ['src/css/**/*.css'];
gracefulFs.gracefulify(realFs);
var static_server = require('./static_server');

/*
 only uglify in production.  Since chrome inspector doesn't support source map
 variable names, debugging sucks when minified
 https://code.google.com/p/chromium/issues/detail?id=327092
*/
var production = process.env.NODE_ENV === 'production';
if (production) {
    gutil.log('making production build');
}

var debugMode = process.env.DEBUG === 'true';

gutil.log('debugMode: ' + debugMode);

if(debugMode) {
    gutil.log('debug turned on');
}

/*
  I don't want to have to define the browserify code twice.  Yet, I need it to run inside
  of watchify, and then I also want to run it manually for the 'build' task.  So I have to
  abstract out the process of making a bundler, and then leave it open to manual triggering
*/
var indexBundler = bundlerBuilder('./src/js/index.jsx', 'index.js', true);
// var viewerBundler = bundlerBuilder('./src/js/viewer.jsx', 'viewer.js', true);
// var manifest2015Bundler = bundlerBuilder('./src/js/manifest2015.js', 'manifest2015.js', false);
// var graphViewerBundler = bundlerBuilder('./src/js/graph-viewer.jsx', 'graph-viewer.js', true);
// var adjustablGridBundler= bundlerBuilder('./src/js/single-page-grid-layout.jsx','single-page-grid-layout.js',true);
function bundlerBuilder (startPath, finishName, useReactify) {
    var bundler = watchify(browserify(startPath, objectAssign({debug: true, cache: {}, packageCache: {}}, watchify.args)));
    if (useReactify) {
        bundler.transform(reactify);
    }

    if(!debugMode) {
        bundler.transform("stripify")
    }

    bundler.transform(envify);
    bundler.on('log', gutil.log);

    var rebundle = function() {
        return bundler.bundle()
            .on('error', gutil.log.bind(gutil, 'Browserify Error'))
            .pipe(source(finishName))
            // .pipe(gulpif(production, buffer()))
            // .pipe(gulpif(production, sourcemaps.init({loadMaps: true})))
            // .pipe(gulpif(production, uglify()))
            // .pipe(gulpif(production, sourcemaps.write('./')))
            .pipe(gulp.dest(dest + '/js'));
    };

    return {bundler: bundler, rebundle: rebundle};
}

gulp.task('watch', function () {
    // trigger livereload on any change to dest
    livereload.listen(lvPort);
    gulp.watch('src/**').on('change', livereload.changed);

    // html changes
    gulp.watch('src/*.html', ['html']);

    gulp.watch('src/images/**', ['images']);

    // css changes
    gulp.watch(cssGlobs, ['css']);

    indexBundler.bundler.on('update', indexBundler.rebundle);
    // viewerBundler.bundler.on('update', viewerBundler.rebundle);
    // manifest2015Bundler.bundler.on('update', manifest2015Bundler.rebundle);
    // graphViewerBundler.bundler.on('update', graphViewerBundler.rebundle);
    // adjustablGridBundler.bundler.on('update', adjustablGridBundler.rebundle);
});

gulp.task('html', function() {
    return gulp.src('src/*.html')
        .pipe(template({polyfillFeatures: 'Element.prototype.classList,Object.create'}))
        .pipe(gulp.dest(dest));
});

gulp.task('icon',function(){
    return gulp.src('src/*.ico')
        .pipe(gulp.dest(dest));
});
gulp.task('images',function(){
   return gulp.src('src/images/*')
       .pipe(gulp.dest(dest+ '/images'));
});

gulp.task('css', function() {
    return gulp.src(cssGlobs)
        .pipe(gulp.dest(dest + '/css'));
});

gulp.task('bundlejs', function() {
    return mergeStream(
        indexBundler.rebundle()
        // viewerBundler.rebundle(),
        // manifest2015Bundler.rebundle(),
        // graphViewerBundler.rebundle(),
        // adjustablGridBundler.rebundle()
    );
});

gulp.task('build-version-document', function() {
    return run('node ./build/app-versioning/app-version.js').exec();
});

gulp.task('include-monaco-editor', function() {
    //APEP - Small hack to include this full dependency within th dist folder - typically this should be hosted on a CDN. Or build into the bundle
    return gulp.src(['node_modules/react-monaco-editor/node_modules/monaco-editor/**']).pipe(gulp.dest('dist/monaco-editor'));
});

gulp.task('external-deps-for-china', function() {
    return gulp.src(['external-client-side-deps/**']).pipe(gulp.dest('dist/external'));
});
gulp.task('include-schemas',function(){
    return gulp.src(['src/schemas/**']).pipe(gulp.dest('dist/schemas'));
});

gulp.task('build-dist', ['bundlejs', 'html', 'css', 'icon', 'images', 'external-deps-for-china',  'include-monaco-editor', 'include-schemas', 'build-version-document']);

///// BEGIN CLI TASKS ////////////////////////////////

gulp.task('build', ['build-dist'], function() {
    // watchify watch handles must be closed, otherwise gulp task will hang,
    // thus the .on('end', ...)
    indexBundler.bundler.close();
    // viewerBundler.bundler.close();
    // manifest2015Bundler.bundler.close();
    // graphViewerBundler.bundler.close();
    // adjustablGridBundler.bundler.close();
});

gulp.task('serve', function(next) {
    static_server(dest, {callback: next, livereload: true});
});

//, 'watch'
gulp.task('default', ['build-dist', 'serve', 'watch']);
<commit_msg>Small change to default task for Azure deployment.<commit_after>'use strict';

var gulp = require('gulp');
var gutil = require('gulp-util');
var path = require('path');
var run = require('gulp-run');
var gulpif = require('gulp-if');
var template = require('gulp-template');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var watchify = require('watchify');
var sourcemaps = require('gulp-sourcemaps');
var mergeStream = require('merge-stream');
var objectAssign = require('object-assign');
var browserify = require('browserify');
var reactify = require('reactify');
var envify = require('envify');
var stripify = require('stripify');
//var streamify = require('gulp-streamify'); AJF: removed as can't find it being used
var uglify = require('gulp-uglify');
var concat = require('gulp-concat'),
    livereload = require('gulp-livereload'),
    dest = 'dist',
    lvPort = 35729;
var realFs = require('fs');
var gracefulFs = require('graceful-fs');

var cssGlobs = ['src/css/**/*.css'];
gracefulFs.gracefulify(realFs);
var static_server = require('./static_server');

/*
 only uglify in production.  Since chrome inspector doesn't support source map
 variable names, debugging sucks when minified
 https://code.google.com/p/chromium/issues/detail?id=327092
*/
var production = process.env.NODE_ENV === 'production';
if (production) {
    gutil.log('making production build');
}

var debugMode = process.env.DEBUG === 'true';

gutil.log('debugMode: ' + debugMode);

if(debugMode) {
    gutil.log('debug turned on');
}

/*
  I don't want to have to define the browserify code twice.  Yet, I need it to run inside
  of watchify, and then I also want to run it manually for the 'build' task.  So I have to
  abstract out the process of making a bundler, and then leave it open to manual triggering
*/
var indexBundler = bundlerBuilder('./src/js/index.jsx', 'index.js', true);
// var viewerBundler = bundlerBuilder('./src/js/viewer.jsx', 'viewer.js', true);
// var manifest2015Bundler = bundlerBuilder('./src/js/manifest2015.js', 'manifest2015.js', false);
// var graphViewerBundler = bundlerBuilder('./src/js/graph-viewer.jsx', 'graph-viewer.js', true);
// var adjustablGridBundler= bundlerBuilder('./src/js/single-page-grid-layout.jsx','single-page-grid-layout.js',true);
function bundlerBuilder (startPath, finishName, useReactify) {
    var bundler = watchify(browserify(startPath, objectAssign({debug: true, cache: {}, packageCache: {}}, watchify.args)));
    if (useReactify) {
        bundler.transform(reactify);
    }

    if(!debugMode) {
        bundler.transform("stripify")
    }

    bundler.transform(envify);
    bundler.on('log', gutil.log);

    var rebundle = function() {
        return bundler.bundle()
            .on('error', gutil.log.bind(gutil, 'Browserify Error'))
            .pipe(source(finishName))
            // .pipe(gulpif(production, buffer()))
            // .pipe(gulpif(production, sourcemaps.init({loadMaps: true})))
            // .pipe(gulpif(production, uglify()))
            // .pipe(gulpif(production, sourcemaps.write('./')))
            .pipe(gulp.dest(dest + '/js'));
    };

    return {bundler: bundler, rebundle: rebundle};
}

gulp.task('watch', function () {
    // trigger livereload on any change to dest
    livereload.listen(lvPort);
    gulp.watch('src/**').on('change', livereload.changed);

    // html changes
    gulp.watch('src/*.html', ['html']);

    gulp.watch('src/images/**', ['images']);

    // css changes
    gulp.watch(cssGlobs, ['css']);

    indexBundler.bundler.on('update', indexBundler.rebundle);
    // viewerBundler.bundler.on('update', viewerBundler.rebundle);
    // manifest2015Bundler.bundler.on('update', manifest2015Bundler.rebundle);
    // graphViewerBundler.bundler.on('update', graphViewerBundler.rebundle);
    // adjustablGridBundler.bundler.on('update', adjustablGridBundler.rebundle);
});

gulp.task('html', function() {
    return gulp.src('src/*.html')
        .pipe(template({polyfillFeatures: 'Element.prototype.classList,Object.create'}))
        .pipe(gulp.dest(dest));
});

gulp.task('icon',function(){
    return gulp.src('src/*.ico')
        .pipe(gulp.dest(dest));
});
gulp.task('images',function(){
   return gulp.src('src/images/*')
       .pipe(gulp.dest(dest+ '/images'));
});

gulp.task('css', function() {
    return gulp.src(cssGlobs)
        .pipe(gulp.dest(dest + '/css'));
});

gulp.task('bundlejs', function() {
    return mergeStream(
        indexBundler.rebundle()
        // viewerBundler.rebundle(),
        // manifest2015Bundler.rebundle(),
        // graphViewerBundler.rebundle(),
        // adjustablGridBundler.rebundle()
    );
});

gulp.task('build-version-document', function() {
    return run('node ./build/app-versioning/app-version.js').exec();
});

gulp.task('include-monaco-editor', function() {
    //APEP - Small hack to include this full dependency within th dist folder - typically this should be hosted on a CDN. Or build into the bundle
    return gulp.src(['node_modules/react-monaco-editor/node_modules/monaco-editor/**']).pipe(gulp.dest('dist/monaco-editor'));
});

gulp.task('external-deps-for-china', function() {
    return gulp.src(['external-client-side-deps/**']).pipe(gulp.dest('dist/external'));
});
gulp.task('include-schemas',function(){
    return gulp.src(['src/schemas/**']).pipe(gulp.dest('dist/schemas'));
});

gulp.task('build-dist', ['bundlejs', 'html', 'css', 'icon', 'images', 'external-deps-for-china',  'include-monaco-editor', 'include-schemas', 'build-version-document']);

///// BEGIN CLI TASKS ////////////////////////////////

gulp.task('build', ['build-dist'], function() {
    // watchify watch handles must be closed, otherwise gulp task will hang,
    // thus the .on('end', ...)
    indexBundler.bundler.close();
    // viewerBundler.bundler.close();
    // manifest2015Bundler.bundler.close();
    // graphViewerBundler.bundler.close();
    // adjustablGridBundler.bundler.close();
});

gulp.task('serve', function(next) {
    static_server(dest, {callback: next, livereload: true});
});

//, 'watch'
gulp.task('default', ['build', 'serve', 'watch']);
<|endoftext|>


<commit_before>require( '@stephenbunch/buildpack/register' )( require( 'gulp' ), {
  template: 'library',
  options: {
    projectDir: __dirname,
    name: 'bind'
  }
});
<commit_msg>update gulpfile<commit_after>require( '@stephenbunch/buildpack/register' )( require( 'gulp' ), {
  template: 'library',
  options: {
    projectDir: __dirname
  }
});
<|endoftext|>


<commit_before>'use strict';

var util = require('util');

var Handlebars = require('handlebars');

function SourceTransformer(source) {
  this.source = source;
}
module.exports.SourceTransformer = SourceTransformer;

SourceTransformer.prototype.findDependencies = function() {
  return [];
};

SourceTransformer.prototype.evaluate = function(dependencyMap) {
  return null;
};

var JavaScriptSourceTransformer = function() {
  SourceTransformer.apply(this, arguments);
};
util.inherits(JavaScriptSourceTransformer, SourceTransformer);

JavaScriptSourceTransformer.prototype.findDependencies = function() {
  var dependencies = {};

  var source = this.source.replace(/^\s*\/\/.*$/, '');
  source = source.replace(/^\/\*.+?\*\//m, '');
  source.split(/[\n\r]+/).every(function(line) {
    line = line.trim();
    if (!line) {
      return true;
    }
    var result = /^var\s+\w+\s*=\s*([\w.]+)\s*;?$/.exec(line);
    if (!result) {
      return false;
    }

    dependencies[result[1]] = 1;
    return true;
  });

  var dependencyPaths = Object.keys(dependencies);
  return dependencyPaths;
};

JavaScriptSourceTransformer.prototype.evaluate = function(dependencyMap) {
  var source = this.source;

  var aliases = [];
  var values = [];
  for (var dependencyPath in dependencyMap) {
    var alias = dependencyPath.replace(/\./g, '_') + '_' + (+new Date());
    var obj = dependencyMap[dependencyPath];

    // Replace all foo.bar with foo_bar_12345 aliases.
    source = source.split(dependencyPath).join(alias);

    aliases.push(alias);
    values.push(obj);
  }

  // Build a function with the given source, using aliases as arguments.
  // Then call the function with the actual objects in the correct order.
  var wrapped = '(function(' + aliases.join(',') + ') { ' + source + ' })';
  var result = eval(wrapped).apply(null, values);
  return result;
};

function HandlebarsSourceTransformer() {
  SourceTransformer.apply(this, arguments);
}
util.inherits(HandlebarsSourceTransformer, SourceTransformer);

HandlebarsSourceTransformer.prototype.evaluate = function(dependencyMap) {
  return Handlebars.compile(this.source);
};

var TRANSFORMERS = {};

function setTransformer(extension, fn) {
  TRANSFORMERS[extension] = fn;
}
module.exports.setTransformer = setTransformer;

function getTransformer(extension) {
  return TRANSFORMERS[extension] || SourceTransformer;
}
module.exports.getTransformer = getTransformer;

setTransformer('.js', JavaScriptSourceTransformer);
setTransformer('.html', HandlebarsSourceTransformer);

<commit_msg>Whitespace tweak.<commit_after>'use strict';

var util = require('util');

var Handlebars = require('handlebars');

function SourceTransformer(source) {
  this.source = source;
}
module.exports.SourceTransformer = SourceTransformer;

SourceTransformer.prototype.findDependencies = function() {
  return [];
};

SourceTransformer.prototype.evaluate = function(dependencyMap) {
  return null;
};

var JavaScriptSourceTransformer = function() {
  SourceTransformer.apply(this, arguments);
};
util.inherits(JavaScriptSourceTransformer, SourceTransformer);

JavaScriptSourceTransformer.prototype.findDependencies = function() {
  var dependencies = {};

  var source = this.source.replace(/^\s*\/\/.*$/, '');
  source = source.replace(/^\/\*.+?\*\//m, '');
  source.split(/[\n\r]+/).every(function(line) {
    line = line.trim();
    if (!line) {
      return true;
    }
    var result = /^var\s+\w+\s*=\s*([\w.]+)\s*;?$/.exec(line);
    if (!result) {
      return false;
    }

    dependencies[result[1]] = 1;
    return true;
  });

  var dependencyPaths = Object.keys(dependencies);
  return dependencyPaths;
};

JavaScriptSourceTransformer.prototype.evaluate = function(dependencyMap) {
  var source = this.source;

  var aliases = [];
  var values = [];
  for (var dependencyPath in dependencyMap) {
    var alias = dependencyPath.replace(/\./g, '_') + '_' + (+new Date());
    var obj = dependencyMap[dependencyPath];

    // Replace all foo.bar with foo_bar_12345 aliases.
    source = source.split(dependencyPath).join(alias);

    aliases.push(alias);
    values.push(obj);
  }

  // Build a function with the given source, using aliases as arguments.
  // Then call the function with the actual objects in the correct order.
  var wrapped = '(function(' + aliases.join(',') + ') { ' + source + ' })';
  var result = eval(wrapped).apply(null, values);
  return result;
};

function HandlebarsSourceTransformer() {
  SourceTransformer.apply(this, arguments);
}
util.inherits(HandlebarsSourceTransformer, SourceTransformer);

HandlebarsSourceTransformer.prototype.evaluate = function(dependencyMap) {
  return Handlebars.compile(this.source);
};

var TRANSFORMERS = {};

function setTransformer(extension, fn) {
  TRANSFORMERS[extension] = fn;
}
module.exports.setTransformer = setTransformer;

function getTransformer(extension) {
  return TRANSFORMERS[extension] || SourceTransformer;
}
module.exports.getTransformer = getTransformer;

setTransformer('.js', JavaScriptSourceTransformer);
setTransformer('.html', HandlebarsSourceTransformer);

<|endoftext|>


<commit_before>/*eslint-env browser */
/*global require: false, module: false */
'use strict';

var React = require('react');
var ReactDOM = require('react-dom');
var {Button, ButtonToolbar, Modal, Glyphicon} = require('react-bootstrap/lib');
var CohortSelect = require('./views/CohortSelect');
var DatasetSelect = require('./views/DatasetSelect2');
var _ = require('./underscore_ext');
var uuid = require('./uuid');
require('./ColumnEdit.css');
var phenotypeEdit = require('./views/PhenotypeEdit');
var geneEdit = require('./views/GeneEdit');
var geneProbeEdit = require('./views/GeneProbeEdit');
var {PropTypes} = React;
var {getColSpec} = require('./models/datasetJoins');
var {defaultColorClass} = require('./heatmapColors');
var {easeInOutQuad} = require('./easing');
var Rx = require('rx');
require('rx.time');

var editors = {
	'clinicalMatrix': phenotypeEdit,
	'mutationVector': geneEdit,
	'none': {Editor: () => , valid: () => false}
};

//var pickEditor = (m) => {
//	return _.get(editors, _.get(m, 'type', 'none'), geneProbeEdit);
//}

var pickEditor = function(datasets, chosenDs) {
	if (datasets && chosenDs) {
		let dsMeta = datasets[chosenDs[0]]; // only 1 entry when dataset sub type is NOT 'phenotype'
		return _.get(editors, _.get(dsMeta, 'type', 'none'), geneProbeEdit);
	} else {
		return {Editor: null, apply: null};
	}
};

function updateChoice(currentPosition, defs, oldChoices) {
	/*
	 1. Find specific section within defs collection.
	 2. Sections that do not represent 'prevPosition' keep their values -- are not changed
	 3. Once found, reset all 'choice' params (e.g. 'staged' and 'committed') to null.
	 */
	let comparePosition = _.getIn(defs, [currentPosition, 'next']);
	let updatedChoices = _.mapObject(oldChoices, (s, key) => {
		if (key === comparePosition) {
			comparePosition = _.getIn(defs, [comparePosition, 'next']);
			return null;
		} else {
			return s;
		}
	});

	return updatedChoices;
}

function updatePositions(newSection, oldPositions) {
	//Set new sectopm to true, and all other defs to false
	return _.mapObject(oldPositions, (value, section) => (section === newSection));
}

function makeLabel(content, label) {
	return (

			{label}

{content}

	);
}

var NavButtons = React.createClass({
	propTypes: {
		choices: PropTypes.object,
		onCancel: PropTypes.func,
		onForward: PropTypes.func,
		onPrev: PropTypes.func,
		positions: PropTypes.object
	},
	makeForwardBtn: function(currentSection) {
		/* FORWARD BTN: Select | Next | Done */
		let btnLabel,
			icon,
			{choices, onForward} = this.props,
			disabled = !choices[currentSection] || choices[currentSection].length === 0;

		if (currentSection === "cohort") {
			btnLabel = 'Select';
			icon = '';
		} else if (currentSection === "dataset") {
			btnLabel = 'Next';
			icon = "menu-right";
		} else if (currentSection === "editor") {
			btnLabel = 'Done';
			icon = '';
		}

		return (
			<Button key="FORWARD" bsStyle='primary' disabled={disabled} onClick={onForward}>
				{btnLabel} <Glyphicon glyph={icon}/>
			</Button>
		);
	},
	render: function() {
		let buttons = [],
			{defs, onBack, onCancel, positions} = this.props,
			currentSection = _.findKey(positions, (status) => status),
			prevSection = defs[currentSection].prev;

		/* PREV && CANCEL */
		if (prevSection) {
			if (!defs[prevSection].omit) {
				buttons.push(
					<Button key='BACK' onClick={onBack} bsStyle='primary'>
						<Glyphicon glyph='menu-left' /> Prev
					</Button>);
			}
			buttons.push(<Button key="CANCEL" onClick={onCancel}>Cancel</Button>);
		}
		buttons.push(this.makeForwardBtn(currentSection));
		return (
			<ButtonToolbar>{buttons}</ButtonToolbar>
		);
	}
});

var ColumnEdit = React.createClass({
	defs: {
		cohort: {
			omit: true,
			name: 'Cohort',
			next: 'dataset',
			prev: null
		},
		dataset: {
			omit: false,
			name: 'dataset',
			next: 'editor',
			prev: 'cohort'
		},
		editor: {
			omit: false,
			name: 'data slice',
			next: null,
			prev: 'dataset'
		}
	},
	getInitialState: function () {
		let {appState: {cohort: activeCohorts}} = this.props,
			cohort = _.getIn(activeCohorts, [0 /* index into composite cohorts */, 'name']);
		return {
			choices: {
				cohort: cohort,
				dataset: [],
				editor: null
			},
			positions: {
				cohort: cohort ? false : true,
				dataset: cohort ? true : false,
				editor: false
			}
		};
	},
	componentWillMount: function () {
		this.onSelectBus = new Rx.Subject();
		this.sub = this.onSelectBus.map(scrollTop => {
			// Using a ref to the Modal isn't working, for reasons I don't
			// understand.
			var ce = document.getElementsByClassName('columnEdit')[0],
				current = ce.scrollTop,
				duration = 500,
				steps = 30;

			return Rx.Observable.interval(duration / steps)
				.map(i => easeInOutQuad(i, current, scrollTop, steps))
				.take(steps);
		}).switchLatest().subscribe(scrollTop => {
			var ce = document.getElementsByClassName('columnEdit')[0];
			ce.scrollTop = scrollTop;
		});
	},
	componentWillUnmount: function () {
		this.sub.dispose();
	},
	addColumn: function (settings) {
		let {callback, appState} = this.props,
			dsIDs = this.state.choices.dataset,
			dsID = _.has(settings, 'dsID') ? settings.dsID : dsIDs[0],
			ds = appState.datasets[dsID],
			colSpec = getColSpec([settings], appState.datasets),
			meta = _.map(dsIDs, dsID => {
				return appState.datasets[dsID];
			});

		settings = _.assoc(colSpec,
			'width', 200, // XXX move this default setting?
			'columnLabel', ds.label,
			'user', {columnLabel: ds.label, fieldLabel: colSpec.fieldLabel},
			'colorClass', defaultColorClass(ds),
			'assembly', ds.assembly,
			'datasetMetadata', meta);
		this.props.onHide();
		callback(['add-column', uuid(), settings, true]);
	},
	onCohortSelect: function(value) {
		this.setChoice('cohort', value);
	},
	scrollPositionToNextButton: function () {
		var dialogBottom = ReactDOM.findDOMNode(this.refs.columnEditBody)
				.getBoundingClientRect().bottom,
			columnEdit = document.getElementsByClassName('columnEdit')[0],
			columnEditBottom = columnEdit.getBoundingClientRect().bottom;
		return columnEdit.scrollTop + (dialogBottom - columnEditBottom);
	},
	onDatasetSelect: function (dsIDs) {
		var {callback, appState: {datasets}} = this.props,
			metas = _.pick(datasets, dsIDs);

		this.setChoice('dataset', dsIDs);

		if (_.toArray(metas).length === 1) {
			let dsID = _.first(dsIDs);
			callback(['edit-dataset', dsID, metas[dsID]]);
		}

		this.onSelectBus.onNext(this.scrollPositionToNextButton());
	},
	onBack: function() {
		let {positions} = this.state,
			currentSpot = _.findKey(positions, (position) => position),
			newSpot = this.defs[currentSpot].prev;
		if (newSpot) {
			/*
			 - Exception situation where user cannot go back to 'Cohort' section
			 after it's selected.
			 - This exeption is already take care of simply by not displaying back button
			 within set of Navigation buttons
			 */
			let newPositions = updatePositions(newSpot, positions);
			this.setState({positions: newPositions});
		}
	},
	onForward: function() {
		let newState = {},
			{choices, positions} = this.state,
			currentSpot = _.findKey(positions, (position) => position),
			currentSpotDef = this.defs[currentSpot],
			nextSpot = currentSpotDef.next;

		if (this.defs[currentSpot].omit) {
			if (currentSpot === 'cohort') {
				this.props.callback([currentSpot, 0 /* index into composite cohorts */, choices[currentSpot]]);
			} else {
				this.props.callback([currentSpot, choices[currentSpot]]);
			}
		}

		// Set new position in workflow if necessary and reset choices
		if (nextSpot) {
			_.extendOwn(newState, {
				choices: updateChoice(currentSpot, this.defs, choices),
				positions: updatePositions(nextSpot, positions)
			});
			this.setState(newState);
		} else if (currentSpot === 'editor') {
			let {appState: {features, datasets}} = this.props,
				chosenDs = choices.dataset,
				{apply} = pickEditor(datasets, chosenDs),
				hasGenes = chosenDs && !!datasets[chosenDs[0]].probeMap;

			this.addColumn(apply(features, choices.editor, hasGenes, datasets[chosenDs[0]]));
		}
	},
	onHub: function() {
		location.href = "../hub/";
	},
	setChoice: function(section, newValue) {
		let newState = _.assocIn(this.state, ['choices', section], newValue);
		this.setState(newState);
	},
	onSetEditor: function (newEditor) {
		var oldEditor = this.state.choices.editor || {};
		this.setChoice('editor', _.merge(oldEditor, newEditor));
	},
	render: function () {
		var {choices, positions} = this.state,
			{appState: {cohorts, columnEdit, datasets, features, servers}, callback, onHide} = this.props,
			chosenDs = choices.dataset,  // choices.dataset is an array of datasets
			{Editor} = pickEditor(datasets, chosenDs),
			chosenDsSingle = (chosenDs && chosenDs.length === 1) ? datasets[chosenDs[0]] : null,
			chosenDsSingleLink = chosenDsSingle ? "../datapages/?dataset=" + chosenDsSingle.name +
				"&host=" + JSON.parse(chosenDsSingle.dsID).host : null;

		return (
			<Modal show={true} className = 'columnEdit container' enforceFocus>
				<Modal.Header onHide={onHide} closeButton>
        			<Modal.Title> {positions.cohort ? 'Select a cohort' : 'Select data'}
        			</Modal.Title>
      			</Modal.Header>

				<Modal.Body ref='columnEditBody' className='columnEditBody'>
					{positions.cohort ?
					<CohortSelect onSelect={this.onCohortSelect} cohorts={cohorts}
						cohort={choices.cohort} makeLabel={makeLabel}/> : null}

					{positions.cohort ?

							If not found, perhaps the cohort is on a different data hub?
							{' '}
							<Button onClick={this.onHub}>Configure My Data Hubs</Button>

 : null}

					{positions.dataset ?
					<DatasetSelect datasets={datasets} makeLabel={makeLabel}
						event='dataset' value={chosenDs || null} onSelect={this.onDatasetSelect}
						servers={_.uniq(_.reduce(servers, (all, list) => all.concat(list), []))}/> : null}

					{positions.editor ?

{makeLabel( chosenDs.length === 1 ?
							{datasets[chosenDs[0]].label} : "Combined phenotypes",
							"Dataset")}

						: null}

					{positions.editor ?
					<Editor {...columnEdit} allFeatures={features} callback={callback}
						{...(this.state.choices.editor || {})} chosenDs={chosenDs}
						hasGenes={chosenDs && !!datasets[chosenDs[0]].probeMap}
						makeLabel={makeLabel} setEditorState={this.onSetEditor}/> : null}

				</Modal.Body>

						<NavButtons {...this.state}
							onBack={this.onBack} onCancel={onHide} defs={this.defs}
							onForward= {this.onForward}
						/>

			</Modal>
		);
	}
});

module.exports = ColumnEdit;
<commit_msg>fix problem in creating clinical data column using columnEdit2.js (albert style create column): the datasetMetadata in the column setting was incorrect<commit_after>/*eslint-env browser */
/*global require: false, module: false */
'use strict';

var React = require('react');
var ReactDOM = require('react-dom');
var {Button, ButtonToolbar, Modal, Glyphicon} = require('react-bootstrap/lib');
var CohortSelect = require('./views/CohortSelect');
var DatasetSelect = require('./views/DatasetSelect2');
var _ = require('./underscore_ext');
var uuid = require('./uuid');
require('./ColumnEdit.css');
var phenotypeEdit = require('./views/PhenotypeEdit');
var geneEdit = require('./views/GeneEdit');
var geneProbeEdit = require('./views/GeneProbeEdit');
var {PropTypes} = React;
var {getColSpec} = require('./models/datasetJoins');
var {defaultColorClass} = require('./heatmapColors');
var {easeInOutQuad} = require('./easing');
var Rx = require('rx');
require('rx.time');

var editors = {
	'clinicalMatrix': phenotypeEdit,
	'mutationVector': geneEdit,
	'none': {Editor: () => , valid: () => false}
};

//var pickEditor = (m) => {
//	return _.get(editors, _.get(m, 'type', 'none'), geneProbeEdit);
//}

var pickEditor = function(datasets, chosenDs) {
	if (datasets && chosenDs) {
		let dsMeta = datasets[chosenDs[0]]; // only 1 entry when dataset sub type is NOT 'phenotype'
		return _.get(editors, _.get(dsMeta, 'type', 'none'), geneProbeEdit);
	} else {
		return {Editor: null, apply: null};
	}
};

function updateChoice(currentPosition, defs, oldChoices) {
	/*
	 1. Find specific section within defs collection.
	 2. Sections that do not represent 'prevPosition' keep their values -- are not changed
	 3. Once found, reset all 'choice' params (e.g. 'staged' and 'committed') to null.
	 */
	let comparePosition = _.getIn(defs, [currentPosition, 'next']);
	let updatedChoices = _.mapObject(oldChoices, (s, key) => {
		if (key === comparePosition) {
			comparePosition = _.getIn(defs, [comparePosition, 'next']);
			return null;
		} else {
			return s;
		}
	});

	return updatedChoices;
}

function updatePositions(newSection, oldPositions) {
	//Set new sectopm to true, and all other defs to false
	return _.mapObject(oldPositions, (value, section) => (section === newSection));
}

function makeLabel(content, label) {
	return (

			{label}

{content}

	);
}

var NavButtons = React.createClass({
	propTypes: {
		choices: PropTypes.object,
		onCancel: PropTypes.func,
		onForward: PropTypes.func,
		onPrev: PropTypes.func,
		positions: PropTypes.object
	},
	makeForwardBtn: function(currentSection) {
		/* FORWARD BTN: Select | Next | Done */
		let btnLabel,
			icon,
			{choices, onForward} = this.props,
			disabled = !choices[currentSection] || choices[currentSection].length === 0;

		if (currentSection === "cohort") {
			btnLabel = 'Select';
			icon = '';
		} else if (currentSection === "dataset") {
			btnLabel = 'Next';
			icon = "menu-right";
		} else if (currentSection === "editor") {
			btnLabel = 'Done';
			icon = '';
		}

		return (
			<Button key="FORWARD" bsStyle='primary' disabled={disabled} onClick={onForward}>
				{btnLabel} <Glyphicon glyph={icon}/>
			</Button>
		);
	},
	render: function() {
		let buttons = [],
			{defs, onBack, onCancel, positions} = this.props,
			currentSection = _.findKey(positions, (status) => status),
			prevSection = defs[currentSection].prev;

		/* PREV && CANCEL */
		if (prevSection) {
			if (!defs[prevSection].omit) {
				buttons.push(
					<Button key='BACK' onClick={onBack} bsStyle='primary'>
						<Glyphicon glyph='menu-left' /> Prev
					</Button>);
			}
			buttons.push(<Button key="CANCEL" onClick={onCancel}>Cancel</Button>);
		}
		buttons.push(this.makeForwardBtn(currentSection));
		return (
			<ButtonToolbar>{buttons}</ButtonToolbar>
		);
	}
});

var ColumnEdit = React.createClass({
	defs: {
		cohort: {
			omit: true,
			name: 'Cohort',
			next: 'dataset',
			prev: null
		},
		dataset: {
			omit: false,
			name: 'dataset',
			next: 'editor',
			prev: 'cohort'
		},
		editor: {
			omit: false,
			name: 'data slice',
			next: null,
			prev: 'dataset'
		}
	},
	getInitialState: function () {
		let {appState: {cohort: activeCohorts}} = this.props,
			cohort = _.getIn(activeCohorts, [0 /* index into composite cohorts */, 'name']);
		return {
			choices: {
				cohort: cohort,
				dataset: [],
				editor: null
			},
			positions: {
				cohort: cohort ? false : true,
				dataset: cohort ? true : false,
				editor: false
			}
		};
	},
	componentWillMount: function () {
		this.onSelectBus = new Rx.Subject();
		this.sub = this.onSelectBus.map(scrollTop => {
			// Using a ref to the Modal isn't working, for reasons I don't
			// understand.
			var ce = document.getElementsByClassName('columnEdit')[0],
				current = ce.scrollTop,
				duration = 500,
				steps = 30;

			return Rx.Observable.interval(duration / steps)
				.map(i => easeInOutQuad(i, current, scrollTop, steps))
				.take(steps);
		}).switchLatest().subscribe(scrollTop => {
			var ce = document.getElementsByClassName('columnEdit')[0];
			ce.scrollTop = scrollTop;
		});
	},
	componentWillUnmount: function () {
		this.sub.dispose();
	},
	addColumn: function (settings) {
		let {callback, appState} = this.props,
			//dsIDs = this.state.choices.dataset,
			//dsID = _.has(settings, 'dsID') ? settings.dsID : dsIDs[0];
			dsID = settings.dsID,
			ds = appState.datasets[dsID],
			colSpec = getColSpec([settings], appState.datasets),
			meta = _.map([dsID], dsID => {
				return appState.datasets[dsID];
			});

		settings = _.assoc(colSpec,
			'width', ds.type === 'mutationVector' ? 200 : 100,
			'columnLabel', ds.label,
			'user', {columnLabel: ds.label, fieldLabel: colSpec.fieldLabel},
			'colorClass', defaultColorClass(ds),
			'assembly', ds.assembly,
			'datasetMetadata', meta);
		this.props.onHide();
		callback(['add-column', uuid(), settings, true]);
	},
	onCohortSelect: function(value) {
		this.setChoice('cohort', value);
	},
	scrollPositionToNextButton: function () {
		var dialogBottom = ReactDOM.findDOMNode(this.refs.columnEditBody)
				.getBoundingClientRect().bottom,
			columnEdit = document.getElementsByClassName('columnEdit')[0],
			columnEditBottom = columnEdit.getBoundingClientRect().bottom;
		return columnEdit.scrollTop + (dialogBottom - columnEditBottom);
	},
	onDatasetSelect: function (dsIDs) {
		var {callback, appState: {datasets}} = this.props,
			metas = _.pick(datasets, dsIDs);

		this.setChoice('dataset', dsIDs);

		if (_.toArray(metas).length === 1) {
			let dsID = _.first(dsIDs);
			callback(['edit-dataset', dsID, metas[dsID]]);
		}

		this.onSelectBus.onNext(this.scrollPositionToNextButton());
	},
	onBack: function() {
		let {positions} = this.state,
			currentSpot = _.findKey(positions, (position) => position),
			newSpot = this.defs[currentSpot].prev;
		if (newSpot) {
			/*
			 - Exception situation where user cannot go back to 'Cohort' section
			 after it's selected.
			 - This exeption is already take care of simply by not displaying back button
			 within set of Navigation buttons
			 */
			let newPositions = updatePositions(newSpot, positions);
			this.setState({positions: newPositions});
		}
	},
	onForward: function() {
		let newState = {},
			{choices, positions} = this.state,
			currentSpot = _.findKey(positions, (position) => position),
			currentSpotDef = this.defs[currentSpot],
			nextSpot = currentSpotDef.next;

		if (this.defs[currentSpot].omit) {
			if (currentSpot === 'cohort') {
				this.props.callback([currentSpot, 0 /* index into composite cohorts */, choices[currentSpot]]);
			} else {
				this.props.callback([currentSpot, choices[currentSpot]]);
			}
		}

		// Set new position in workflow if necessary and reset choices
		if (nextSpot) {
			_.extendOwn(newState, {
				choices: updateChoice(currentSpot, this.defs, choices),
				positions: updatePositions(nextSpot, positions)
			});
			this.setState(newState);
		} else if (currentSpot === 'editor') {
			let {appState: {features, datasets}} = this.props,
				chosenDs = choices.dataset,
				{apply} = pickEditor(datasets, chosenDs),
				hasGenes = chosenDs && !!datasets[chosenDs[0]].probeMap;

			this.addColumn(apply(features, choices.editor, hasGenes, datasets[chosenDs[0]]));
		}
	},
	onHub: function() {
		location.href = "../hub/";
	},
	setChoice: function(section, newValue) {
		let newState = _.assocIn(this.state, ['choices', section], newValue);
		this.setState(newState);
	},
	onSetEditor: function (newEditor) {
		var oldEditor = this.state.choices.editor || {};
		this.setChoice('editor', _.merge(oldEditor, newEditor));
	},
	render: function () {
		var {choices, positions} = this.state,
			{appState: {cohorts, columnEdit, datasets, features, servers}, callback, onHide} = this.props,
			chosenDs = choices.dataset,  // choices.dataset is an array of datasets
			{Editor} = pickEditor(datasets, chosenDs),
			chosenDsSingle = (chosenDs && chosenDs.length === 1) ? datasets[chosenDs[0]] : null,
			chosenDsSingleLink = chosenDsSingle ? "../datapages/?dataset=" + chosenDsSingle.name +
				"&host=" + JSON.parse(chosenDsSingle.dsID).host : null;

		return (
			<Modal show={true} className = 'columnEdit container' enforceFocus>
				<Modal.Header onHide={onHide} closeButton>
        			<Modal.Title> {positions.cohort ? 'Select a cohort' : 'Select data'}
        			</Modal.Title>
      			</Modal.Header>

				<Modal.Body ref='columnEditBody' className='columnEditBody'>
					{positions.cohort ?
					<CohortSelect onSelect={this.onCohortSelect} cohorts={cohorts}
						cohort={choices.cohort} makeLabel={makeLabel}/> : null}

					{positions.cohort ?

							If not found, perhaps the cohort is on a different data hub?
							{' '}
							<Button onClick={this.onHub}>Configure My Data Hubs</Button>

 : null}

					{positions.dataset ?
					<DatasetSelect datasets={datasets} makeLabel={makeLabel}
						event='dataset' value={chosenDs || null} onSelect={this.onDatasetSelect}
						servers={_.uniq(_.reduce(servers, (all, list) => all.concat(list), []))}/> : null}

					{positions.editor ?

{makeLabel( chosenDs.length === 1 ?
							{datasets[chosenDs[0]].label} : "Combined phenotypes",
							"Dataset")}

						: null}

					{positions.editor ?
					<Editor {...columnEdit} allFeatures={features} callback={callback}
						{...(this.state.choices.editor || {})} chosenDs={chosenDs}
						hasGenes={chosenDs && !!datasets[chosenDs[0]].probeMap}
						makeLabel={makeLabel} setEditorState={this.onSetEditor}/> : null}

				</Modal.Body>

						<NavButtons {...this.state}
							onBack={this.onBack} onCancel={onHide} defs={this.defs}
							onForward= {this.onForward}
						/>

			</Modal>
		);
	}
});

module.exports = ColumnEdit;
<|endoftext|>


<commit_before>logger._print( 'original array = [' + D.join(', ') + ']' );
var N = D.length;
var writes = 0;
var pos;
var item;
var temp;
for( cycleStart=0; cycleStart<=N-2; cycleStart++ ){
    item = D[cycleStart];
    pos = cycleStart;
    for( i=cycleStart+1; i<=N-1; i++ ){
        if( D[i]<item ){
            pos++;
        }
    }
    if( pos == cycleStart ){
        continue;
    }
    while( item == D[pos] ){
        pos++;
    }
    temp = D[pos];
    D[pos] = item;
    item = temp;

    logger._print( 'Rewrite '+D[pos]+' to index '+pos );

    tracer._notify(pos, D[pos])._notify(cycleStart, D[cycleStart])._wait();
    tracer._denotify(pos)._denotify(pos);

    while( pos != cycleStart ){
        pos = cycleStart;
        for( i=cycleStart+1; i<=N-1; i++ ){
            if( D[i]<item ){
                pos++;
            }
        }

        while( item == D[pos] ){
            pos++;
        }
        temp = D[pos];
        D[pos] = item;
        item = temp;

        logger._print( 'Rewrite '+D[pos]+' to index '+pos );

        tracer._notify(pos, D[pos])._notify(cycleStart, D[cycleStart])._wait();
        tracer._denotify(pos)._denotify(pos);

        writes++;
    }

    writes++;
}

logger._print( 'Number of writes performed is ' + writes );<commit_msg>fix reference error<commit_after>logger._print( 'original array = [' + D.join(', ') + ']' );
var N = D.length;
var writes = 0;
var pos;
var item;
var temp;
for( var cycleStart=0; cycleStart<=N-2; cycleStart++ ){
    item = D[cycleStart];
    pos = cycleStart;
    for( var i=cycleStart+1; i<=N-1; i++ ){
        if( D[i]<item ){
            pos++;
        }
    }
    if( pos == cycleStart ){
        continue;
    }
    while( item == D[pos] ){
        pos++;
    }
    temp = D[pos];
    D[pos] = item;
    item = temp;

    logger._print( 'Rewrite '+D[pos]+' to index '+pos );

    tracer._notify(pos, D[pos])._notify(cycleStart, D[cycleStart])._wait();
    tracer._denotify(pos)._denotify(pos);

    while( pos != cycleStart ){
        pos = cycleStart;
        for( i=cycleStart+1; i<=N-1; i++ ){
            if( D[i]<item ){
                pos++;
            }
        }

        while( item == D[pos] ){
            pos++;
        }
        temp = D[pos];
        D[pos] = item;
        item = temp;

        logger._print( 'Rewrite '+D[pos]+' to index '+pos );

        tracer._notify(pos, D[pos])._notify(cycleStart, D[cycleStart])._wait();
        tracer._denotify(pos)._denotify(pos);

        writes++;
    }

    writes++;
}

logger._print( 'Number of writes performed is ' + writes );
<|endoftext|>


<commit_before>'use strict';
var mongoose = require('mongoose');
var ShortId = require('mongoose-shortid');
var timestamps = require('mongoose-timestamp');
var BBPromise = require('bluebird');
var Schema = mongoose.Schema;
var mongooseDelete = require('mongoose-delete');
var keygen = require('keygenerator');

var HoistInviteSchema = new Schema({
  schemaVersion: String,
  _id: {
    type: ShortId,
    base: 64,
    retries: 4,
    len: 20
  },
  userName: {
    type: String,
    required: 'Must have a user name'
  },
  existingUserId: {
    type: ShortId,
    default: null
  },
  emailAddress: {
    type: String,
    required: 'Must have an email address'
  },
  organisation: {
    type: ShortId,
    required: 'Must have an organisation'
  },
  inviteCode: {
    type: String,
    index: true,
    required: 'Must have an invite code',
    unique: true,
    default: keygen._()
  },
  activatedDate: {
    type: Date,
    default: null
  },
  activated: {
    type: Boolean,
    default: false
  }
});

HoistInviteSchema.plugin(mongooseDelete);
HoistInviteSchema.plugin(timestamps);

mongoose.model('HoistInvite', HoistInviteSchema);

var HoistInvite = mongoose.model('HoistInvite');
BBPromise.promisifyAll(HoistInvite);
BBPromise.promisifyAll(HoistInvite.prototype);
exports.name = 'HoistInvite';
exports.model = HoistInvite;
<commit_msg>change username to display name<commit_after>'use strict';
var mongoose = require('mongoose');
var ShortId = require('mongoose-shortid');
var timestamps = require('mongoose-timestamp');
var BBPromise = require('bluebird');
var Schema = mongoose.Schema;
var mongooseDelete = require('mongoose-delete');
var keygen = require('keygenerator');

var HoistInviteSchema = new Schema({
  schemaVersion: String,
  _id: {
    type: ShortId,
    base: 64,
    retries: 4,
    len: 20
  },
  displayName: {
    type: String,
    required: 'Must have a user name'
  },
  existingUserId: {
    type: ShortId,
    default: null
  },
  emailAddress: {
    type: String,
    required: 'Must have an email address'
  },
  organisation: {
    type: ShortId,
    required: 'Must have an organisation'
  },
  inviteCode: {
    type: String,
    index: true,
    required: 'Must have an invite code',
    unique: true,
    default: keygen._()
  },
  activatedDate: {
    type: Date,
    default: null
  },
  activated: {
    type: Boolean,
    default: false
  }
});

HoistInviteSchema.plugin(mongooseDelete);
HoistInviteSchema.plugin(timestamps);

mongoose.model('HoistInvite', HoistInviteSchema);

var HoistInvite = mongoose.model('HoistInvite');
BBPromise.promisifyAll(HoistInvite);
BBPromise.promisifyAll(HoistInvite.prototype);
exports.name = 'HoistInvite';
exports.model = HoistInvite;
<|endoftext|>


<commit_before>// Copyright 2018, University of Colorado Boulder

/**
 * Creates a simple enumeration, with most of the boilerplate.
 *
 * When you create an enumeration object, it sets up a few things, e.g.:
 *
 *   const CardinalDirection = new Enumeration( [ 'NORTH', 'SOUTH', 'EAST', 'WEST' ] );
 *
 * Will provide the following:
 *
 *   CardinalDirection.NORTH; // 'NORTH'
 *   CardinalDirection.SOUTH; // 'SOUTH'
 *   CardinalDirection.EAST; // 'EAST'
 *   CardinalDirection.WEST; // 'WEST'
 *   CardinalDirection.VALUES; // [ 'NORTH', 'SOUTH', 'EAST', 'WEST' ]
 *
 * And support for checking whether any value is a value of the enumeration:
 *
 *   CardinalDirection.includes( 'NORTH' ); // true
 *   CardinalDirection.includes( 'YORKSHIRE_TERRIER_WITH_THE_CANDLE_STICK_IN_THE_BALLROOM' ); // false
 *
 * Conventions for using Enumeration, from https://github.com/phetsims/phet-core/issues/53:
 *
 * (1) Enumerations are named like classes/types. Nothing in the name needs to identify that they are Enumerations.
 *     See the example above: CardinalDirection, not CardinalDirectionEum or CardinalDirectionEnumeration.
 *
 * (2) Enumeration values are named like constants, using uppercase. See the example above.
 *
 * (3) If an Enumeration is closely related to some class, then make it a static field of that class. If an
 *     Enumeration is specific to a Property, then the Enumeration should likely be owned by the class that
 *     owns that Property.
 *
 * (4) If an Enumeration is not closely related to some class, then put the Enumeration in its own .js file.
 *     Do not combine multiple Enumerations into one file.
 *
 * (5) If a Property takes an Enumeration value, its validation typically looks like this:
 *
 *     const cardinalDirectionProperty = new Property( CardinalDirection.NORTH, {
 *       validValues: CardinalDirection.VALUES
 *     }
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
define( require => {
  'use strict';

  // modules
  const phetCore = require( 'PHET_CORE/phetCore' );

  class Enumeration {
    /**
     * @param {Array.<string>} keys - The string keys for the enumeration. Customarily, these are uppercase, using
     *                                underscores where there would be other punctuation. For example,
     *                                `THIS_IS_AN_EXAMPLE` or `DOES_NOT_WANT_TO_BE_AN_EXAMPLE_TOO_BAD`.
     * @param {function} [beforeFreeze] - If provided, it will be called as beforeFreeze( enumeration ) just before the
     *                                    enumeration is frozen. Since it's not possible to modify the enumeration after
     *                                    it is frozen (e.g. adding convenience functions), and there is no reference to
     *                                    the enumeration object beforehand, this allows defining custom values/methods
     *                                    on the enumeration object itself.
     */
    constructor( keys, beforeFreeze ) {
      assert && assert( Array.isArray( keys ), 'Values should be an array' );
      assert && assert( _.uniq( keys ).length === keys.length, 'There should be no duplicated values provided' );
      assert && keys.forEach( value => assert( typeof value === 'string', 'Each value should be a string' ) );
      assert && keys.forEach( value => assert( /^[A-Z][A-Z0-9_]*$/g.test( value ),
        'Enumeration values should be uppercase alphanumeric with underscores and begin with a letter' ) );
      assert && assert( !_.includes( keys, 'VALUES' ),
        'This is the name of a built-in provided value, so it cannot be included as an enumeration value' );
      assert && assert( !_.includes( keys, 'includes' ),
        'This is the name of a built-in provided value, so it cannot be included as an enumeration value' );

      // @public {Object[]} (read-only) - the object values of the enumeration
      this.VALUES = [];

      // @public {string[]} (read-only) - the string keys of the enumeration
      this.KEYS = [];

      keys.forEach( key => {
        this[ key ] = {
          name: key,
          toString() {return key;}
        };
        this.VALUES.push( this[ key ] );
        this.KEYS.push( key );
      } );

      beforeFreeze && beforeFreeze( this );
      assert && Object.freeze( this );
      assert && Object.freeze( this.VALUES );
      assert && Object.freeze( this.KEYS );
    }

    /**
     * Checks whether the given value is a value of this enumeration. Should generally be used for assertions
     * @public
     *
     * @param {string} value
     * @returns {boolean}
     */
    includes( value ) {
      return this.VALUES.includes( value );
    }
  }

  return phetCore.register( 'Enumeration', Enumeration );
} );
<commit_msg>Update example documentation, see #56<commit_after>// Copyright 2018, University of Colorado Boulder

/**
 * Creates a simple enumeration, with most of the boilerplate.
 *
 * An Enumeration can be created like this:
 *
 *   const CardinalDirection = new Enumeration( [ 'NORTH', 'SOUTH', 'EAST', 'WEST' ] );
 *
 * and values are referenced like this:
 *
 *   CardinalDirection.NORTH;
 *   CardinalDirection.SOUTH;
 *   CardinalDirection.EAST;
 *   CardinalDirection.WEST;
 *
 *   CardinalDirection.VALUES;
 *   // returns [ CardinalDirection.NORTH, CardinalDirection.SOUTH, CardinalDirection.EAST, CardinalDirection.WEST ]
 *
 * And support for checking whether any value is a value of the enumeration:
 *
 *   CardinalDirection.includes( CardinalDirection.NORTH ); // true
 *   CardinalDirection.includes( CardinalDirection.SOUTHWEST ); // false
 *   CardinalDirection.includes( 'NORTH' ); // false, values are not strings
 *
 * Conventions for using Enumeration, from https://github.com/phetsims/phet-core/issues/53:
 *
 * (1) Enumerations are named like classes/types. Nothing in the name needs to identify that they are Enumerations.
 *     See the example above: CardinalDirection, not CardinalDirectionEum or CardinalDirectionEnumeration.
 *
 * (2) Enumeration values are named like constants, using uppercase. See the example above.
 *
 * (3) If an Enumeration is closely related to some class, then make it a static field of that class. If an
 *     Enumeration is specific to a Property, then the Enumeration should likely be owned by the class that
 *     owns that Property.
 *
 * (4) If an Enumeration is not closely related to some class, then put the Enumeration in its own .js file.
 *     Do not combine multiple Enumerations into one file.
 *
 * (5) If a Property takes an Enumeration value, its validation typically looks like this:
 *
 *     const cardinalDirectionProperty = new Property( CardinalDirection.NORTH, {
 *       validValues: CardinalDirection.VALUES
 *     }
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
define( require => {
  'use strict';

  // modules
  const phetCore = require( 'PHET_CORE/phetCore' );

  class Enumeration {
    /**
     * @param {Array.<string>} keys - The string keys for the enumeration. Customarily, these are uppercase, using
     *                                underscores where there would be other punctuation. For example,
     *                                `THIS_IS_AN_EXAMPLE` or `DOES_NOT_WANT_TO_BE_AN_EXAMPLE_TOO_BAD`.
     * @param {function} [beforeFreeze] - If provided, it will be called as beforeFreeze( enumeration ) just before the
     *                                    enumeration is frozen. Since it's not possible to modify the enumeration after
     *                                    it is frozen (e.g. adding convenience functions), and there is no reference to
     *                                    the enumeration object beforehand, this allows defining custom values/methods
     *                                    on the enumeration object itself.
     */
    constructor( keys, beforeFreeze ) {
      assert && assert( Array.isArray( keys ), 'Values should be an array' );
      assert && assert( _.uniq( keys ).length === keys.length, 'There should be no duplicated values provided' );
      assert && keys.forEach( value => assert( typeof value === 'string', 'Each value should be a string' ) );
      assert && keys.forEach( value => assert( /^[A-Z][A-Z0-9_]*$/g.test( value ),
        'Enumeration values should be uppercase alphanumeric with underscores and begin with a letter' ) );
      assert && assert( !_.includes( keys, 'VALUES' ),
        'This is the name of a built-in provided value, so it cannot be included as an enumeration value' );
      assert && assert( !_.includes( keys, 'includes' ),
        'This is the name of a built-in provided value, so it cannot be included as an enumeration value' );

      // @public {Object[]} (read-only) - the object values of the enumeration
      this.VALUES = [];

      // @public {string[]} (read-only) - the string keys of the enumeration
      this.KEYS = [];

      keys.forEach( key => {
        this[ key ] = {
          name: key,
          toString() {return key;}
        };
        this.VALUES.push( this[ key ] );
        this.KEYS.push( key );
      } );

      beforeFreeze && beforeFreeze( this );
      assert && Object.freeze( this );
      assert && Object.freeze( this.VALUES );
      assert && Object.freeze( this.KEYS );
    }

    /**
     * Checks whether the given value is a value of this enumeration. Should generally be used for assertions
     * @public
     *
     * @param {string} value
     * @returns {boolean}
     */
    includes( value ) {
      return this.VALUES.includes( value );
    }
  }

  return phetCore.register( 'Enumeration', Enumeration );
} );
<|endoftext|>