<commit_before>/*global angular */

/**
 * @ngdoc directive
 * @name vjsVideoApp.directive:vjs.directive.js
 * @description
 * # vjs.directive.js
 */
(function () {
    'use strict';

    var module = angular.module('vjs.video', []);

    function getVersion() {
        return (window.videojs && window.videojs.VERSION) ?
                window.videojs.VERSION : '0.0.0';
    }

    module.controller('VjsVideoController', ['$scope', function ($scope) {
        var self = this;

        function getVidElement(element, isContainer) {
            var vid = null,
                videos;

            if (!window.videojs) {
                throw new Error('video.js was not found!');
            }

            if (isContainer) {
                videos = element[0].getElementsByTagName('video');
                if (videos.length === 0) {
                    throw new Error('video tag must be defined within container directive!');
                } else if (videos.length > 1) {
                    throw new Error('only one video can be defined within the container directive!');
                }

                vid = videos[0];
            } else {
                if (element[0].nodeName === 'VIDEO') {
                    vid = element[0];
                } else {
                    throw new Error('directive must be attached to a video tag!');
                }
            }

            return vid;
        }

        function applyRatio(el, ratioVal) {
            var ratio = ratioVal,
                style = document.createElement('style'),
                parseRatio = function (r) {
                    var tokens = r.split(':'),
                        tokenErrorMsg = 'the ratio must either be "wide", "standard" or ' +
                                        'decimal values in the format of w:h';

                    //if invalid ratio throw an error
                    if (tokens.length !== 2) {
                        throw new Error(tokenErrorMsg);
                    }

                    //confirm that both tokens are numbers
                    if (isNaN(tokens[0]) || isNaN(tokens[1])) {
                        throw new Error(tokenErrorMsg);
                    }

                    //confirm that the width or height is not zero
                    if (Number(tokens[0]) === 0 || Number(tokens[1]) === 0) {
                        throw new Error('neither the width or height ratio can be zero!');
                    }

                    return (Number(tokens[1]) / Number(tokens[0])) * 100;
                },
                genContainerId = function (element) {
                    var container = element[0].querySelector('.vjs-tech'),
                        vjsId;

                    if (container) {
                        vjsId = 'vjs-container-' + container.getAttribute('id');
                    } else {
                        //vjsId = 'vjs-container-default';
                        throw new Error('Failed to find instance of video-js class!');
                    }

                    //add generated id to container
                    element[0].setAttribute('id', vjsId);

                    return vjsId;
                },
                containerId,
                ratioPercentage,
                css;

            //if ratio isn't defined lets default to wide screen
            if (!ratio) {
                ratio = '16:9';
            }

            switch (ratio) {
            case 'wide':
                ratio = '16:9';
                break;
            case 'standard':
                ratio = '4:3';
                break;
            }

            containerId = genContainerId(el);

            ratioPercentage = parseRatio(ratio);

            css = ['#', containerId, ' ',
                   '.video-js {padding-top:', ratioPercentage,
                   '%;}\n', '.vjs-fullscreen {padding-top: 0px;}'].join('');

            style.type = 'text/css';
            style.rel = 'stylesheet';
            if (style.styleSheet) {
                style.styleSheet.cssText = css;
            } else {
                style.appendChild(document.createTextNode(css));
            }

            el[0].appendChild(style);
        }

        function generateMedia(ctrl, mediaChangedHandler) {
            var errMsgNoValid = 'a sources and/or tracks element must be ' +
                                'defined for the vjs-media attribute',
                errMsgNoSrcs  = 'sources must be an array of objects with at ' +
                                'least one item',
                errMsgNoTrks  = 'tracks must be an array of objects with at ' +
                                'least one item',
                div,
                curDiv;
            //check to see if vjsMedia is defined
            if (!ctrl.vjsMedia) {
                return;
            }

            //if sources and tracks aren't defined, throw an error
            if (!ctrl.vjsMedia.sources && !ctrl.vjsMedia.tracks) {
                throw new Error(errMsgNoValid);
            }

            //verify sources and tracks are arrays if they are defined
            if (ctrl.vjsMedia.sources && !(ctrl.vjsMedia.sources instanceof Array)) {
                throw new Error(errMsgNoSrcs);
            }
            if (ctrl.vjsMedia.tracks && !(ctrl.vjsMedia.tracks instanceof Array)) {
                throw new Error(errMsgNoTrks);
            }

            //build DOM elements for sources and tracks as children to a div
            div = document.createElement("div");

            if (ctrl.vjsMedia.sources) {
                ctrl.vjsMedia.sources.forEach(function (curObj) {
                    curDiv = document.createElement('source');
                    curDiv.setAttribute('src', curObj.src || "");
                    curDiv.setAttribute('type', curObj.type || "");
                    div.appendChild(curDiv);
                });
            }

            if (ctrl.vjsMedia.tracks) {
                ctrl.vjsMedia.tracks.forEach(function (curObj) {
                    curDiv = document.createElement('track');
                    curDiv.setAttribute('kind', curObj.kind || "");
                    curDiv.setAttribute('label', curObj.label || "");
                    curDiv.setAttribute('src', curObj.src || "");
                    curDiv.setAttribute('srclang', curObj.srclang || "");

                    //check for default flag
                    if (curObj.default === true) {
                        curDiv.setAttribute('default', "");
                    }

                    div.appendChild(curDiv);
                });
            }

            //invoke callback
            mediaChangedHandler.call(undefined, {element: div});

        }

        function initVideoJs(vid, params, element, mediaChangedHandler) {
            var opts = params.vjsSetup || {},
                ratio = params.vjsRatio,
                isValidContainer =
                    ((element[0].nodeName !== 'VIDEO') && !getVersion().match(/^5\./)) ? true : false,
                mediaWatcher;

            if (!window.videojs) {
                return null;
            }

            //override poster settings if defined in vjsMedia
            if (params.vjsMedia && params.vjsMedia.poster) {
                opts.poster = params.vjsMedia.poster;
            }

            //generate any defined sources or tracks
            generateMedia(params, mediaChangedHandler);

            //watch for changes to vjs-media
            mediaWatcher = $scope.$watch(
                function () {
                    return params.vjsMedia;
                },
                function (newVal, oldVal) {

                    if (newVal && !angular.equals(newVal, oldVal)) {
                        //deregister watcher
                        mediaWatcher();

                        if (isValidContainer) {
                            window.videojs(vid).dispose();
                            $scope.$emit('vjsVideoMediaChanged');
                        } else {
                            $scope.$emit('vjsVideoMediaChanged');
                        }
                    }
                }
            );

            //bootstrap videojs
            window.videojs(vid, opts, function () {
                if (isValidContainer) {
                    applyRatio(element, ratio);
                }

                //emit ready event with reference to video
                $scope.$emit('vjsVideoReady', {
                    id: vid.getAttribute('id'),
                    vid: this
                });
            });

            //dispose of videojs before destroying directive
            $scope.$on('$destroy', function () {
                window.videojs(vid).dispose();
            });
        }

        //export public methods
        self.initVideoJs = initVideoJs;
        self.getVidElement = getVidElement;
    }]);

    module.directive('vjsVideo', ['$compile', '$timeout', function ($compile, $timeout) {

        return {
            restrict: 'A',
            transclude: true,
            scope: {
                vjsSetup: '=',
                vjsMedia: '='
            },
            controller: 'VjsVideoController',
            controllerAs: 'vjsCtrl',
            bindToController: true,
            link: function postLink(scope, element, attrs, ctrl, transclude) {
                var vid,
                    parentContainer,
                    origContent,
                    compiledEl,
                    mediaChangedHandler = function (e) {
                        //remove any inside contents
                        element.children().remove();
                        //add generated sources and tracks
                        element.append(e.element.childNodes);
                    },
                    init = function () {
                        vid = ctrl.getVidElement(element);

                        //attach transcluded content
                        transclude(function (content) {
                            element.append(content);

                            //now that the transcluded content is injected
                            //initialize video.js
                            ctrl.initVideoJs(vid, ctrl, element, mediaChangedHandler);
                        });
                    };

                origContent = element.clone();

                //we need to wrap the video inside of a div
                //for easier DOM management
                if (!element.parent().hasClass('vjs-video-wrap')) {
                    element.wrap('

');
                }

                parentContainer = element.parent();

                scope.$on('vjsVideoMediaChanged', function () {
                    //retreive base element that video.js creates
                    var staleChild = parentContainer.children()[0];

                    //remove current directive instance
                    //destroy will trigger a video.js dispose
                    $timeout(function () {
                        scope.$destroy();
                    });

                    //compile the new directive and add it to the DOM
                    compiledEl = origContent.clone();
                    parentContainer.append(compiledEl);
                    //it is key to pass in the parent scope to the directive
                    compiledEl = $compile(compiledEl)(scope.$parent);

                    //remove original element created by video.js
                    staleChild.remove();
                });

                init();
            }
        };
    }]);

    module.directive('vjsVideoContainer', [function () {

        return {
            restrict: 'AE',
            transclude: true,
            template: '

',
            scope: {
                vjsSetup: '=',
                vjsRatio: '@',
                vjsMedia: '='
            },
            controller: 'VjsVideoController',
            controllerAs: 'vjsCtrl',
            bindToController: true,
            link: function postLink(scope, element, attrs, ctrl, transclude) {
                var vid,
                    origContent,
                    mediaChangedHandler = function (e) {
                        var vidEl = element[0].querySelector('video');

                        if (vidEl) {
                            //remove any inside contents
                            while (vidEl.firstChild) {
                                vidEl.removeChild(vidEl.firstChild);
                            }

                            //add generated sources and tracks
                            while (e.element.childNodes.length > 0) {
                                vidEl.appendChild(e.element.childNodes[0]);
                            }
                        }
                    },
                    init = function () {
                        vid = ctrl.getVidElement(element, true);

                        //we want to confirm that the vjs-video directive or
                        //any corresponding attributes are not defined on the
                        //internal video element
                        if (vid.getAttribute('vjs-video') !== null) {
                            throw new Error(
                                'vjs-video should not be used on the video ' +
                                'tag when using vjs-video-container!');
                        }

                        //we also want to make sure that no vjs-* attributes
                        //are included on the internal video tag
                        if ((vid.getAttribute('vjs-setup') !== null) ||
                            (vid.getAttribute('vjs-media') !== null) ||
                            (vid.getAttribute('vjs-ratio') !== null)) {
                            throw new Error(
                                'directive attributes should not be used on ' +
                                'the video tag when using vjs-video-container!'
                            );

                        }

                        //check if video.js version 5.x is running
                        if (getVersion().match(/^5\./)) {

                            if (ctrl.vjsRatio) {
                                if (!ctrl.vjsSetup) {
                                    ctrl.vjsSetup = {};
                                }

                                ctrl.vjsSetup.aspectRatio = ctrl.vjsRatio;
                            }
                        } else {
                            //set width and height of video to auto
                            vid.setAttribute('width', 'auto');
                            vid.setAttribute('height', 'auto');
                        }

                        //bootstrap video js
                        ctrl.initVideoJs(vid, ctrl, element, mediaChangedHandler);
                    };

                //save original content
                transclude(function (content) {
                    origContent = content.clone();
                });

                scope.$on('vjsVideoMediaChanged', function () {
                    //replace element children with orignal content
                    element.children().remove();
                    element.append(origContent.clone());
                    init();
                });

                init();
            }
        };
    }]);
}());
<commit_msg>Fixes #15, made two way data binding variables optional<commit_after>/*global angular */

/**
 * @ngdoc directive
 * @name vjsVideoApp.directive:vjs.directive.js
 * @description
 * # vjs.directive.js
 */
(function () {
    'use strict';

    var module = angular.module('vjs.video', []);

    function getVersion() {
        return (window.videojs && window.videojs.VERSION) ?
                window.videojs.VERSION : '0.0.0';
    }

    module.controller('VjsVideoController', ['$scope', function ($scope) {
        var self = this;

        function getVidElement(element, isContainer) {
            var vid = null,
                videos;

            if (!window.videojs) {
                throw new Error('video.js was not found!');
            }

            if (isContainer) {
                videos = element[0].getElementsByTagName('video');
                if (videos.length === 0) {
                    throw new Error('video tag must be defined within container directive!');
                } else if (videos.length > 1) {
                    throw new Error('only one video can be defined within the container directive!');
                }

                vid = videos[0];
            } else {
                if (element[0].nodeName === 'VIDEO') {
                    vid = element[0];
                } else {
                    throw new Error('directive must be attached to a video tag!');
                }
            }

            return vid;
        }

        function applyRatio(el, ratioVal) {
            var ratio = ratioVal,
                style = document.createElement('style'),
                parseRatio = function (r) {
                    var tokens = r.split(':'),
                        tokenErrorMsg = 'the ratio must either be "wide", "standard" or ' +
                                        'decimal values in the format of w:h';

                    //if invalid ratio throw an error
                    if (tokens.length !== 2) {
                        throw new Error(tokenErrorMsg);
                    }

                    //confirm that both tokens are numbers
                    if (isNaN(tokens[0]) || isNaN(tokens[1])) {
                        throw new Error(tokenErrorMsg);
                    }

                    //confirm that the width or height is not zero
                    if (Number(tokens[0]) === 0 || Number(tokens[1]) === 0) {
                        throw new Error('neither the width or height ratio can be zero!');
                    }

                    return (Number(tokens[1]) / Number(tokens[0])) * 100;
                },
                genContainerId = function (element) {
                    var container = element[0].querySelector('.vjs-tech'),
                        vjsId;

                    if (container) {
                        vjsId = 'vjs-container-' + container.getAttribute('id');
                    } else {
                        //vjsId = 'vjs-container-default';
                        throw new Error('Failed to find instance of video-js class!');
                    }

                    //add generated id to container
                    element[0].setAttribute('id', vjsId);

                    return vjsId;
                },
                containerId,
                ratioPercentage,
                css;

            //if ratio isn't defined lets default to wide screen
            if (!ratio) {
                ratio = '16:9';
            }

            switch (ratio) {
            case 'wide':
                ratio = '16:9';
                break;
            case 'standard':
                ratio = '4:3';
                break;
            }

            containerId = genContainerId(el);

            ratioPercentage = parseRatio(ratio);

            css = ['#', containerId, ' ',
                   '.video-js {padding-top:', ratioPercentage,
                   '%;}\n', '.vjs-fullscreen {padding-top: 0px;}'].join('');

            style.type = 'text/css';
            style.rel = 'stylesheet';
            if (style.styleSheet) {
                style.styleSheet.cssText = css;
            } else {
                style.appendChild(document.createTextNode(css));
            }

            el[0].appendChild(style);
        }

        function generateMedia(ctrl, mediaChangedHandler) {
            var errMsgNoValid = 'a sources and/or tracks element must be ' +
                                'defined for the vjs-media attribute',
                errMsgNoSrcs  = 'sources must be an array of objects with at ' +
                                'least one item',
                errMsgNoTrks  = 'tracks must be an array of objects with at ' +
                                'least one item',
                div,
                curDiv;
            //check to see if vjsMedia is defined
            if (!ctrl.vjsMedia) {
                return;
            }

            //if sources and tracks aren't defined, throw an error
            if (!ctrl.vjsMedia.sources && !ctrl.vjsMedia.tracks) {
                throw new Error(errMsgNoValid);
            }

            //verify sources and tracks are arrays if they are defined
            if (ctrl.vjsMedia.sources && !(ctrl.vjsMedia.sources instanceof Array)) {
                throw new Error(errMsgNoSrcs);
            }
            if (ctrl.vjsMedia.tracks && !(ctrl.vjsMedia.tracks instanceof Array)) {
                throw new Error(errMsgNoTrks);
            }

            //build DOM elements for sources and tracks as children to a div
            div = document.createElement("div");

            if (ctrl.vjsMedia.sources) {
                ctrl.vjsMedia.sources.forEach(function (curObj) {
                    curDiv = document.createElement('source');
                    curDiv.setAttribute('src', curObj.src || "");
                    curDiv.setAttribute('type', curObj.type || "");
                    div.appendChild(curDiv);
                });
            }

            if (ctrl.vjsMedia.tracks) {
                ctrl.vjsMedia.tracks.forEach(function (curObj) {
                    curDiv = document.createElement('track');
                    curDiv.setAttribute('kind', curObj.kind || "");
                    curDiv.setAttribute('label', curObj.label || "");
                    curDiv.setAttribute('src', curObj.src || "");
                    curDiv.setAttribute('srclang', curObj.srclang || "");

                    //check for default flag
                    if (curObj.default === true) {
                        curDiv.setAttribute('default', "");
                    }

                    div.appendChild(curDiv);
                });
            }

            //invoke callback
            mediaChangedHandler.call(undefined, {element: div});

        }

        function initVideoJs(vid, params, element, mediaChangedHandler) {
            var opts = params.vjsSetup || {},
                ratio = params.vjsRatio,
                isValidContainer =
                    ((element[0].nodeName !== 'VIDEO') && !getVersion().match(/^5\./)) ? true : false,
                mediaWatcher;

            if (!window.videojs) {
                return null;
            }

            //override poster settings if defined in vjsMedia
            if (params.vjsMedia && params.vjsMedia.poster) {
                opts.poster = params.vjsMedia.poster;
            }

            //generate any defined sources or tracks
            generateMedia(params, mediaChangedHandler);

            //watch for changes to vjs-media
            mediaWatcher = $scope.$watch(
                function () {
                    return params.vjsMedia;
                },
                function (newVal, oldVal) {

                    if (newVal && !angular.equals(newVal, oldVal)) {
                        //deregister watcher
                        mediaWatcher();

                        if (isValidContainer) {
                            window.videojs(vid).dispose();
                            $scope.$emit('vjsVideoMediaChanged');
                        } else {
                            $scope.$emit('vjsVideoMediaChanged');
                        }
                    }
                }
            );

            //bootstrap videojs
            window.videojs(vid, opts, function () {
                if (isValidContainer) {
                    applyRatio(element, ratio);
                }

                //emit ready event with reference to video
                $scope.$emit('vjsVideoReady', {
                    id: vid.getAttribute('id'),
                    vid: this
                });
            });

            //dispose of videojs before destroying directive
            $scope.$on('$destroy', function () {
                window.videojs(vid).dispose();
            });
        }

        //export public methods
        self.initVideoJs = initVideoJs;
        self.getVidElement = getVidElement;
    }]);

    module.directive('vjsVideo', ['$compile', '$timeout', function ($compile, $timeout) {

        return {
            restrict: 'A',
            transclude: true,
            scope: {
                vjsSetup: '=?',
                vjsMedia: '=?'
            },
            controller: 'VjsVideoController',
            controllerAs: 'vjsCtrl',
            bindToController: true,
            link: function postLink(scope, element, attrs, ctrl, transclude) {
                var vid,
                    parentContainer,
                    origContent,
                    compiledEl,
                    mediaChangedHandler = function (e) {
                        //remove any inside contents
                        element.children().remove();
                        //add generated sources and tracks
                        element.append(e.element.childNodes);
                    },
                    init = function () {
                        vid = ctrl.getVidElement(element);

                        //attach transcluded content
                        transclude(function (content) {
                            element.append(content);

                            //now that the transcluded content is injected
                            //initialize video.js
                            ctrl.initVideoJs(vid, ctrl, element, mediaChangedHandler);
                        });
                    };

                origContent = element.clone();

                //we need to wrap the video inside of a div
                //for easier DOM management
                if (!element.parent().hasClass('vjs-video-wrap')) {
                    element.wrap('

');
                }

                parentContainer = element.parent();

                scope.$on('vjsVideoMediaChanged', function () {
                    //retreive base element that video.js creates
                    var staleChild = parentContainer.children()[0];

                    //remove current directive instance
                    //destroy will trigger a video.js dispose
                    $timeout(function () {
                        scope.$destroy();
                    });

                    //compile the new directive and add it to the DOM
                    compiledEl = origContent.clone();
                    parentContainer.append(compiledEl);
                    //it is key to pass in the parent scope to the directive
                    compiledEl = $compile(compiledEl)(scope.$parent);

                    //remove original element created by video.js
                    staleChild.remove();
                });

                init();
            }
        };
    }]);

    module.directive('vjsVideoContainer', [function () {

        return {
            restrict: 'AE',
            transclude: true,
            template: '

',
            scope: {
                vjsSetup: '=?',
                vjsRatio: '@',
                vjsMedia: '=?'
            },
            controller: 'VjsVideoController',
            controllerAs: 'vjsCtrl',
            bindToController: true,
            link: function postLink(scope, element, attrs, ctrl, transclude) {
                var vid,
                    origContent,
                    mediaChangedHandler = function (e) {
                        var vidEl = element[0].querySelector('video');

                        if (vidEl) {
                            //remove any inside contents
                            while (vidEl.firstChild) {
                                vidEl.removeChild(vidEl.firstChild);
                            }

                            //add generated sources and tracks
                            while (e.element.childNodes.length > 0) {
                                vidEl.appendChild(e.element.childNodes[0]);
                            }
                        }
                    },
                    init = function () {
                        vid = ctrl.getVidElement(element, true);

                        //we want to confirm that the vjs-video directive or
                        //any corresponding attributes are not defined on the
                        //internal video element
                        if (vid.getAttribute('vjs-video') !== null) {
                            throw new Error(
                                'vjs-video should not be used on the video ' +
                                'tag when using vjs-video-container!');
                        }

                        //we also want to make sure that no vjs-* attributes
                        //are included on the internal video tag
                        if ((vid.getAttribute('vjs-setup') !== null) ||
                            (vid.getAttribute('vjs-media') !== null) ||
                            (vid.getAttribute('vjs-ratio') !== null)) {
                            throw new Error(
                                'directive attributes should not be used on ' +
                                'the video tag when using vjs-video-container!'
                            );

                        }

                        //check if video.js version 5.x is running
                        if (getVersion().match(/^5\./)) {

                            if (ctrl.vjsRatio) {
                                if (!ctrl.vjsSetup) {
                                    ctrl.vjsSetup = {};
                                }

                                ctrl.vjsSetup.aspectRatio = ctrl.vjsRatio;
                            }
                        } else {
                            //set width and height of video to auto
                            vid.setAttribute('width', 'auto');
                            vid.setAttribute('height', 'auto');
                        }

                        //bootstrap video js
                        ctrl.initVideoJs(vid, ctrl, element, mediaChangedHandler);
                    };

                //save original content
                transclude(function (content) {
                    origContent = content.clone();
                });

                scope.$on('vjsVideoMediaChanged', function () {
                    //replace element children with orignal content
                    element.children().remove();
                    element.append(origContent.clone());
                    init();
                });

                init();
            }
        };
    }]);
}());
<|endoftext|>


<commit_before>'use strict';

var async = require('async');
var bodyParser = require('body-parser');
var csrf = require('csurf');
var express = require('express');
var expressVersion = require('express/package.json').version;
var session = require('client-sessions');
var stormpath = require('stormpath');
var controllers = require('./controllers');

var authentication = require('./authentication');
var forms = require('./forms');
var helpers = require('./helpers');
var version = require('../package.json').version;

/**
 * Initialize the Stormpath client.
 *
 * @method
 * @private
 *
 * @param {Object} app - The express application.
 *
 * @return {Function} A function which accepts a callback.
 */
function initClient(app) {
  return function(next) {
    var connection;
    var userAgent = 'stormpath-express/' + version + ' ' + 'express/' + expressVersion;

    if (app.get('stormpathCache') === 'memcached') {
      connection = app.get('stormpathCacheHost')  + ':' + app.get('stormpathCachePort');
    }

    var cacheOptions = {
      store: app.get('stormpathCache'),
      connection: connection || {
        host: app.get('stormpathCacheHost'),
        port: app.get('stormpathCachePort'),
      },
      ttl: app.get('stormpathCacheTTL'),
      tti: app.get('stormpathCacheTTI'),
      options: app.get('stormpathCacheOptions'),
    };

    if (app.get('stormpathApiKeyId') && app.get('stormpathApiKeySecret')) {
      app.set('stormpathClient', new stormpath.Client({
        apiKey: new stormpath.ApiKey(
          app.get('stormpathApiKeyId'),
          app.get('stormpathApiKeySecret')
        ),
        cacheOptions: cacheOptions,
        userAgent: userAgent,
      }));
      next();
    } else if (app.get('stormpathApiKeyFile')) {
      stormpath.loadApiKey(app.get('stormpathApiKeyFile'), function(err, apiKey) {
        app.set('stormpathClient', new stormpath.Client({
          apiKey: apiKey,
          cacheOptions: cacheOptions,
          userAgent: userAgent,
        }));
        next();
      });
    }
  };
}

/**
 * Initialize the Stormpath application.
 *
 * @method
 * @private
 *
 * @param {Object} app - The express application.
 *
 * @return {Function} A function which accepts a callback.
 */
function initApplication(app) {
  return function(next) {
    app.get('stormpathClient').getApplication(app.get('stormpathApplication'), function(err, application) {
      if (err) {
        throw new Error("ERROR: Couldn't find Stormpath application.");
      }

      app.set('stormpathApplication', application);
      next();
    });
  };
}

/**
 * Initialize the Stormpath middleware.
 *
 * @method
 *
 * @param {Object} app - The express application.
 * @param {object} opts - A JSON hash of user supplied options.
 *
 * @return {Function} An express middleware.
 */
module.exports.init = function(app, opts) {
  var router = express.Router();
  opts = opts || {};

  var stormpathMiddleware = function(req, res, next) {
    async.series([
      function(callback) {
        helpers.getUser(req, res, callback);
      }
    ], function() {
      next();
    });
  };

  var urlMiddleware = function(req, res, next) {
    res.locals.url = req.protocol + '://' + req.get('host');
    next();
  };

  async.series([
    helpers.initSettings(app, opts),
    helpers.checkSettings(app),
    initClient(app),
    initApplication(app),
  ]);

  // Parse the request body.
  router.use(bodyParser.urlencoded({ extended: true }));

  // Initialize session middleware.
  router.use(session({
    cookieName: 'stormpathSession',
    requestKey: 'session',
    secret: app.get('stormpathSecretKey'),
    duration: app.get('stormpathSessionDuration'),
    cookie: {
      httpOnly: true,
      secure: app.get('stormpathEnableHttps'),
    }
  }));

  // Build routes.
  if (app.get('stormpathEnableRegistration')) {
    router.use(app.get('stormpathRegistrationUrl'), stormpathMiddleware);
    router.use(app.get('stormpathRegistrationUrl'), urlMiddleware);
    router.use(app.get('stormpathRegistrationUrl'), csrf());
    router.get(app.get('stormpathRegistrationUrl'), controllers.register);
    router.post(app.get('stormpathRegistrationUrl'), controllers.register);
  }

  if (app.get('stormpathEnableLogin')) {
    router.use(app.get('stormpathLoginUrl'), stormpathMiddleware);
    router.use(app.get('stormpathLoginUrl'), urlMiddleware);
    router.use(app.get('stormpathLoginUrl'), csrf());
    router.get(app.get('stormpathLoginUrl'), controllers.login);
    router.post(app.get('stormpathLoginUrl'), controllers.login);
  }

  if (app.get('stormpathEnableGoogle')) {
    router.use(app.get('stormpathGoogleLoginUrl'), stormpathMiddleware);
    router.use(app.get('stormpathGoogleLoginUrl'), urlMiddleware);
    router.get(app.get('stormpathGoogleLoginUrl'), controllers.googleLogin);
  }

  if (app.get('stormpathEnableFacebook')) {
    router.use(app.get('stormpathFacebookLoginUrl'), stormpathMiddleware);
    router.use(app.get('stormpathFacebookLoginUrl'), urlMiddleware);
    router.get(app.get('stormpathFacebookLoginUrl'), controllers.facebookLogin);
  }

  if (app.get('stormpathEnableLogout')) {
    router.use(app.get('stormpathLogoutUrl'), stormpathMiddleware);
    router.use(app.get('stormpathLogoutUrl'), urlMiddleware);
    router.get(app.get('stormpathLogoutUrl'), controllers.logout);
  }

  if (app.get('stormpathEnableForgotPassword')) {
    router.use(app.get('stormpathForgotPasswordUrl'), stormpathMiddleware);
    router.use(app.get('stormpathForgotPasswordUrl'), urlMiddleware);
    router.use(app.get('stormpathForgotPasswordChangeUrl'), stormpathMiddleware);
    router.use(app.get('stormpathForgotPasswordChangeUrl'), urlMiddleware);
    router.use(app.get('stormpathForgotPasswordUrl'), csrf());
    router.use(app.get('stormpathForgotPasswordChangeUrl'), csrf());
    router.get(app.get('stormpathForgotPasswordChangeUrl'), controllers.forgotChange);
    router.post(app.get('stormpathForgotPasswordChangeUrl'), controllers.forgotChange);
    router.get(app.get('stormpathForgotPasswordUrl'), controllers.forgot);
    router.post(app.get('stormpathForgotPasswordUrl'), controllers.forgot);
  }

  if (app.get('stormpathEnableAccountVerification')) {
    router.use(app.get('stormpathAccountVerificationCompleteUrl'), stormpathMiddleware);
    router.use(app.get('stormpathAccountVerificationCompleteUrl'), urlMiddleware);
    router.get(app.get('stormpathAccountVerificationCompleteUrl'), controllers.verificationComplete);
  }

  router.use(app.get('stormpathGetOauthTokenUrl'), stormpathMiddleware);
  router.use(app.get('stormpathGetOauthTokenUrl'), urlMiddleware);
  router.post(app.get('stormpathGetOauthTokenUrl'), controllers.getToken);

  app.use('/', router);
  return stormpathMiddleware;
};

/**
 * Expose the `loginRequired` middleware.
 *
 * @property loginRequired
 */
module.exports.loginRequired = authentication.loginRequired;

/**
 * Expose the `groupsRequired` middleware.
 *
 * @property groupsRequired
 */
module.exports.groupsRequired = authentication.groupsRequired;

/**
 * Expose the `apiAuthenticationRequired` middleware.
 *
 * @property apiAuthenticationRequired
 */
module.exports.apiAuthenticationRequired = authentication.apiAuthenticationRequired;
<commit_msg>Adding in routing for ID site controllers.<commit_after>'use strict';

var async = require('async');
var bodyParser = require('body-parser');
var csrf = require('csurf');
var express = require('express');
var expressVersion = require('express/package.json').version;
var session = require('client-sessions');
var stormpath = require('stormpath');
var controllers = require('./controllers');

var authentication = require('./authentication');
var forms = require('./forms');
var helpers = require('./helpers');
var version = require('../package.json').version;

/**
 * Initialize the Stormpath client.
 *
 * @method
 * @private
 *
 * @param {Object} app - The express application.
 *
 * @return {Function} A function which accepts a callback.
 */
function initClient(app) {
  return function(next) {
    var connection;
    var userAgent = 'stormpath-express/' + version + ' ' + 'express/' + expressVersion;

    if (app.get('stormpathCache') === 'memcached') {
      connection = app.get('stormpathCacheHost')  + ':' + app.get('stormpathCachePort');
    }

    var cacheOptions = {
      store: app.get('stormpathCache'),
      connection: connection || {
        host: app.get('stormpathCacheHost'),
        port: app.get('stormpathCachePort'),
      },
      ttl: app.get('stormpathCacheTTL'),
      tti: app.get('stormpathCacheTTI'),
      options: app.get('stormpathCacheOptions'),
    };

    if (app.get('stormpathApiKeyId') && app.get('stormpathApiKeySecret')) {
      app.set('stormpathClient', new stormpath.Client({
        apiKey: new stormpath.ApiKey(
          app.get('stormpathApiKeyId'),
          app.get('stormpathApiKeySecret')
        ),
        cacheOptions: cacheOptions,
        userAgent: userAgent,
      }));
      next();
    } else if (app.get('stormpathApiKeyFile')) {
      stormpath.loadApiKey(app.get('stormpathApiKeyFile'), function(err, apiKey) {
        app.set('stormpathClient', new stormpath.Client({
          apiKey: apiKey,
          cacheOptions: cacheOptions,
          userAgent: userAgent,
        }));
        next();
      });
    }
  };
}

/**
 * Initialize the Stormpath application.
 *
 * @method
 * @private
 *
 * @param {Object} app - The express application.
 *
 * @return {Function} A function which accepts a callback.
 */
function initApplication(app) {
  return function(next) {
    app.get('stormpathClient').getApplication(app.get('stormpathApplication'), function(err, application) {
      if (err) {
        throw new Error("ERROR: Couldn't find Stormpath application.");
      }

      app.set('stormpathApplication', application);
      next();
    });
  };
}

/**
 * Initialize the Stormpath middleware.
 *
 * @method
 *
 * @param {Object} app - The express application.
 * @param {object} opts - A JSON hash of user supplied options.
 *
 * @return {Function} An express middleware.
 */
module.exports.init = function(app, opts) {
  var router = express.Router();
  opts = opts || {};

  var stormpathMiddleware = function(req, res, next) {
    async.series([
      function(callback) {
        helpers.getUser(req, res, callback);
      }
    ], function() {
      next();
    });
  };

  var urlMiddleware = function(req, res, next) {
    res.locals.url = req.protocol + '://' + req.get('host');
    next();
  };

  async.series([
    helpers.initSettings(app, opts),
    helpers.checkSettings(app),
    initClient(app),
    initApplication(app),
  ]);

  // Parse the request body.
  router.use(bodyParser.urlencoded({ extended: true }));

  // Initialize session middleware.
  router.use(session({
    cookieName: 'stormpathSession',
    requestKey: 'session',
    secret: app.get('stormpathSecretKey'),
    duration: app.get('stormpathSessionDuration'),
    cookie: {
      httpOnly: true,
      secure: app.get('stormpathEnableHttps'),
    }
  }));

  // Build routes.
  if (app.get('stormpathEnableIdSite')) {
    router.get(app.get('stormpathIdSiteUrl'), controllers.idSiteVerify);
  }

  if (app.get('stormpathEnableRegistration')) {
    router.use(app.get('stormpathRegistrationUrl'), stormpathMiddleware);

    if (app.get('stormpathEnableIdSite')) {
      router.get(app.get('stormpathRegistrationUrl'), controllers.idSiteRegister);
    } else {
      router.use(app.get('stormpathRegistrationUrl'), urlMiddleware);
      router.use(app.get('stormpathRegistrationUrl'), csrf());
      router.get(app.get('stormpathRegistrationUrl'), controllers.register);
      router.post(app.get('stormpathRegistrationUrl'), controllers.register);
    }
  }

  if (app.get('stormpathEnableLogin')) {
    router.use(app.get('stormpathLoginUrl'), stormpathMiddleware);

    if (app.get('stormpathEnableIdSite')) {
      router.get(app.get('stormpathLoginUrl'), controllers.idSiteLogin);
    } else {
      router.use(app.get('stormpathLoginUrl'), urlMiddleware);
      router.use(app.get('stormpathLoginUrl'), csrf());
      router.get(app.get('stormpathLoginUrl'), controllers.login);
      router.post(app.get('stormpathLoginUrl'), controllers.login);
    }
  }

  if (app.get('stormpathEnableGoogle')) {
    router.use(app.get('stormpathGoogleLoginUrl'), stormpathMiddleware);
    router.use(app.get('stormpathGoogleLoginUrl'), urlMiddleware);
    router.get(app.get('stormpathGoogleLoginUrl'), controllers.googleLogin);
  }

  if (app.get('stormpathEnableFacebook')) {
    router.use(app.get('stormpathFacebookLoginUrl'), stormpathMiddleware);
    router.use(app.get('stormpathFacebookLoginUrl'), urlMiddleware);
    router.get(app.get('stormpathFacebookLoginUrl'), controllers.facebookLogin);
  }

  if (app.get('stormpathEnableLogout')) {
    router.use(app.get('stormpathLogoutUrl'), stormpathMiddleware);
    router.use(app.get('stormpathLogoutUrl'), urlMiddleware);
    router.get(app.get('stormpathLogoutUrl'), controllers.logout);
  }

  if (app.get('stormpathEnableForgotPassword')) {
    router.use(app.get('stormpathForgotPasswordUrl'), stormpathMiddleware);
    router.use(app.get('stormpathForgotPasswordUrl'), urlMiddleware);
    router.use(app.get('stormpathForgotPasswordChangeUrl'), stormpathMiddleware);
    router.use(app.get('stormpathForgotPasswordChangeUrl'), urlMiddleware);
    router.use(app.get('stormpathForgotPasswordUrl'), csrf());
    router.use(app.get('stormpathForgotPasswordChangeUrl'), csrf());
    router.get(app.get('stormpathForgotPasswordChangeUrl'), controllers.forgotChange);
    router.post(app.get('stormpathForgotPasswordChangeUrl'), controllers.forgotChange);
    router.get(app.get('stormpathForgotPasswordUrl'), controllers.forgot);
    router.post(app.get('stormpathForgotPasswordUrl'), controllers.forgot);
  }

  if (app.get('stormpathEnableAccountVerification')) {
    router.use(app.get('stormpathAccountVerificationCompleteUrl'), stormpathMiddleware);
    router.use(app.get('stormpathAccountVerificationCompleteUrl'), urlMiddleware);
    router.get(app.get('stormpathAccountVerificationCompleteUrl'), controllers.verificationComplete);
  }

  router.use(app.get('stormpathGetOauthTokenUrl'), stormpathMiddleware);
  router.use(app.get('stormpathGetOauthTokenUrl'), urlMiddleware);
  router.post(app.get('stormpathGetOauthTokenUrl'), controllers.getToken);

  app.use('/', router);
  return stormpathMiddleware;
};

/**
 * Expose the `loginRequired` middleware.
 *
 * @property loginRequired
 */
module.exports.loginRequired = authentication.loginRequired;

/**
 * Expose the `groupsRequired` middleware.
 *
 * @property groupsRequired
 */
module.exports.groupsRequired = authentication.groupsRequired;

/**
 * Expose the `apiAuthenticationRequired` middleware.
 *
 * @property apiAuthenticationRequired
 */
module.exports.apiAuthenticationRequired = authentication.apiAuthenticationRequired;
<|endoftext|>


<commit_before>import angular from 'angular';

angular
  .module('drsApp')
  .directive('drsInputPlayer', InputPlayer);

function InputPlayer() {
  const directive = {
    restrict: 'E',
    templateUrl: require('app/scripts/drsInputPlayer.template.html'),
    scope: {},
    controller: InputPlayerCtrl,
    controllerAs: 'vm',
    bindToController: true
  };
  return directive;
}

InputPlayerCtrl.$inject = ['$rootScope', 'Constants', 'PlayerListService', 'SettingsService', 'The100Service'];

function InputPlayerCtrl($rootScope, Constants, PlayerListService, SettingsService, The100Service) {
  const vm = this;

  angular.extend(vm, {
    pl: PlayerListService,
    ss: SettingsService,
    t100s: The100Service
  });

  vm.run = run;
  vm.player = "";
  vm.keyup = keyup;
  vm.toggle = toggle;
  vm.platform = getPlatformFromSettings();

    function run() {
        var input = vm.player;

        var match;
        match = input.match(/the100\.io\/game\/([0-9]+)$/)

        if (match === null) {
            return add();
        } else {
            return the100(match[1]);
        }
    }

    function the100(gameId) {

        const platform = vm.platform ? Constants.platforms[1] : Constants.platforms[0];

        vm.t100s.scrapeGamertags(gameId)
            .then((function (tags) {
                tags.forEach(t => {
                    vm.pl.addPlayer(t, platform)
                })
                vm.player = "";
            }))
    }

  function add() {
    const platform = vm.platform ? Constants.platforms[1] : Constants.platforms[0];

    vm.pl.addPlayer(vm.player, platform)
      .then(function success() {
        vm.player = "";
      }, function failure(error) {
        console.log("PSN Id or Gamertag input failure: %o", error);
        vm.player = "";
      });
  }

  function getPlatformFromSettings() {
    // map XBox/PlayStation to true/false. Defaults to PlayStation.
    return SettingsService.platform === Constants.platforms[1];
  }

  function keyup(event) {
    if (event.keyCode === 13) {
      vm.run();
    }
  }

  function toggle(platform) {
    // map true/false to XBox/PlayStation.
    const active = platform ? Constants.platforms[1] : Constants.platforms[0];
    vm.ss.platform = active;
    vm.ss.save();
  }

  $rootScope.$on("drs-settings-loaded", function() {
    vm.platform = getPlatformFromSettings();
  });
}<commit_msg>s/var/const<commit_after>import angular from 'angular';

angular
  .module('drsApp')
  .directive('drsInputPlayer', InputPlayer);

function InputPlayer() {
  const directive = {
    restrict: 'E',
    templateUrl: require('app/scripts/drsInputPlayer.template.html'),
    scope: {},
    controller: InputPlayerCtrl,
    controllerAs: 'vm',
    bindToController: true
  };
  return directive;
}

InputPlayerCtrl.$inject = ['$rootScope', 'Constants', 'PlayerListService', 'SettingsService', 'The100Service'];

function InputPlayerCtrl($rootScope, Constants, PlayerListService, SettingsService, The100Service) {
  const vm = this;

  angular.extend(vm, {
    pl: PlayerListService,
    ss: SettingsService,
    t100s: The100Service
  });

  vm.run = run;
  vm.player = "";
  vm.keyup = keyup;
  vm.toggle = toggle;
  vm.platform = getPlatformFromSettings();

    function run() {
        const input = vm.player;

        const match = input.match(/the100\.io\/game\/([0-9]+)$/)

        if (match === null) {
            return add();
        } else {
            return the100(match[1]);
        }
    }

    function the100(gameId) {

        const platform = vm.platform ? Constants.platforms[1] : Constants.platforms[0];

        vm.t100s.scrapeGamertags(gameId)
            .then((function (tags) {
                tags.forEach(t => {
                    vm.pl.addPlayer(t, platform)
                })
                vm.player = "";
            }))
    }

  function add() {
    const platform = vm.platform ? Constants.platforms[1] : Constants.platforms[0];

    vm.pl.addPlayer(vm.player, platform)
      .then(function success() {
        vm.player = "";
      }, function failure(error) {
        console.log("PSN Id or Gamertag input failure: %o", error);
        vm.player = "";
      });
  }

  function getPlatformFromSettings() {
    // map XBox/PlayStation to true/false. Defaults to PlayStation.
    return SettingsService.platform === Constants.platforms[1];
  }

  function keyup(event) {
    if (event.keyCode === 13) {
      vm.run();
    }
  }

  function toggle(platform) {
    // map true/false to XBox/PlayStation.
    const active = platform ? Constants.platforms[1] : Constants.platforms[0];
    vm.ss.platform = active;
    vm.ss.save();
  }

  $rootScope.$on("drs-settings-loaded", function() {
    vm.platform = getPlatformFromSettings();
  });
}
<|endoftext|>


<commit_before>/*
 * structures
 *
 *
 * Copyright (c) 2013 Mark Selby
 * Licensed under the MIT license.
 */

'use strict';

var EventEmitter = require('events').EventEmitter;
var Util = require('util');

var Structure = function (structure, parent, params, name) {
  EventEmitter.call(this);

  // Structure to fulfil. Contains :
  // source: method to call that returns a query
  // parent_key: the parent field name for attaching related children
  // key: the field name in our rows to match to the parent rows
  // children: optional substructures for retrieving related sub-data
  this.structure = structure;

  // Parent is set if we're from a children substructure
  this.parent = parent;

  // Store the params to pass on to queries
  this._params = params;

  // Child rows take their name from the structure declaration
  this.name = name;

  this.prepare();
};

Util.inherits(Structure, EventEmitter);

var p = Structure.prototype;

p.init = function () {
  // Execute the source query for this part of the structure
  this.structure.source(this.params())
    .on('row', Array.isArray(this.rows) ? this.rootRow.bind(this) : this.childRow.bind(this))
    .on('error', this.error.bind(this))
    .on('end', this.end.bind(this))
    .execute();
};

p.prepare = function () {
  // This is the root, so we just place the result rows into an array
  if (!this.parent) {
    this.rows = [];
    return;
  }
  if (!this.structure.parent_key) {
    throw 'No parent key defined for : ' + Util.inspect(this.structure);
  }
  if (!this.structure.key) {
    throw 'No key defined for : ' + Util.inspect(this.structure);
  }
  if (!this.parent.rows) {
    throw 'No rows defined for parent : ' + Util.inspect(this.parent);
  }
  if (!this.parent.rows[0][this.structure.parent_key]) {
    throw 'Parent result is missing parent_key field : ' + Util.inspect(this.structure);
  }

  // Create a placholder index into child rows
  this.rows = {};
  // Iterate the parent rows
  this.parent.rows.forEach(function (row) {
    // Ignore parent rows where parent_key field is null-ish
    if (!row[this.structure.parent_key]) { return; }
    // Create results placeholder on each parent row
    row[this.name] = [];
    // Create the indexed by parent key pointer into the parent rows
    this.rows[row[this.structure.parent_key]] = row[this.name];
  }.bind(this));
};

// If it's the root query then we just stuff the result into the array from prepare()
p.rootRow = function (row) {
  this.rows.push(row);
};

// Child rows need to honour the keys
p.childRow = function (row) {
  this.rows[row[this.structure.key]].push(row);
};

p.params = function () {
  return Array.isArray(this.rows) ? this._params : { id: Object.keys(this.rows) };
};

// This particular part of the structure has completed
p.end = function () {
  // Only if we have rows should we bother trying to fetch any child rows
  if (this.rows.length && this.structure.children) {
    this.pending = 0;
    this.keys = {};
    Object.keys(this.structure.children).forEach(function (name) {
      this.pending++;
      new Structure(this.structure.children[name], this, this.params(), name)
        .on('done', this.childDone.bind(this))
        .on('error', this.error.bind(this))
        .init();
    }.bind(this));
  } else {
    this.emit('done', this.target);
  }
};

p.error = function (err) {
  throw 'Structure error : ' + err + ' processing ' + Util.inspect(this.structure);
};

p.childDone = function () {
  this.pending--;
  if (!this.pending) {
    this.emit('done', this.rows);
  }
};

module.exports = Structure;
<commit_msg>Separated parent row concept from this._row<commit_after>/*
 * structures
 *
 *
 * Copyright (c) 2013 Mark Selby
 * Licensed under the MIT license.
 */

'use strict';

var EventEmitter = require('events').EventEmitter;
var Util = require('util');

var Structure = function (structure, parent, params, name) {
  EventEmitter.call(this);

  // Structure to fulfil. Contains :
  // source: method to call that returns a query
  // parent_key: the parent field name for attaching related children
  // key: the field name in our rows to match to the parent rows
  // children: optional substructures for retrieving related sub-data
  this.structure = structure;

  // Parent is set if we're from a children substructure
  this.parent = parent;

  // Store the params to pass on to queries
  this._params = params;

  // Child rows take their name from the structure declaration
  this.name = name;

  // console.log(structure);

  this.prepare();
};

Util.inherits(Structure, EventEmitter);

var p = Structure.prototype;

p.init = function () {
  // Execute the source query for this part of the structure
  this.structure.source(this.params())
    .on('row', Array.isArray(this._rows) ? this.rootRow.bind(this) : this.childRow.bind(this))
    .on('error', this.error.bind(this))
    .on('end', this.end.bind(this))
    .execute();
};

p.prepare = function () {
  // This is the root, so we just place the result rows into an array
  if (!this.parent) {
    this._rows = [];
    return;
  }
  if (!this.structure.parent_key) {
    throw 'No parent key defined for : ' + Util.inspect(this.structure);
  }
  if (!this.structure.key) {
    throw 'No key defined for : ' + Util.inspect(this.structure);
  }
  if (!this.parentRows()) {
    throw 'No rows defined for parent : ' + Util.inspect(this.parent);
  }
  // console.log('Parent rows : ' + Util.inspect(this.parent.rows()[0]));
  // if (!this.parent._rows[0][this.structure.parent_key]) {
  if (!this.parentRows()[0][this.structure.parent_key]) {
    throw 'Parent result is missing parent_key field : ' + Util.inspect(this.structure);
  }

  // Create a placholder index into child rows
  this._rows = {};
  // Iterate the parent rows
  this.parentRows().forEach(function (row) {
    // Ignore parent rows where parent_key field is null-ish
    if (!row[this.structure.parent_key]) { return; }
    // Create results placeholder on each parent row
    row[this.name] = [];
    // Create the indexed by parent key pointer into the parent rows
    this._rows[row[this.structure.parent_key]] = row[this.name];
  }.bind(this));
};

// If it's the root query then we just stuff the result into the array from prepare()
p.rootRow = function (row) {
  this._rows.push(row);
};

// Child rows need to honour the keys
p.childRow = function (row) {
  this._rows[row[this.structure.key]].push(row);
};

p.params = function () {
  // return Array.isArray(this._rows) ? this._params : { id: Object.keys(this._rows) };
  return this.parent ? { id: Object.keys(this._rows) } : this._params;
};

// Return the rows as an array, whether array (root) or hash (child data)
p.parentRows = function () {
  if (!this._parentRows) {
    this._parentRows = Array.isArray(this.parent._rows) ? this.parent._rows : [].concat.apply([], Object.keys(this.parent._rows).map(function (k) { return this.parent._rows[k]; }.bind(this)));
  }
  return this._parentRows;
};

// This particular part of the structure has completed
p.end = function () {
  // Only if we have rows should we bother trying to fetch any child rows
  // if (this._rows.length && this.structure.children) {
  if (this.structure.children) {
    this.pending = 0;
    this.keys = {};
    Object.keys(this.structure.children).forEach(function (name) {
      this.pending++;
      new Structure(this.structure.children[name], this, this.params(), name)
        .on('done', this.childDone.bind(this))
        .on('error', this.error.bind(this))
        .init();
    }.bind(this));
  } else {
    this.emit('done', this.target);
  }
};

p.error = function (err) {
  throw 'Structure error : ' + err + ' processing ' + Util.inspect(this.structure);
};

p.childDone = function () {
  this.pending--;
  if (!this.pending) {
    this.emit('done', this._rows);
  }
};

module.exports = Structure;
<|endoftext|>


<commit_before>define(['backbone.marionette', 'hbs!../templates/module'],
  function (Marionette, template) {
    'use strict';

    return Marionette.ItemView.extend({
      template: template,
      initialize: function (data) {

      },
      events: {
        'click .show-full-desc': 'showFullDescription'
      },
      onShow: function () {
        var code = this.model.get('module').ModuleCode;
        DISQUS.reset({
          reload: true,
          config: function () {
            this.page.identifier = code;
            this.page.url = window.location.href;
          }
        });
      },
      showFullDescription: function ($ev) {
        $('.module-desc').addClass('module-desc-more');
        return false;
      }
    });
  });
<commit_msg>Set disqus page title and hardcode url to nusmods.com<commit_after>define(['backbone.marionette', 'hbs!../templates/module'],
  function (Marionette, template) {
    'use strict';

    return Marionette.ItemView.extend({
      template: template,
      initialize: function (data) {

      },
      events: {
        'click .show-full-desc': 'showFullDescription'
      },
      onShow: function () {
        var module = this.model.get('module');
        DISQUS.reset({
          reload: true,
          config: function () {
            var code = module.ModuleCode;
            this.page.identifier = code;
            this.page.title = code + ' ' + module.ModuleTitle + ' · Reviews';
            this.page.url = 'http://nusmods.com/#!/modules/' + code + '/reviews';
          }
        });
      },
      showFullDescription: function ($ev) {
        $('.module-desc').addClass('module-desc-more');
        return false;
      }
    });
  });
<|endoftext|>


<commit_before>
/**
 * subdomain middleware
 * keep shipping next()
 */

module.exports = function(options) {

  if (options.base === undefined) {
    throw new Error('options.base required!');
  } else {
    var matches = options.base.split('.');
    if (matches.length !== 2) {
      throw new Error('unrecognized domain name!');
    } else {
      options.prefix = matches[0];
      options.sufix = matches[1];
    }
  }

  // return middleware
  return function(request, response, next) {

    // get host
    var host = request.headers.host;

    // remove 'www' prefix from URL? (tacky, right?)
    if (options.removeWWW && options.removeWWW === true) {
      if (/^www/.test(host)){
        return response.redirect('http://' + host.replace(/^www\./, '') + request.url);
      };
    };

    // subdomain specific middleware
    if (host === options.base || host === 'localhost:8000') {
      // not a subdomain
      next();
    } else {
      // get subdomain
      var matches = host.match(new RegExp('(.*)\.' + options.prefix + '\.' + options.sufix));
      if (matches.length === 2) {
        var _subdomain = matches[1];
        response.send(_subdomain);
      } else {
        next();
      }
    };
  };

};

/* EOF */<commit_msg>[forceWWW]<commit_after>
/**
 * subdomain middleware
 * keep shipping next()
 */

module.exports = function(options) {

  if (options.base === undefined) {
    throw new Error('options.base required!');
  } else {
    var matches = options.base.split('.');
    if (matches.length !== 2) {
      throw new Error('unrecognized domain name!');
    } else {
      options.prefix = matches[0];
      options.sufix = matches[1];
    }
  }

  // return middleware
  return function(request, response, next) {

    // get host
    var host = request.headers.host;

    // remove 'www' prefix from URL? (tacky, right?)
    if (options.removeWWW && options.removeWWW === true) {
      if (/^www/.test(host)){
        response.redirect('http://' + host.replace(/^www\./, '') + request.url);
        next();
      };
    };

    // subdomain specific middleware
    if (host === options.base || host === 'localhost:8000') {
      // not a subdomain
      next();
    } else {
      // get subdomain
      var matches = host.match(new RegExp('(.*)\.' + options.prefix + '\.' + options.sufix));
      if (matches.length === 2) {
        var _subdomain = matches[1];
        response.send(_subdomain);
      } else {
        next();
      }
    };
  };

};

/* EOF */<|endoftext|>


<commit_before>'use strict';

let _ = require('lodash'),
  errors = require('../routes/shared/errors'),
  mixins = require('./concerns'),
  machine = require('../../config/machine'),
  versions = require('../../config/versions');

const LATEST_VERSIONS = _.first(versions);

module.exports = function(sequelize, DataTypes) {
  let Cluster = sequelize.define('Cluster', mixins.extend('state', 'attributes', {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      defaultValue: DataTypes.UUIDV1,
      unique: true
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: null,
      unique: true,
      validate: { len: [1, 64] }
    },
    token: {
      type: DataTypes.TEXT,
      allowNull: true,
      defaultValue: null,
      unique: true
    },
    strategy: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: 'spread',
      validate: {
        isIn: {
          args: [['spread', 'binpack', 'random']],
          msg: 'Must be spread, binpack or random'
        }
      }
    },
    docker_version: {
      type: DataTypes.STRING,
      allowNull: true,
      defaultValue: null,
    },
    swarm_version: {
      type: DataTypes.STRING,
      allowNull: true,
      defaultValue: null,
    },
    containers_count: DataTypes.VIRTUAL
  }, DataTypes), mixins.extend('state', 'options', {
    defaultScope: {
      order: [['id', 'ASC']]
    },
    getterMethods: {
      state_message: function() {
        let state = this.get('state');

        switch (state) {
          case 'empty':
            return 'Create at least one node to work with this cluster';
          case 'unreachable':
            return 'Master node is unreachable';
          case 'deploying':
            return 'One or more node(s) are beeing deployed';
          case 'upgrading':
            return 'One or more node(s) are beeing upgraded';
          case 'running':
            return 'Cluster is running and reachable';
        }
      },
    },
    hooks: {
      beforeCreate: function(cluster) {
        _.merge(cluster, {
          docker_version: LATEST_VERSIONS.docker,
          swarm_version:  LATEST_VERSIONS.swarm
        });
        return cluster._initializeToken();
      },
      afterCreate: function(cluster) {
        return cluster._initializeCert();
      },
      afterDestroy: function(cluster) {
        return cluster._destroyToken();
      },
    },
    instanceMethods: {
      _initializeToken: function() {
        return machine.createToken().then(token => {
          this.token = token;
        });
      },
      _initializeCert: function() {
        return machine.createCerts().then(certs => {
          let params = {};

          _.keys(certs).forEach(type => {
            _.keys(certs[type]).forEach(name => {
              params[`${type}_${name}`] = certs[type][name];
            });
          });
          return this.createCert(params);
        });
      },
      _destroyToken: function() {
        return machine.deleteToken(this.token);
      },
      _hasLatestVersions: function() {
        return LATEST_VERSIONS.docker === this.docker_version &&
               LATEST_VERSIONS.swarm  === this.swarm_version;
      },
      notify: function(changes) {
        if (_.has(changes, 'last_ping')) {
          return this.update({ last_ping: changes.last_ping });
        }
        switch (changes.last_state) {
          case 'deploying':
          case 'upgrading':
            return this.update({ last_state: changes.last_state });
          case 'running':
            return this.getNodes({ where: {
              last_state: { $ne: changes.last_state } }
            }).then(nodes => {
              if (nodes.length > 0) {
                return this.update({ last_state: _.first(nodes).last_state });
              }
              return this.update({ last_state: changes.last_state });
            });
        }
        return Promise.resolve(this);
      },
      upgrade: function() {
        let state = this.get('state');

        if (state !== 'running') {
          return Promise.reject(new errors.StateError('upgrade', state));
        }
        if (this._hasLatestVersions()) {
          return Promise.reject(new errors.AlreadyUpgradedError());
        }
        return this.getNodes().then(nodes => {
          _.invoke(nodes, 'upgrade', versions);

          return this.update({
            docker_version: LATEST_VERSIONS.docker,
            swarm_version:  LATEST_VERSIONS.swarm,
            last_state: 'upgrading'
          });
        });
      }
    },
    classMethods: {
      associate: function(models) {
        Cluster.hasMany(models.Node, { onDelete: 'cascade',
          counterCache: { as: 'nodes_count' }
        });
        Cluster.hasOne(models.Cert, { onDelete: 'cascade' });
      }
    }
  }));
  return Cluster;
};
<commit_msg>refactor notify<commit_after>'use strict';

let _ = require('lodash'),
  errors = require('../routes/shared/errors'),
  mixins = require('./concerns'),
  machine = require('../../config/machine'),
  versions = require('../../config/versions');

const LATEST_VERSIONS = _.first(versions);

module.exports = function(sequelize, DataTypes) {
  let Cluster = sequelize.define('Cluster', mixins.extend('state', 'attributes', {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      defaultValue: DataTypes.UUIDV1,
      unique: true
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: null,
      unique: true,
      validate: { len: [1, 64] }
    },
    token: {
      type: DataTypes.TEXT,
      allowNull: true,
      defaultValue: null,
      unique: true
    },
    strategy: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: 'spread',
      validate: {
        isIn: {
          args: [['spread', 'binpack', 'random']],
          msg: 'Must be spread, binpack or random'
        }
      }
    },
    docker_version: {
      type: DataTypes.STRING,
      allowNull: true,
      defaultValue: null,
    },
    swarm_version: {
      type: DataTypes.STRING,
      allowNull: true,
      defaultValue: null,
    },
    containers_count: DataTypes.VIRTUAL
  }, DataTypes), mixins.extend('state', 'options', {
    defaultScope: {
      order: [['id', 'ASC']]
    },
    getterMethods: {
      state_message: function() {
        let state = this.get('state');

        switch (state) {
          case 'empty':
            return 'Create at least one node to work with this cluster';
          case 'unreachable':
            return 'Master node is unreachable';
          case 'deploying':
            return 'One or more node(s) are beeing deployed';
          case 'upgrading':
            return 'One or more node(s) are beeing upgraded';
          case 'running':
            return 'Cluster is running and reachable';
        }
      },
    },
    hooks: {
      beforeCreate: function(cluster) {
        _.merge(cluster, {
          docker_version: LATEST_VERSIONS.docker,
          swarm_version:  LATEST_VERSIONS.swarm
        });
        return cluster._initializeToken();
      },
      afterCreate: function(cluster) {
        return cluster._initializeCert();
      },
      afterDestroy: function(cluster) {
        return cluster._destroyToken();
      },
    },
    instanceMethods: {
      _initializeToken: function() {
        return machine.createToken().then(token => {
          this.token = token;
        });
      },
      _initializeCert: function() {
        return machine.createCerts().then(certs => {
          let params = {};

          _.keys(certs).forEach(type => {
            _.keys(certs[type]).forEach(name => {
              params[`${type}_${name}`] = certs[type][name];
            });
          });
          return this.createCert(params);
        });
      },
      _destroyToken: function() {
        return machine.deleteToken(this.token);
      },
      _hasLatestVersions: function() {
        return LATEST_VERSIONS.docker === this.docker_version &&
               LATEST_VERSIONS.swarm  === this.swarm_version;
      },
      _getLastStateFromNodes: function() {
        return this.getNodes({ where: {
          last_state: { $ne: 'running' }
        }}).then(nodes => {
          if (nodes.length > 0) {
            return _.first(nodes).last_state;
          }
          return 'running';
        });
      },
      notify: function(changes) {
        if (_.has(changes, 'last_ping')) {
          return this.update({ last_ping: changes.last_ping });
        }
        switch (changes.last_state) {
          case 'deploying':
          case 'upgrading':
            return this.update({ last_state: changes.last_state });
          case 'running':
            return this._getLastStateFromNodes().then(lastState => {
              return this.update({ last_state: lastState });
            });
        }
        return Promise.resolve(this);
      },
      upgrade: function() {
        let state = this.get('state');

        if (state !== 'running') {
          return Promise.reject(new errors.StateError('upgrade', state));
        }
        if (this._hasLatestVersions()) {
          return Promise.reject(new errors.AlreadyUpgradedError());
        }
        return this.getNodes().then(nodes => {
          _.invoke(nodes, 'upgrade', versions);

          return this.update({
            docker_version: LATEST_VERSIONS.docker,
            swarm_version:  LATEST_VERSIONS.swarm,
            last_state: 'upgrading'
          });
        });
      }
    },
    classMethods: {
      associate: function(models) {
        Cluster.hasMany(models.Node, { onDelete: 'cascade',
          counterCache: { as: 'nodes_count' }
        });
        Cluster.hasOne(models.Cert, { onDelete: 'cascade' });
      }
    }
  }));
  return Cluster;
};
<|endoftext|>


<commit_before>var request = require('superagent'),
    Promise = require('bluebird');

var METHOD_MAP = {
  'create': 'post',
  'update': 'put',
  'delete': 'del',
  'read': 'get',
  'patch': 'patch'
};

// Main exported sync function. Returns a promise to mimic Backbone + jQuery,
// if using the built in cache support it will check the cache for data or send
// off the HTTP request.
module.exports = function(method, model, options) {
  return new Promise(function(resolve, reject) {
    var url = (options.url ||
      (typeof model.url == 'function' ? model.url() : model.url));
    var data = (options.data ||
      (method === 'create' || method === 'update' ? model.toJSON(options) : {}));
    var cacheKey = url + JSON.stringify(data);

    // DRY up success/error handling and HTTP sending request
    var success = function(res) {
      options.res = { headers: res.headers };
      if (options.success) options.success(res.body);
      if (options.complete) options.complete(res.body);
      resolve(res.body);
    }
    var error = function(err) {
      if (options.error) options.error(err);
      if (options.complete) options.complete(err);
      reject(err);
    }
    var send = function() {
      request[METHOD_MAP[method]](url)
        .send(method == 'create' || method == 'update' ? data : null)
        .query(method == 'create' || method == 'update' ? null : data)
        .set(options.headers || {})
        .timeout(options.timeout || module.exports.timeout)
        .end(function(err, res) {
          if (err || !res.ok) return error(err || res);
          // Save result in cache
          if (options.cache && module.exports.cacheClient) {
            module.exports.cacheClient.set(cacheKey, JSON.stringify({
              body: res.body,
              headers: res.headers
            }));
            module.exports.cacheClient.expire(cacheKey,
              (options.cacheTime || module.exports.defaultCacheTime));
          }
          // Resolve success
          success(res);
        });
    }

    // If cached, check cache—otherwise just send. Trigger request regardless
    if (options.cache && module.exports.cacheClient) {
      module.exports.cacheClient.get(cacheKey, function(err, cachedJSON) {
        if (err) {
          error(err);
        } else if (cachedJSON) {
          success(JSON.parse(cachedJSON));
        } else {
          send();
        }
      });
    } else {
      send();
    }
  });
}

Promise.onPossiblyUnhandledRejection(console.warn);

// Configuration that can be overwritten by the user. Includes a optional
// cache client library integration, default cache expiry, and
// the default timeout for a sent http request.
module.exports.cacheClient = null;
module.exports.defaultCacheTime = 3600;
module.exports.timeout = 10000;
<commit_msg>latest<commit_after>var request = require('superagent');
var Promise = require('bluebird');

var METHOD_MAP = {
  'create': 'post',
  'update': 'put',
  'delete': 'del',
  'read': 'get',
  'patch': 'patch'
};

// Main exported sync function. Returns a Q promise to mimic Backbone + jQuery,
// if using the built in cache support it will check the cache for data or send
// off the HTTP request.
//
// @param {Function} method
// @param {Object} model
// @param {Object} options
// @return {Object} A Q promise to mimc how Backbone work with jQuery

module.exports = function(method, model, options) {
  var cacheKey = urlDataCacheKey(method, model, options)[2];
  return new Promise(function(resolve, reject) {
    if (options.cache && module.exports.cacheClient) {
      module.exports.cacheClient.get(cacheKey, function(err, cachedJSON) {
        if (err || cachedJSON) model.trigger('request', model, {}, options);
        if (err) {
          error(options, err, reject);
        } else if (cachedJSON) {
          success(options, JSON.parse(cachedJSON), resolve);
        } else {
          send(method, model, options, resolve, reject);
        }
      });
    } else {
      send(method, model, options, resolve, reject);
    }
  });
};

// Helper to compute the requesting url, params, and cache key based off those
// two. Used when sending a new http request or determing the cache key to read.
//
// @param {Function} method
// @param {Object} model
// @param {Object} options
// @return {Array} Array of [url, data, cacheKey]

var urlDataCacheKey = function(method, model, options) {
  var url = (options.url ||
    (typeof model.url == 'function' ? model.url() : model.url));
  var data = (options.data ||
    (method === 'create' || method === 'update' ? model.toJSON(options) : {}));
  var cacheKey = url + JSON.stringify(data);
  return [url, data, cacheKey];
}

// Builds and sends the actual http request. This reflects the guts of the
// default Backbone.sync logic.
//
// @param {Function} method
// @param {Object} model
// @param {Object} options
// @param {Function} resolve Deferred resolve
// @param {Function} reject  Deferred reject

var send = function (method, model, options, resolve, reject) {
  var url = urlDataCacheKey(method, model, options)[0];
  var data = urlDataCacheKey(method, model, options)[1];
  var cacheKey = urlDataCacheKey(method, model, options)[2];

  // Allow intercepting of the request object to inject sync-wide things like
  // an oAuth token.
  request[METHOD_MAP[method]](url)
    .send(method == 'create' || method == 'update' ? data : null)
    .query(method == 'create' || method == 'update' ? null : data)
    .set(options.headers || {})
    .timeout(options.timeout || module.exports.timeout)
    .end(function(err, res) {
      if (err || !res.ok) return error(options, (err || res), reject);
      if (options.cache && module.exports.cacheClient) {
        module.exports.cacheClient.set(cacheKey, JSON.stringify({
          body: res.body,
          headers: res.headers
        }));
        module.exports.cacheClient.expire(cacheKey,
          (options.cacheTime || module.exports.defaultCacheTime));
      }
      success(options, res, resolve);
    });
  model.trigger('request', model, {});
}

// DRYs up resolving the callbacks and deferreds for a successful response,
// whether that's from the cache or a resolved http request.
//
// @param {Object} options Backbone options
// @param {Object} res A response object with { body: {}, headers: {} }
// @param {Function} resolve Deferred resolve

var success = function(options, res, resolve) {
  options.res = { headers: res.headers };
  if (options.success) options.success(res.body);
  if (options.complete) options.complete(res.body);
  resolve(res.body);
}

// DRYs up resolving the callbacks and deferreds for an unsuccessful response,
// whether that's from the cache or a resolved http request.
//
// @param {Object} options Backbone options
// @param {Object} err
// @param {Function} reject  Deferred reject

var error = function(options, err, reject) {
  if (options.error) options.error(err);
  if (options.complete) options.complete(err);
  reject(err);
}

// Configuration that can be overwritten by the user. Includes a optional
// cache client library integration, default cache expiry, and
// the default timeout for a sent http request.

module.exports.cacheClient = null;
module.exports.defaultCacheTime = 3600;
module.exports.timeout = 2000;
<|endoftext|>


<commit_before>define(['backbone', 'underscore', 'jquery', 'BaseNodeView'], function(Backbone, _, $, BaseNodeView) {

  return BaseNodeView.extend({

    initialize: function(args) {

      BaseNodeView.prototype.initialize.apply(this, arguments);

      this.model.on('change:selected', this.colorSelected, this);
      this.model.on('change:visible', this.changeVisibility, this);
      this.model.on('remove', this.onRemove, this);
      this.model.on('change:prettyLastValue', this.onEvalComplete, this );
      this.model.workspace.on('change:current', this.changeVisibility, this);

      this.onEvalComplete();

    },

    setMaterials: function(partMat, meshMat, lineMat){

      this.threeGeom.traverse(function(ele) {
        if (ele instanceof THREE.Mesh) {
          ele.material = meshMat;
        } else if (ele instanceof THREE.Line) {
          ele.material = lineMat;
        } else {
          ele.material = partMat;
        }
      });

      render();

    },

    colorSelected: function(){

      BaseNodeView.prototype.colorSelected.apply(this, arguments);

      if ( !( this.threeGeom && this.model.get('visible')) ) return this;

      if (this.model.get('selected')) {

        var meshMat = new THREE.MeshPhongMaterial({color: 0x00FFFF});
        var partMat = new THREE.ParticleBasicMaterial({color: 0x00FFFF, size: 3, sizeAttenuation: false});
        var lineMat = new THREE.LineBasicMaterial({ color: 0x00ffff });

      } else {

        var meshMat = new THREE.MeshPhongMaterial({color: 0x999999});
        var partMat = new THREE.ParticleBasicMaterial({color: 0x999999, size: 3, sizeAttenuation: false});
        var lineMat = new THREE.LineBasicMaterial({ color: 0x000000 });

      }

      this.setMaterials(partMat, meshMat, lineMat);

      return this;

    },

    formatPreview: function(data){

      // ugh this is terrible code

      if (!data) return null;

      if (!data.normal && !data.polygons && !data.vertices)
        return BaseNodeView.prototype.formatPreview.apply(this, arguments);

      if (data.length > 0 && !data[0].normal && !data[0].polygons && !data[0].vertices)
        return BaseNodeView.prototype.formatPreview.apply(this, arguments);

      if (data.normal) return "Plane";
      if (data.polygons) return "Solid";
      if (data.vertices) return "Polygon";

      if (data.length) {

        var solidCount = 0;
        var polyCount = 0;
        var planeCount = 0;

        for (var i = 0; i < data.length; i++) {
          if ( data[i].polygons ) solidCount++;
          if ( data[i].normal ) planeCount++;
          if ( data[i].vertices ) polyCount++;
        }

        var solidString = solidCount + " Solids";
        var polyString = polyCount + " Polygons";
        var planeString = planeCount + " Planes";

        var stringArr = [];

        if (solidCount > 0) stringArr.push(solidString);
        if (planeCount > 0) stringArr.push(planeString);
        if (polyCount > 0) stringArr.push(polyString);

        if (planeCount === 0 && solidCount === 0 && polyCount === 0) return "Nothing";

        return stringArr.join(',');

      }
      return "Nothing";

    },

    // 3D move to node subclass
    onRemove: function(){
      this.model.workspace.off('change:current', this.changeVisibility, this);
      scene.remove(this.threeGeom);
      render();
    },

    evaluated: false,

    toThreeGeom: function( rawGeom ) {

      var threeGeom = new THREE.Geometry(), face;

      if (!rawGeom) return threeGeom;

      if (!rawGeom.vertices && !rawGeom.linestrip ) return threeGeom;

      if (rawGeom.linestrip) return this.addLineStrip( rawGeom, threeGeom );

      if (rawGeom.vertices && !rawGeom.faces) return addPoints( rawGeom, threeGeom );

      for ( var i = 0; i < rawGeom.vertices.length; i++ ) {
        var v = rawGeom.vertices[i];
        threeGeom.vertices.push( new THREE.Vector3( v[0], v[1], v[2] ) );
      }

      if (!rawGeom.faces) return threeGeom;

      for ( var i = 0; i < rawGeom.faces.length; i++ ) {
        var f = rawGeom.faces[i];
        face = new THREE.Face3( f[0], f[1], f[2], new THREE.Vector3( f[3][0], f[3][1], f[3][2] ) );
        threeGeom.faces.push( face );
      }

      threeGeom._floodType = 0;

      return threeGeom;

    },

    addPoints: function( rawGeom, threeGeom ){

      for ( var i = 0; i < rawGeom.vertices.length; i++ ) {
        var v = rawGeom.vertices[i];
        threeGeom.vertices.push( new THREE.Vector3( v[0], v[1], v[2] ) );
      }

      threeGeom._floodType = 1;

      return threeGeom;
    },

    addLineStrip: function( rawGeom, threeGeom ){

      console.log('add line strip')
      for ( var i = 0; i < rawGeom.linestrip.length; i++ ) {
        var v = rawGeom.linestrip[i];
        threeGeom.vertices.push( new THREE.Vector3( v[0], v[1], v[2] ) );
      }

      threeGeom._floodType = 2;

      return threeGeom;

    },

    onEvalComplete: function(a, b, newValue){

      if (!newValue && this.evaluated) return;

      this.evaluated = true;

      var lastValue = this.model.get('prettyLastValue');
      var temp;

      if ( !lastValue ) return;

      if ( lastValue.vertices || lastValue.linestrip ){
        temp = [];
        temp.push(lastValue);
      } else {
        temp = lastValue; // extract the list
      }

      var threeTemp = new THREE.Object3D();
      this.drawChunked( threeTemp, temp, function() {

        if ( this.threeGeom ){
          scene.remove( this.threeGeom );
        }

        this.threeGeom = threeTemp;

        scene.add( this.threeGeom );

        this.changeVisibility();

      }, this );

    },

    // creating this data may be quite slow, we'll need to be careful
    drawChunked: function(geom, list, callback, that){

      var i = 0;
      var tick = function() {

        var start = new Date().getTime();
        for (; i < list.length && (new Date().getTime()) - start < 50; i++) {

          var g3  = that.toThreeGeom( list[i] );

          if (that.model.get('selected')){
            var color = 0x00FFFF;
          } else {
            var color = 0x999999;
          }

          switch (g3._floodType) {
            case 0:
              geom.add( new THREE.Mesh(g3, new THREE.MeshPhongMaterial({color: color})) );
              break;
            case 1:
              geom.add( new THREE.ParticleSystem(g3, new THREE.ParticleBasicMaterial({color: color, size: 3, sizeAttenuation: false}) ));
              break;
            case 2:
              geom.add( new THREE.Line(g3, new THREE.LineBasicMaterial({ color: 0x000000 })));
              break;
          }

        }

        if (i < list.length) {
          setTimeout(tick, 25);
        } else {
          callback.call(that);
        }

      };

      setTimeout(tick, 0);

    },

    changeVisibility: function(){

      if ( !this.threeGeom ){
        return;
      }

      if (!this.model.get('visible') || !this.model.workspace.get('current') )
      {
        scene.remove(this.threeGeom);
      } else if ( this.model.get('visible') )
      {
        scene.add(this.threeGeom);
      }

      render();

    },

    renderNode: function() {

      BaseNodeView.prototype.renderNode.apply(this, arguments);

      this.$toggleVis = this.$el.find('.toggle-vis');
      this.$toggleVis.show();

      var icon = this.$toggleVis.find('i');
      var label = this.$toggleVis.find('span');

      if (this.model.get('visible')){
        icon.addClass('icon-eye-open');
        icon.removeClass('icon-eye-close');
        label.html('Hide geometry');
      } else {
        icon.removeClass('icon-eye-open');
        icon.addClass('icon-eye-close');
        label.html('Show geometry');
      }

      return this;

    },

  });

});<commit_msg>A few fixes for incorrect preview values<commit_after>define(['backbone', 'underscore', 'jquery', 'BaseNodeView'], function(Backbone, _, $, BaseNodeView) {

  return BaseNodeView.extend({

    initialize: function(args) {

      BaseNodeView.prototype.initialize.apply(this, arguments);

      this.model.on('change:selected', this.colorSelected, this);
      this.model.on('change:visible', this.changeVisibility, this);
      this.model.on('remove', this.onRemove, this);
      this.model.on('change:prettyLastValue', this.onEvalComplete, this );
      this.model.workspace.on('change:current', this.changeVisibility, this);

      this.onEvalComplete();

    },

    setMaterials: function(partMat, meshMat, lineMat){

      this.threeGeom.traverse(function(ele) {
        if (ele instanceof THREE.Mesh) {
          ele.material = meshMat;
        } else if (ele instanceof THREE.Line) {
          ele.material = lineMat;
        } else {
          ele.material = partMat;
        }
      });

      render();

    },

    colorSelected: function(){

      BaseNodeView.prototype.colorSelected.apply(this, arguments);

      if ( !( this.threeGeom && this.model.get('visible')) ) return this;

      if (this.model.get('selected')) {

        var meshMat = new THREE.MeshPhongMaterial({color: 0x00FFFF});
        var partMat = new THREE.ParticleBasicMaterial({color: 0x00FFFF, size: 3, sizeAttenuation: false});
        var lineMat = new THREE.LineBasicMaterial({ color: 0x00ffff });

      } else {

        var meshMat = new THREE.MeshPhongMaterial({color: 0x999999});
        var partMat = new THREE.ParticleBasicMaterial({color: 0x999999, size: 3, sizeAttenuation: false});
        var lineMat = new THREE.LineBasicMaterial({ color: 0x000000 });

      }

      this.setMaterials(partMat, meshMat, lineMat);

      return this;

    },

    formatPreview: function(data){

      // ugh this is terrible code

      if (data == null || data === undefined)
        return BaseNodeView.prototype.formatPreview.apply(this, arguments);

      if (data.length === undefined && !data.normal && !data.polygons && !data.vertices)
        return BaseNodeView.prototype.formatPreview.apply(this, arguments);

      if (data.length > 0 && !data[0].normal && !data[0].polygons && !data[0].vertices)
        return BaseNodeView.prototype.formatPreview.apply(this, arguments);

      if (data.normal) return "Plane";
      if (data.polygons) return "Solid";
      if (data.vertices) return "Polygon";

      if (data.length) {

        var solidCount = 0;
        var polyCount = 0;
        var planeCount = 0;

        for (var i = 0; i < data.length; i++) {
          if ( data[i].polygons ) solidCount++;
          if ( data[i].normal ) planeCount++;
          if ( data[i].vertices ) polyCount++;
        }

        var solidString = solidCount + " Solids";
        var polyString = polyCount + " Polygons";
        var planeString = planeCount + " Planes";

        var stringArr = [];

        if (solidCount > 0) stringArr.push(solidString);
        if (planeCount > 0) stringArr.push(planeString);
        if (polyCount > 0) stringArr.push(polyString);

        if (planeCount === 0 && solidCount === 0 && polyCount === 0) return "Nothing";

        return stringArr.join(',');

      }
      return "Nothing";

    },

    // 3D move to node subclass
    onRemove: function(){
      this.model.workspace.off('change:current', this.changeVisibility, this);
      scene.remove(this.threeGeom);
      render();
    },

    evaluated: false,

    toThreeGeom: function( rawGeom ) {

      var threeGeom = new THREE.Geometry(), face;

      if (!rawGeom) return threeGeom;

      if (!rawGeom.vertices && !rawGeom.linestrip ) return threeGeom;

      if (rawGeom.linestrip) return this.addLineStrip( rawGeom, threeGeom );

      if (rawGeom.vertices && !rawGeom.faces) return addPoints( rawGeom, threeGeom );

      for ( var i = 0; i < rawGeom.vertices.length; i++ ) {
        var v = rawGeom.vertices[i];
        threeGeom.vertices.push( new THREE.Vector3( v[0], v[1], v[2] ) );
      }

      if (!rawGeom.faces) return threeGeom;

      for ( var i = 0; i < rawGeom.faces.length; i++ ) {
        var f = rawGeom.faces[i];
        face = new THREE.Face3( f[0], f[1], f[2], new THREE.Vector3( f[3][0], f[3][1], f[3][2] ) );
        threeGeom.faces.push( face );
      }

      threeGeom._floodType = 0;

      return threeGeom;

    },

    addPoints: function( rawGeom, threeGeom ){

      for ( var i = 0; i < rawGeom.vertices.length; i++ ) {
        var v = rawGeom.vertices[i];
        threeGeom.vertices.push( new THREE.Vector3( v[0], v[1], v[2] ) );
      }

      threeGeom._floodType = 1;

      return threeGeom;
    },

    addLineStrip: function( rawGeom, threeGeom ){

      console.log('add line strip')
      for ( var i = 0; i < rawGeom.linestrip.length; i++ ) {
        var v = rawGeom.linestrip[i];
        threeGeom.vertices.push( new THREE.Vector3( v[0], v[1], v[2] ) );
      }

      threeGeom._floodType = 2;

      return threeGeom;

    },

    onEvalComplete: function(a, b, newValue){

      if (!newValue && this.evaluated) return;

      this.evaluated = true;

      var lastValue = this.model.get('prettyLastValue');
      var temp;

      if ( !lastValue ) return;

      if ( lastValue.vertices || lastValue.linestrip ){
        temp = [];
        temp.push(lastValue);
      } else {
        temp = lastValue; // extract the list
      }

      var threeTemp = new THREE.Object3D();
      this.drawChunked( threeTemp, temp, function() {

        if ( this.threeGeom ){
          scene.remove( this.threeGeom );
        }

        this.threeGeom = threeTemp;

        scene.add( this.threeGeom );

        this.changeVisibility();

      }, this );

    },

    // creating this data may be quite slow, we'll need to be careful
    drawChunked: function(geom, list, callback, that){

      var i = 0;
      var tick = function() {

        var start = new Date().getTime();
        for (; i < list.length && (new Date().getTime()) - start < 50; i++) {

          var g3  = that.toThreeGeom( list[i] );

          if (that.model.get('selected')){
            var color = 0x00FFFF;
          } else {
            var color = 0x999999;
          }

          switch (g3._floodType) {
            case 0:
              geom.add( new THREE.Mesh(g3, new THREE.MeshPhongMaterial({color: color})) );
              break;
            case 1:
              geom.add( new THREE.ParticleSystem(g3, new THREE.ParticleBasicMaterial({color: color, size: 3, sizeAttenuation: false}) ));
              break;
            case 2:
              geom.add( new THREE.Line(g3, new THREE.LineBasicMaterial({ color: 0x000000 })));
              break;
          }

        }

        if (i < list.length) {
          setTimeout(tick, 25);
        } else {
          callback.call(that);
        }

      };

      setTimeout(tick, 0);

    },

    changeVisibility: function(){

      if ( !this.threeGeom ){
        return;
      }

      if (!this.model.get('visible') || !this.model.workspace.get('current') )
      {
        scene.remove(this.threeGeom);
      } else if ( this.model.get('visible') )
      {
        scene.add(this.threeGeom);
      }

      render();

    },

    renderNode: function() {

      BaseNodeView.prototype.renderNode.apply(this, arguments);

      this.$toggleVis = this.$el.find('.toggle-vis');
      this.$toggleVis.show();

      var icon = this.$toggleVis.find('i');
      var label = this.$toggleVis.find('span');

      if (this.model.get('visible')){
        icon.addClass('icon-eye-open');
        icon.removeClass('icon-eye-close');
        label.html('Hide geometry');
      } else {
        icon.removeClass('icon-eye-open');
        icon.addClass('icon-eye-close');
        label.html('Show geometry');
      }

      return this;

    },

  });

});<|endoftext|>


<commit_before>// door.js
//
// mongo data model definition for a Revit door instance.
//
// Copyright 2015 by Jeremy Tammik, Autodesk Inc.

var mongoose = require( 'mongoose' );

var Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;

var RvtUniqueId = String;

// use Revit UniqueId for door instances.

var doorSchema = new Schema(
  { _id          : RvtUniqueId // suppress automatic generation
    , project_id : String
    , level      : String
    , tag        : String
    , firerating : Number },
  { _id: false } // suppress automatic generation
);

mongoose.model( 'Door', doorSchema );
<commit_msg>removed unused ObjectId definition<commit_after>// door.js
//
// mongo data model definition for a Revit door instance.
//
// Copyright 2015 by Jeremy Tammik, Autodesk Inc.

var mongoose = require( 'mongoose' );

var Schema = mongoose.Schema;

var RvtUniqueId = String;

// use Revit UniqueId for door instances.

var doorSchema = new Schema(
  { _id          : RvtUniqueId // suppress automatic generation
    , project_id : String
    , level      : String
    , tag        : String
    , firerating : Number },
  { _id: false } // suppress automatic generation
);

mongoose.model( 'Door', doorSchema );
<|endoftext|>


<commit_before>import 'babel-polyfill';
import parse, { tokensToString } from './lexer';
import range from './types/range';
import keyword from './types/keyword';
import block from './types/block';

const version = require('../../package.json').version;

export default {
  parse,
  tokensToString,
  range,
  keyword,
  block,
  version
};
<commit_msg>export middleware until it's in it's own repo<commit_after>import 'babel-polyfill';
import parse, { tokensToString } from './lexer';
import range from './types/range';
import keyword from './types/keyword';
import block from './types/block';
import tsv from '../middleware/tsv';

const version = require('../../package.json').version;

export default {
  parse,
  range,
  keyword,
  block,
  middleware: { tsv },
  tokensToString,
  version
};
<|endoftext|>


<commit_before>export default class TokenStack {
  constructor() {
    this.stack = { all: [] };
  }

  at(index, name = 'all') {
    return this.stack[name] && this.stack[name][index];
  }

  push(token) {
    this.stack.all.push(token);
    if (this.stack[token.name] instanceof Array === false) {
      this.stack[token.name] = [];
    }
    this.stack[token.name].push(token);
  }

  pop() {
    let token = this.stack.all.pop();
    if (token) this.stack[token.name].pop();
    return token;
  }

  contains(name) {
    if (this.stack[name]) {
      if (this.stack[name].length > 0) return true;
    }
    return false;
  }

  get length() {
    return this.stack.all.length;
  }
}

export function isInTable(blocks) {
  return blocks.contains('TABLE') || blocks.contains('TABLE_ROW') || blocks.contains('TABLE_CELL');
}
<commit_msg>added last property and renamed arg for isInTable<commit_after>export default class TokenStack {
  constructor() {
    this.stack = { all: [] };
  }

  at(index, name = 'all') {
    return this.stack[name] && this.stack[name][index];
  }

  push(token) {
    this.stack.all.push(token);
    if (this.stack[token.name] instanceof Array === false) {
      this.stack[token.name] = [];
    }
    this.stack[token.name].push(token);
  }

  pop() {
    let token = this.stack.all.pop();
    if (token) this.stack[token.name].pop();
    return token;
  }

  contains(name) {
    if (this.stack[name]) {
      if (this.stack[name].length > 0) return true;
    }
    return false;
  }

  get length() {
    return this.stack.all.length;
  }

  get last() {
    let index = this.stack.all.length - 1;
    return this.stack.all[index];
  }
}

export function isInTable(stack) {
  return stack.contains('TABLE') || stack.contains('TABLE_ROW') || stack.contains('TABLE_CELL');
}
<|endoftext|>