<commit_before>/**
 This Source Code is licensed under the MIT license. If a copy of the
 MIT-license was not distributed with this file, You can obtain one at:
 http://opensource.org/licenses/mit-license.html.

 @author: Hans van den Akker (mysim1)
 @license MIT
 @copyright Bizboard, 2015

 */

import _                            from 'lodash';
import {Router}                     from '../core/Router';
import {Provide, annotate}  from 'di.js';
import Easing                       from 'famous/transitions/Easing';
import AnimationController          from 'famous-flex/src/AnimationController';

export class ArvaRouter extends Router {

    constructor() {
        super();

        if (window == null) {
            return;
        }

        this.routes = {};
        this.history = [];
        this.decode = decodeURIComponent;

        window.addEventListener('hashchange', this.run);

    }

    /**
     * Set the initial controller and method to be activated whenever the controllers are activated.
     * @param controller
     * @param method
     */
    setDefault(controller, method = null) {

        this.defaultController = Object.getPrototypeOf(controller).constructor.name
            .replace('Controller', '');

        if (method != null) { this.defaultMethod = method }
    }

    setControllerSpecs(specs) {
        this.specs = specs;
    }

    /**
     * Force navigation to one of the controllers
     * @param controller
     * @param method
     * @param params
     */
    go(controller, method, params=null) {

        let controllerName = '';
        if (Object.getPrototypeOf(controller).constructor.name=="Function")
            controllerName = controller.name;
        else controllerName = Object.getPrototypeOf(controller).constructor.name;

        let routeRoot = controllerName
            .replace(this.defaultController, '')
            .replace('Controller', '');

        let hash = '#' + (routeRoot.length > 0 ? '/' + routeRoot : '') + ('/' + method);
        if (params) {
            for(let i=0;i< Object.keys(params).length;i++) {
                var key = Object.keys(params)[i];
                hash+=i==0?'?':'&';
                hash+=(key+'='+params[key]);
            }
        }

        if (history.pushState) {
            history.pushState(null, null, hash);
        }

        this.run();
    }

    /**
     * Register a single controller
     * @param {String} route
     * @param {Function} handler
     */
    add(route, handler) {
        let pieces = route.split('/'),
            rules = this.routes;

        for (let i = 0; i < pieces.length; ++i) {
            let piece = pieces[i],
                name = piece[0] === ':' ? ':' : piece;

            rules = rules[name] || (rules[name] = {});

            if (name === ':') {
                rules['@name'] = piece.slice(1);
            }
        }

        rules['@'] = handler;

    }

    /**
     * On a route change, call the corresponding controller method with the given parameter values.
     * @returns {boolean}
     */
    run() {

        //if (!url || typeof(url) == 'object')
        let url = window.location.hash.replace('#', ''); // || '#';

        if (url !== '') {
            url = url.replace('/?', '?');
            url[0] === '/' && (url = url.slice(1));
            url.slice(-1) === '/' && (url = url.slice(0, -1));
        }

        let rules = this.routes,
            querySplit = url.split('?'),
            pieces = querySplit[0].split('/'),
            values = [],
            keys = [],
            method = '';
        let rule = null;
        let controller = null;

        // if there is no controller reference, assume we have hit the default Controller
        if (pieces.length === 1 && pieces[0].length === 0) {
            pieces[0] = this.defaultController;
            pieces.push(this.defaultMethod);
        }
        else if (pieces.length === 1 && pieces[0].length > 0) {
            pieces.unshift(this.defaultController);
        }

        controller = pieces[0];

        // Parse the non-query portion of the URL...
        for (let i = 0; i < pieces.length && rules; ++i) {
            let piece = this.decode(pieces[i]);
            rule = rules[piece];

            if (!rule && (rule = rules[':'])) {
                method = piece;
            }

            rules = rules[piece];
        }

        (function parseQuery(q) {
            let query = q.split('&');

            for (let i = 0; i < query.length; ++i) {
                let nameValue = query[i].split('=');

                if (nameValue.length > 1) {
                    keys.push(nameValue[0]);
                    values.push(this.decode(nameValue[1]));
                }
            }
        }).call(this, querySplit.length > 1 ? querySplit[1] : '');

        if (rule && rule['@']) {

            /* Push current route to the history stack for later use */
            let previousRoute = this.history.length ? this.history[this.history.length - 1] : undefined;
            let currentRoute = {
                url: url,
                controller: controller,
                method: method,
                keys: keys,
                values: values
            };
            currentRoute.spec = previousRoute ? this._getAnimationSpec(previousRoute, currentRoute) : {};
            this._setHistory(currentRoute);

            // make the controller active for current scope
            rule['@'](currentRoute);

            return true;
        } else {
            console.log('Controller doesn\'t exist!');
        }

        return false;
    }

    /**
     * Checks if the current route is already present in the history stack, and if so removes all entries after
     * and including the first occurrence. It will then append the current route to the history stack.
     * @param currentRoute Route object containing url, controller, method, keys, and values.
     * @private
     */
    _setHistory(currentRoute) {
        for (let i = 0; i < this.history.length; i++) {
            let previousRoute = this.history[i];
            if (currentRoute.controller === previousRoute.controller &&
                currentRoute.method === previousRoute.method &&
                _.isEqual(currentRoute.values, previousRoute.values)) {
                this.history.splice(i, this.history.length - i);
                break;
            }
        }

        this.history.push(currentRoute);
    }

    /**
     * Method to check whether a route is already present in the history stack.
     * @param currentRoute Route object containing url, controller, method, keys, and values.
     * @returns {boolean}
     * @private
     */
    _hasVisited(currentRoute) {
        for (let i = 0; i < this.history.length; i++) {
            let previousRoute = this.history[i];
            if (currentRoute.controller === previousRoute.controller &&
                currentRoute.method === previousRoute.method &&
                _.isEqual(currentRoute.values, previousRoute.values)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the Famous-Flex animation spec for two given routes. Takes its spec inputs from the specs set in
     * router.setControllerSpecs(), which is called from the app constructor.
     * @param previousRoute Previous route object containing url, controller, method, keys, and values.
     * @param currentRoute Current route object containing url, controller, method, keys, and values.
     * @returns {*} A spec object if one is found, or an empty object otherwise.
     * @private
     */
    _getAnimationSpec(previousRoute, currentRoute) {
        let fromController = previousRoute.controller;
        let toController = currentRoute.controller;

        if (fromController.indexOf('Controller') === -1) {
            fromController += 'Controller';
        }
        if (toController.indexOf('Controller') === -1) {
            toController += 'Controller';
        }

        /* We're on exactly the same page as before */
        if (currentRoute.controller === previousRoute.controller &&
            currentRoute.method === previousRoute.method &&
            _.isEqual(currentRoute.values, previousRoute.values)) {
            return {};
        }

        /* Same controller, different method or different parameters */
        if (currentRoute.controller === previousRoute.controller) {

            let direction = this._hasVisited(currentRoute) ? 'previous' : 'next';
            if (this.specs && this.specs[fromController] && this.specs[fromController].methods) {
                return this.specs[fromController].methods[direction];
            }

            /* Default method-to-method animations, used only if not overridden in app's controllers spec. */
            let defaults = {
                'previous': {
                    transition: {duration: 1000, curve: Easing.outBack},
                    animation: AnimationController.Animation.Slide.Right
                },
                'next': {
                    transition: {duration: 1000, curve: Easing.outBack},
                    animation: AnimationController.Animation.Slide.Left
                }
            };
            return defaults[direction];
        }

        /* Different controller */
        if (this.specs && this.specs.hasOwnProperty(toController) && this.specs[toController].controllers) {
            let controllerSpecs = this.specs[toController].controllers;
            for (let specIndex in controllerSpecs) {
                let spec = controllerSpecs[specIndex];
                if (spec.activeFrom && spec.activeFrom.indexOf(fromController) !== -1) {
                    return spec;
                }
            }
        }

        console.log('No spec defined from ' + fromController + ' to ' + toController + '. Please check router.setControllerSpecs() in your app constructor.')
    }

}

annotate(ArvaRouter, new Provide(Router));<commit_msg>setDefault now supports instance and classes.<commit_after>/**
 This Source Code is licensed under the MIT license. If a copy of the
 MIT-license was not distributed with this file, You can obtain one at:
 http://opensource.org/licenses/mit-license.html.

 @author: Hans van den Akker (mysim1)
 @license MIT
 @copyright Bizboard, 2015

 */

import _                            from 'lodash';
import {Router}                     from '../core/Router';
import {Provide, annotate}  from 'di.js';
import Easing                       from 'famous/transitions/Easing';
import AnimationController          from 'famous-flex/src/AnimationController';

export class ArvaRouter extends Router {

    constructor() {
        super();

        if (window == null) {
            return;
        }

        this.routes = {};
        this.history = [];
        this.decode = decodeURIComponent;

        window.addEventListener('hashchange', this.run);

    }

    /**
     * Set the initial controller and method to be activated whenever the controllers are activated.
     * @param controller
     * @param method
     */
    setDefault(controller, method = null) {

        let controllerName = '';
        if (Object.getPrototypeOf(controller).constructor.name=="Function")
            controllerName = controller.name;
        else controllerName = Object.getPrototypeOf(controller).constructor.name;
        this.defaultController = controllerName
            .replace('Controller', '');

        if (method != null) { this.defaultMethod = method; }
    }

    setControllerSpecs(specs) {
        this.specs = specs;
    }

    /**
     * Force navigation to one of the controllers
     * @param controller
     * @param method
     * @param params
     */
    go(controller, method, params=null) {

        let controllerName = '';
        if (Object.getPrototypeOf(controller).constructor.name=="Function")
            controllerName = controller.name;
        else controllerName = Object.getPrototypeOf(controller).constructor.name;

        let routeRoot = controllerName
            .replace(this.defaultController, '')
            .replace('Controller', '');

        let hash = '#' + (routeRoot.length > 0 ? '/' + routeRoot : '') + ('/' + method);
        if (params) {
            for(let i=0;i< Object.keys(params).length;i++) {
                var key = Object.keys(params)[i];
                hash+=i==0?'?':'&';
                hash+=(key+'='+params[key]);
            }
        }

        if (history.pushState) {
            history.pushState(null, null, hash);
        }

        this.run();
    }

    /**
     * Register a single controller
     * @param {String} route
     * @param {Function} handler
     */
    add(route, handler) {
        let pieces = route.split('/'),
            rules = this.routes;

        for (let i = 0; i < pieces.length; ++i) {
            let piece = pieces[i],
                name = piece[0] === ':' ? ':' : piece;

            rules = rules[name] || (rules[name] = {});

            if (name === ':') {
                rules['@name'] = piece.slice(1);
            }
        }

        rules['@'] = handler;

    }

    /**
     * On a route change, call the corresponding controller method with the given parameter values.
     * @returns {boolean}
     */
    run() {

        //if (!url || typeof(url) == 'object')
        let url = window.location.hash.replace('#', ''); // || '#';

        if (url !== '') {
            url = url.replace('/?', '?');
            url[0] === '/' && (url = url.slice(1));
            url.slice(-1) === '/' && (url = url.slice(0, -1));
        }

        let rules = this.routes,
            querySplit = url.split('?'),
            pieces = querySplit[0].split('/'),
            values = [],
            keys = [],
            method = '';
        let rule = null;
        let controller = null;

        // if there is no controller reference, assume we have hit the default Controller
        if (pieces.length === 1 && pieces[0].length === 0) {
            pieces[0] = this.defaultController;
            pieces.push(this.defaultMethod);
        }
        else if (pieces.length === 1 && pieces[0].length > 0) {
            pieces.unshift(this.defaultController);
        }

        controller = pieces[0];

        // Parse the non-query portion of the URL...
        for (let i = 0; i < pieces.length && rules; ++i) {
            let piece = this.decode(pieces[i]);
            rule = rules[piece];

            if (!rule && (rule = rules[':'])) {
                method = piece;
            }

            rules = rules[piece];
        }

        (function parseQuery(q) {
            let query = q.split('&');

            for (let i = 0; i < query.length; ++i) {
                let nameValue = query[i].split('=');

                if (nameValue.length > 1) {
                    keys.push(nameValue[0]);
                    values.push(this.decode(nameValue[1]));
                }
            }
        }).call(this, querySplit.length > 1 ? querySplit[1] : '');

        if (rule && rule['@']) {

            /* Push current route to the history stack for later use */
            let previousRoute = this.history.length ? this.history[this.history.length - 1] : undefined;
            let currentRoute = {
                url: url,
                controller: controller,
                method: method,
                keys: keys,
                values: values
            };
            currentRoute.spec = previousRoute ? this._getAnimationSpec(previousRoute, currentRoute) : {};
            this._setHistory(currentRoute);

            // make the controller active for current scope
            rule['@'](currentRoute);

            return true;
        } else {
            console.log('Controller doesn\'t exist!');
        }

        return false;
    }

    /**
     * Checks if the current route is already present in the history stack, and if so removes all entries after
     * and including the first occurrence. It will then append the current route to the history stack.
     * @param currentRoute Route object containing url, controller, method, keys, and values.
     * @private
     */
    _setHistory(currentRoute) {
        for (let i = 0; i < this.history.length; i++) {
            let previousRoute = this.history[i];
            if (currentRoute.controller === previousRoute.controller &&
                currentRoute.method === previousRoute.method &&
                _.isEqual(currentRoute.values, previousRoute.values)) {
                this.history.splice(i, this.history.length - i);
                break;
            }
        }

        this.history.push(currentRoute);
    }

    /**
     * Method to check whether a route is already present in the history stack.
     * @param currentRoute Route object containing url, controller, method, keys, and values.
     * @returns {boolean}
     * @private
     */
    _hasVisited(currentRoute) {
        for (let i = 0; i < this.history.length; i++) {
            let previousRoute = this.history[i];
            if (currentRoute.controller === previousRoute.controller &&
                currentRoute.method === previousRoute.method &&
                _.isEqual(currentRoute.values, previousRoute.values)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the Famous-Flex animation spec for two given routes. Takes its spec inputs from the specs set in
     * router.setControllerSpecs(), which is called from the app constructor.
     * @param previousRoute Previous route object containing url, controller, method, keys, and values.
     * @param currentRoute Current route object containing url, controller, method, keys, and values.
     * @returns {*} A spec object if one is found, or an empty object otherwise.
     * @private
     */
    _getAnimationSpec(previousRoute, currentRoute) {
        let fromController = previousRoute.controller;
        let toController = currentRoute.controller;

        if (fromController.indexOf('Controller') === -1) {
            fromController += 'Controller';
        }
        if (toController.indexOf('Controller') === -1) {
            toController += 'Controller';
        }

        /* We're on exactly the same page as before */
        if (currentRoute.controller === previousRoute.controller &&
            currentRoute.method === previousRoute.method &&
            _.isEqual(currentRoute.values, previousRoute.values)) {
            return {};
        }

        /* Same controller, different method or different parameters */
        if (currentRoute.controller === previousRoute.controller) {

            let direction = this._hasVisited(currentRoute) ? 'previous' : 'next';
            if (this.specs && this.specs[fromController] && this.specs[fromController].methods) {
                return this.specs[fromController].methods[direction];
            }

            /* Default method-to-method animations, used only if not overridden in app's controllers spec. */
            let defaults = {
                'previous': {
                    transition: {duration: 1000, curve: Easing.outBack},
                    animation: AnimationController.Animation.Slide.Right
                },
                'next': {
                    transition: {duration: 1000, curve: Easing.outBack},
                    animation: AnimationController.Animation.Slide.Left
                }
            };
            return defaults[direction];
        }

        /* Different controller */
        if (this.specs && this.specs.hasOwnProperty(toController) && this.specs[toController].controllers) {
            let controllerSpecs = this.specs[toController].controllers;
            for (let specIndex in controllerSpecs) {
                let spec = controllerSpecs[specIndex];
                if (spec.activeFrom && spec.activeFrom.indexOf(fromController) !== -1) {
                    return spec;
                }
            }
        }

        console.log('No spec defined from ' + fromController + ' to ' + toController + '. Please check router.setControllerSpecs() in your app constructor.')
    }

}

annotate(ArvaRouter, new Provide(Router));<|endoftext|>


<commit_before>module.exports = function ( karma ) {
  karma.configure({
    /**
     * From where to look for files, starting with the location of this file.
     */
    basePath: '../',

    /**
     * This is the list of file patterns to load into the browser during testing.
     */
    files: [
      <% scripts.forEach( function ( file ) { %>'<%= file %>',
      <% }); %>
      'src/**/*.js',
    ],
    exclude: [
      'src/assets/**/*.js'
    ],
    frameworks: [ 'jasmine' ],
    plugins: [ 'karma-jasmine', 'karma-firefox-launcher', 'karma-chrome-launcher', 'karma-phantomjs-launcher', 'karma-coffee-preprocessor' ],
    preprocessors: {
    },

    /**
     * How to report, by default.
     */
    reporters: 'dots',

    /**
     * On which port should the browser connect, on which port is the test runner
     * operating, and what is the URL path for the browser to use.
     */
    port: 9001,
    runnerPort: 9002,
    urlRoot: '/',

    /**
     * Disable file watching by default.
     */
    autoWatch: false,

    /**
     * The list of browsers to launch to test on. This includes only "Firefox" by
     * default, but other browser names include:
     * Chrome, ChromeCanary, Firefox, Opera, Safari, PhantomJS
     *
     * Note that you can also use the executable name of the browser, like "chromium"
     * or "firefox", but that these vary based on your operating system.
     *
     * You may also leave this blank and manually navigate your browser to
     * http://localhost:9018/ when you're running tests. The window/tab can be left
     * open and the tests will automatically occur there during the build. This has
     * the aesthetic advantage of not launching a browser every time you save.
     */
    browsers: [
      'Firefox'
    ]
  });
};

<commit_msg>moving to chrome<commit_after>module.exports = function ( karma ) {
  karma.configure({
    /**
     * From where to look for files, starting with the location of this file.
     */
    basePath: '../',

    /**
     * This is the list of file patterns to load into the browser during testing.
     */
    files: [
      <% scripts.forEach( function ( file ) { %>'<%= file %>',
      <% }); %>
      'src/**/*.js',
    ],
    exclude: [
      'src/assets/**/*.js'
    ],
    frameworks: [ 'jasmine' ],
    plugins: [ 'karma-jasmine', 'karma-firefox-launcher', 'karma-chrome-launcher', 'karma-phantomjs-launcher', 'karma-coffee-preprocessor' ],
    preprocessors: {
    },

    /**
     * How to report, by default.
     */
    reporters: 'dots',

    /**
     * On which port should the browser connect, on which port is the test runner
     * operating, and what is the URL path for the browser to use.
     */
    port: 9001,
    runnerPort: 9002,
    urlRoot: '/',

    /**
     * Disable file watching by default.
     */
    autoWatch: false,

    /**
     * The list of browsers to launch to test on. This includes only "Firefox" by
     * default, but other browser names include:
     * Chrome, ChromeCanary, Firefox, Opera, Safari, PhantomJS
     *
     * Note that you can also use the executable name of the browser, like "chromium"
     * or "firefox", but that these vary based on your operating system.
     *
     * You may also leave this blank and manually navigate your browser to
     * http://localhost:9018/ when you're running tests. The window/tab can be left
     * open and the tests will automatically occur there during the build. This has
     * the aesthetic advantage of not launching a browser every time you save.
     */
    browsers: [
      'Chrome'
    ]
  });
};

<|endoftext|>


<commit_before>import {takeLatest} from 'redux-saga';
import {call, fork, put} from 'redux-saga/effects';
import {arrayOf} from 'normalizr';
import {receiveAddress} from './actions';
import {mapActions} from './constants';
import {receiveUnits, setFetchError} from '../unit/actions';
import {getFetchUnitsRequest} from '../unit/helpers';
import {unitSchema} from '../unit/constants';
import {createUrl, createRequest, callApi, normalizeEntityResults} from '../api/helpers';

function* onSetLocation({payload: position}: FetchAction) {
  const addressParams = {
    lat: position[0],
    lon: position[1],
    page_size: 1
  };
  const addressRequest = createRequest(createUrl('address/', addressParams));
  const {bodyAsJson: addressJson} = yield call(callApi, addressRequest);
  const addressData = addressJson.results ? addressJson.results[0] : null;
  yield put(receiveAddress(addressData));

  const unitParams = {
  };

  const unitRequest = getFetchUnitsRequest(unitParams);
  const {response, bodyAsJson: unitJson} = yield call(callApi, unitRequest);

  if(response.status === 200) {
    const data = normalizeEntityResults(unitJson.results, arrayOf(unitSchema));
    yield put(receiveUnits(data));
  } else {
    yield put(setFetchError(unitJson.results));
  }
}

function* watchSetLocation() {
  yield takeLatest(mapActions.SET_LOCATION, onSetLocation);
}

export default function* saga() {
  return [
    yield fork(watchSetLocation)
  ];
}
<commit_msg>Remove unnecessary API call on location set.<commit_after>import {takeLatest} from 'redux-saga';
import {call, fork, put} from 'redux-saga/effects';
import {arrayOf} from 'normalizr';
import {receiveAddress} from './actions';
import {mapActions} from './constants';
import {receiveUnits, setFetchError} from '../unit/actions';
import {getFetchUnitsRequest} from '../unit/helpers';
import {unitSchema} from '../unit/constants';
import {createUrl, createRequest, callApi, normalizeEntityResults} from '../api/helpers';

function* onSetLocation({payload: position}: FetchAction) {
  const addressParams = {
    lat: position[0],
    lon: position[1],
    page_size: 1
  };
  const addressRequest = createRequest(createUrl('address/', addressParams));
  const {bodyAsJson: addressJson} = yield call(callApi, addressRequest);
  const addressData = addressJson.results ? addressJson.results[0] : null;
  yield put(receiveAddress(addressData));
}

function* watchSetLocation() {
  yield takeLatest(mapActions.SET_LOCATION, onSetLocation);
}

export default function* saga() {
  return [
    yield fork(watchSetLocation)
  ];
}
<|endoftext|>


<commit_before>// Universal Subtitles, universalsubtitles.org
//
// Copyright (C) 2010 Participatory Culture Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see
// http://www.gnu.org/licenses/agpl-3.0.html.

goog.provide('mirosubs.timeline.Timeline');
goog.require('goog.fx.Dragger');
goog.require('goog.style.cursor');

/**
 *
 * @param {number} spacing The space, in seconds, between two
 *     major ticks.
 * @param {mirosubs.timeline.SubtitleSet} subtitleSet
 */
mirosubs.timeline.Timeline = function(spacing, subtitleSet, videoPlayer) {
    goog.ui.Component.call(this);
    this.spacing_ = spacing;
    this.subtitleSet_ = subtitleSet;
    this.videoPlayer_ = videoPlayer;
};
goog.inherits(mirosubs.timeline.Timeline, goog.ui.Component);
mirosubs.timeline.Timeline.prototype.createDom = function() {
    mirosubs.timeline.Timeline.superClass_.createDom.call(this);
    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());
    var el = this.getElement();
    el.className = 'mirosubs-timeline';
    el.appendChild($d('div', 'top', ' '));
    this.timelineInner_ = new mirosubs.timeline.TimelineInner(
        this, this.spacing_, this.subtitleSet_);
    this.addChild(this.timelineInner_, true);
    el.appendChild($d('div', 'marker'));
};
/**
 * Useful for when times are cleared.
 */
mirosubs.timeline.Timeline.prototype.reset_ = function() {
    this.removeChild(this.timelineInner_, true);
    this.timelineInner_.dispose();
    this.timelineInner_ = new mirosubs.timeline.TimelineInner(
        this, this.spacing_, this.subtitleSet_);
    this.addChild(this.timelineInner_, true);
};
mirosubs.timeline.Timeline.prototype.enterDocument = function() {
    mirosubs.timeline.Timeline.superClass_.enterDocument.call(this);
    this.getHandler().
        listen(
            this.videoPlayer_,
            mirosubs.video.AbstractVideoPlayer.EventType.TIMEUPDATE,
            this.videoTimeUpdate_).
        listen(
            this.timelineInner_,
            goog.object.getValues(
                mirosubs.timeline.TimelineSub.EventType),
            this.timelineSubEdit_).
        listen(
            this.timelineInner_,
            mirosubs.timeline.TimeRowUL.DOUBLECLICK,
            this.timeRowDoubleClick_).
        listen(
            this.subtitleSet_,
            mirosubs.timeline.SubtitleSet.CLEAR_TIMES,
            this.reset_);
    this.initTime_();
};
mirosubs.timeline.Timeline.prototype.timeRowDoubleClick_ = function(e) {
    this.videoPlayer_.setPlayheadTime(e.time);
    this.videoPlayer_.play();
};
mirosubs.timeline.Timeline.prototype.timelineSubEdit_ = function(e) {
    var et = mirosubs.timeline.TimelineSub.EventType;
    if (e.type == et.START_EDITING)
        this.videoPlayer_.pause();
};
mirosubs.timeline.Timeline.prototype.videoTimeUpdate_ = function(e) {
    this.setTime_(this.videoPlayer_.getPlayheadTime());
};
mirosubs.timeline.Timeline.prototype.initTime_ = function() {
    this.ensureWidth_();
    if (this.width_)
        this.videoTimeUpdate_();
    else
        goog.Timer.callOnce(goog.bind(this.initTime_, this));
};
mirosubs.timeline.Timeline.prototype.ensureWidth_ = function() {
    if (!this.width_) {
        var size = goog.style.getSize(this.getElement());
        this.width_ = size.width;
    }
};
mirosubs.timeline.Timeline.prototype.setTime_ = function(time) {
    this.ensureWidth_();
    this.timelineInner_.setTime(
        time, this.width_ / 2,
        this.videoPlayer_.getDuration());
};
mirosubs.timeline.Timeline.prototype.getTime_ = function() {
    this.ensureWidth_();
    return this.timelineInner_.getTime();
};
mirosubs.timeline.Timeline.prototype.beforeDrag = function(e) {
    // Returns false if a timeline subtitle's start or end time is being
    // changed, to keep the timeline from jumping around.
    return !mirosubs.timeline.TimelineSub.isCurrentlyEditing();
};
mirosubs.timeline.Timeline.prototype.startDrag = function(e) {
    this.wasPlaying_ = this.videoPlayer_.isPlaying();
    this.videoPlayer_.pause();
    this.oldLeft_ = this.timelineInner_.getLeft();
};
mirosubs.timeline.Timeline.prototype.onDrag = function(e) {
    this.ensureWidth_();
    this.timelineInner_.setLeft(e.left + this.oldLeft_, this.width_ / 2,
                                this.videoPlayer_.getDuration());
    this.videoPlayer_.setPlayheadTime(this.timelineInner_.getTime());
};
mirosubs.timeline.Timeline.prototype.endDrag = function(e) {
    this.oldLeft_ = null;
    if (this.wasPlaying_) {
        this.videoPlayer_.play();
    }
};
<commit_msg>possible fix for bug 13896: decouple timeline dragging from playhead position and only set position when the user stops dragging<commit_after>// Universal Subtitles, universalsubtitles.org
//
// Copyright (C) 2010 Participatory Culture Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see
// http://www.gnu.org/licenses/agpl-3.0.html.

goog.provide('mirosubs.timeline.Timeline');
goog.require('goog.fx.Dragger');
goog.require('goog.style.cursor');

/**
 *
 * @param {number} spacing The space, in seconds, between two
 *     major ticks.
 * @param {mirosubs.timeline.SubtitleSet} subtitleSet
 */
mirosubs.timeline.Timeline = function(spacing, subtitleSet, videoPlayer) {
    goog.ui.Component.call(this);
    this.spacing_ = spacing;
    this.subtitleSet_ = subtitleSet;
    this.videoPlayer_ = videoPlayer;
};
goog.inherits(mirosubs.timeline.Timeline, goog.ui.Component);
mirosubs.timeline.Timeline.prototype.createDom = function() {
    mirosubs.timeline.Timeline.superClass_.createDom.call(this);
    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());
    var el = this.getElement();
    el.className = 'mirosubs-timeline';
    el.appendChild($d('div', 'top', ' '));
    this.timelineInner_ = new mirosubs.timeline.TimelineInner(
        this, this.spacing_, this.subtitleSet_);
    this.addChild(this.timelineInner_, true);
    el.appendChild($d('div', 'marker'));
};
/**
 * Useful for when times are cleared.
 */
mirosubs.timeline.Timeline.prototype.reset_ = function() {
    this.removeChild(this.timelineInner_, true);
    this.timelineInner_.dispose();
    this.timelineInner_ = new mirosubs.timeline.TimelineInner(
        this, this.spacing_, this.subtitleSet_);
    this.addChild(this.timelineInner_, true);
};
mirosubs.timeline.Timeline.prototype.enterDocument = function() {
    mirosubs.timeline.Timeline.superClass_.enterDocument.call(this);
    this.getHandler().
        listen(
            this.videoPlayer_,
            mirosubs.video.AbstractVideoPlayer.EventType.TIMEUPDATE,
            this.videoTimeUpdate_).
        listen(
            this.timelineInner_,
            goog.object.getValues(
                mirosubs.timeline.TimelineSub.EventType),
            this.timelineSubEdit_).
        listen(
            this.timelineInner_,
            mirosubs.timeline.TimeRowUL.DOUBLECLICK,
            this.timeRowDoubleClick_).
        listen(
            this.subtitleSet_,
            mirosubs.timeline.SubtitleSet.CLEAR_TIMES,
            this.reset_);
    this.initTime_();
};
mirosubs.timeline.Timeline.prototype.timeRowDoubleClick_ = function(e) {
    this.videoPlayer_.setPlayheadTime(e.time);
    this.videoPlayer_.play();
};
mirosubs.timeline.Timeline.prototype.timelineSubEdit_ = function(e) {
    var et = mirosubs.timeline.TimelineSub.EventType;
    if (e.type == et.START_EDITING)
        this.videoPlayer_.pause();
};
mirosubs.timeline.Timeline.prototype.videoTimeUpdate_ = function(e) {
    this.setTime_(this.videoPlayer_.getPlayheadTime());
};
mirosubs.timeline.Timeline.prototype.initTime_ = function() {
    this.ensureWidth_();
    if (this.width_)
        this.videoTimeUpdate_();
    else
        goog.Timer.callOnce(goog.bind(this.initTime_, this));
};
mirosubs.timeline.Timeline.prototype.ensureWidth_ = function() {
    if (!this.width_) {
        var size = goog.style.getSize(this.getElement());
        this.width_ = size.width;
    }
};
mirosubs.timeline.Timeline.prototype.setTime_ = function(time) {
    this.ensureWidth_();
    this.timelineInner_.setTime(
        time, this.width_ / 2,
        this.videoPlayer_.getDuration());
};
mirosubs.timeline.Timeline.prototype.getTime_ = function() {
    this.ensureWidth_();
    return this.timelineInner_.getTime();
};
mirosubs.timeline.Timeline.prototype.beforeDrag = function(e) {
    // Returns false if a timeline subtitle's start or end time is being
    // changed, to keep the timeline from jumping around.
    return !mirosubs.timeline.TimelineSub.isCurrentlyEditing();
};
mirosubs.timeline.Timeline.prototype.startDrag = function(e) {
    this.wasPlaying_ = this.videoPlayer_.isPlaying();
    this.videoPlayer_.pause();
    this.oldLeft_ = this.timelineInner_.getLeft();
};
mirosubs.timeline.Timeline.prototype.onDrag = function(e) {
    this.ensureWidth_();
    this.timelineInner_.setLeft(e.left + this.oldLeft_, this.width_ / 2,
                                this.videoPlayer_.getDuration());
};
mirosubs.timeline.Timeline.prototype.endDrag = function(e) {
    this.oldLeft_ = null;
    this.videoPlayer_.setPlayheadTime(this.timelineInner_.getTime());
    if (this.wasPlaying_) {
        this.videoPlayer_.play();
    }
};
<|endoftext|>


<commit_before>  module.exports = function() {
    var bannerId = $('.attorneyBanner').attr('id'),
      topOffset = 0;

    if (bannerId) {
      topOffset = $('#' + bannerId).parent().height();
    }

    $('.error-summary a').on('click', function(e) {
      e.preventDefault();
      var focusId = $(this).attr('data-focuses'),
        inputToFocus = $('#' + focusId),
        inputTagName = inputToFocus.prop("tagName").toLowerCase(),
        nodeToScrollTo = inputToFocus;

      if (["input", "select", "button"].indexOf(inputTagName) !== -1) {
        nodeToScrollTo = inputToFocus.parent();
      }

      $('html, body').animate({
        scrollTop: nodeToScrollTo.offset().top - topOffset
      }, 500);

      nodeToScrollTo.find(':input').first().focus();
    });
  };

<commit_msg>CATO-3714: Fixing the problem with 'validatorFocus' not checking if 'data-focuses' attribute exists.<commit_after>  module.exports = function() {
    var bannerId = $('.attorneyBanner').attr('id'),
      topOffset = 0;

    if (bannerId) {
      topOffset = $('#' + bannerId).parent().height();
    }

    $('.error-summary a').on('click', function(e) {
      var focusId = $(this).attr('data-focuses');
      if (!focusId)
        return;

      e.preventDefault();
      var inputToFocus = $('#' + focusId),
        inputTagName = inputToFocus.prop("tagName").toLowerCase(),
        nodeToScrollTo = inputToFocus;

      if (["input", "select", "button"].indexOf(inputTagName) !== -1) {
        nodeToScrollTo = inputToFocus.parent();
      }

      $('html, body').animate({
        scrollTop: nodeToScrollTo.offset().top - topOffset
      }, 500);

      nodeToScrollTo.find(':input').first().focus();
    });
  };

<|endoftext|>


<commit_before><commit_msg>Update js.js<commit_after><|endoftext|>


<commit_before><commit_msg>Implemented string.format for d and f<commit_after><|endoftext|>


<commit_before>angular.module('avAdmin').controller('AdminController',
  function(AdminPlugins, ConfigService, $scope, $i18next, $state, $stateParams, ElectionsApi, $compile) {
    var id = $stateParams.id;
    $scope.state = $state.current.name;
    $scope.current = null;
    $scope.noplugin = true;
    $scope.helpurl = ConfigService.helpUrl;
    $scope.showSuccessAction = ConfigService.showSuccessAction;

    // state = admin.XXX
    $scope.shortst = $state.current.name.split(".")[1];

    // plugin stuff
    $scope.plugins = AdminPlugins.plugins;
    AdminPlugins.plugins.list.forEach(function(p) {
        if (p.directive) {
            var tpl = $compile( '' )($scope);
            if ($scope.shortst === p.name) {
                $scope.noplugin = false;
            }
        }
    });

    // removing autoreload stats
    ElectionsApi.autoreloadStats(null);

    function newElection() {
        var el = ElectionsApi.templateEl();
        $scope.current = el;
        ElectionsApi.setCurrent(el);
        ElectionsApi.newElection = true;

        return el;
    }

    if (id) {
        ElectionsApi.getElection(id)
            .then(function(el) {
                $scope.current = el;
                ElectionsApi.setCurrent(el);
                if ('real' in el) {
                    $scope.isTest = !el.real;
                } else {
                    $scope.isTest = true;
                }
            });
    }

    if ($scope.state === 'admin.new') {
        // New election
        newElection();
        $state.go("admin.basic");
        $scope.isTest = !$scope.current['real'];
    }

    var states =[ 'admin.dashboard', 'admin.basic', 'admin.questions', 'admin.censusConfig', 'admin.census', 'admin.auth', 'admin.tally', 'admin.successAction', 'admin.create'];
    if (states.indexOf($scope.state) >= 0) {
        $scope.sidebarlinks = [
            {name: 'basic', icon: 'university'},
            {name: 'questions', icon: 'question-circle'},
            {name: 'auth', icon: 'unlock'},
            {name: 'censusConfig', icon: 'newspaper-o'},
            {name: 'census', icon: 'users'},
            {name: 'successAction', icon: 'star-o'},
            //{name: 'tally', icon: 'pie-chart'},
        ];

        if (!id) {
            $scope.sidebarlinks.push({name: 'create', icon: 'rocket'});
            var current = ElectionsApi.currentElection;
            if (!current.title) {
                current = newElection();
            }
            $scope.current = current;
            $scope.isTest = !$scope.current['real'];
        }
    } else {
        $scope.sidebarlinks = [];
    }
  }
);
<commit_msg>don't display Success Action tab<commit_after>angular.module('avAdmin').controller('AdminController',
  function(AdminPlugins, ConfigService, $scope, $i18next, $state, $stateParams, ElectionsApi, $compile) {
    var id = $stateParams.id;
    $scope.state = $state.current.name;
    $scope.current = null;
    $scope.noplugin = true;
    $scope.helpurl = ConfigService.helpUrl;
    $scope.showSuccessAction = ConfigService.showSuccessAction;

    // state = admin.XXX
    $scope.shortst = $state.current.name.split(".")[1];

    // plugin stuff
    $scope.plugins = AdminPlugins.plugins;
    AdminPlugins.plugins.list.forEach(function(p) {
        if (p.directive) {
            var tpl = $compile( '' )($scope);
            if ($scope.shortst === p.name) {
                $scope.noplugin = false;
            }
        }
    });

    // removing autoreload stats
    ElectionsApi.autoreloadStats(null);

    function newElection() {
        var el = ElectionsApi.templateEl();
        $scope.current = el;
        ElectionsApi.setCurrent(el);
        ElectionsApi.newElection = true;

        return el;
    }

    if (id) {
        ElectionsApi.getElection(id)
            .then(function(el) {
                $scope.current = el;
                ElectionsApi.setCurrent(el);
                if ('real' in el) {
                    $scope.isTest = !el.real;
                } else {
                    $scope.isTest = true;
                }
            });
    }

    if ($scope.state === 'admin.new') {
        // New election
        newElection();
        $state.go("admin.basic");
        $scope.isTest = !$scope.current['real'];
    }

    var states =[ 'admin.dashboard', 'admin.basic', 'admin.questions', 'admin.censusConfig', 'admin.census', 'admin.auth', 'admin.tally', 'admin.successAction', 'admin.create'];
    if (states.indexOf($scope.state) >= 0) {
        $scope.sidebarlinks = [
            {name: 'basic', icon: 'university'},
            {name: 'questions', icon: 'question-circle'},
            {name: 'auth', icon: 'unlock'},
            {name: 'censusConfig', icon: 'newspaper-o'},
            {name: 'census', icon: 'users'},
            //{name: 'successAction', icon: 'star-o'},
            //{name: 'tally', icon: 'pie-chart'},
        ];
        // if showSuccessAction is true,
        // show the SuccessAction tab in the admin gui
        if (true === ConfigService.showSuccessAction) {
           angular.extend($scope.sidebarlinks,
                          {name: 'successAction', icon: 'star-o'});
        }

        if (!id) {
            $scope.sidebarlinks.push({name: 'create', icon: 'rocket'});
            var current = ElectionsApi.currentElection;
            if (!current.title) {
                current = newElection();
            }
            $scope.current = current;
            $scope.isTest = !$scope.current['real'];
        }
    } else {
        $scope.sidebarlinks = [];
    }
  }
);
<|endoftext|>


<commit_before>/**
 * なでしこの構文解析のためのユーティリティクラス
 */

const NakoSyntaxError = require('./nako_syntax_error')

class NakoParserBase {
  constructor () {
    this.debug = false
    this.debugStack = false
    this.stackList = [] // 関数定義の際にスタックが混乱しないように整理する
    this.init()
  }

  init () {
    this.funclist = {} // 関数の一覧
    this.reset()
  }

  reset () {
    this.tokens = [] // 字句解析済みのトークンの一覧を保存
    this.index = 0 // tokens[] のどこまで読んだかを管理する
    this.stack = [] // 計算用のスタック ... 直接は操作せず、pushStack() popStack() を介して使う
    this.y = [] // accept()で解析済みのトークンを配列で得るときに使う
  }

  setFuncList (funclist) {
    this.funclist = funclist
  }

  /**
   * 特定の助詞を持つ要素をスタックから一つ下ろす、指定がなければ末尾を下ろす
   * @param josiList 下ろしたい助詞の配列
   */
  popStack (josiList) {
    if (!josiList) {return this.stack.pop()}

    // josiList にマッチする助詞を探す
    for (let i = 0; i < this.stack.length; i++) {
      const t = this.stack[i]
      if (josiList.length === 0 || josiList.indexOf(t.josi) >= 0) {
        this.stack.splice(i, 1) // remove stack
        if (this.debugStack) {console.log('POP :', t)}
        return t
      }
    }
    // 該当する助詞が見つからなかった場合
    return null
  }

  /**
   * saveStack と loadStack は対で使う。
   * 関数定義などでスタックが混乱しないように配慮するためのもの
   */
  saveStack () {
    this.stackList.push(this.stack)
    this.stack = []
  }

  loadStack () {
    this.stack = this.stackList.pop()
  }

  /**
   * 計算用に要素をスタックに積む
   */
  pushStack (item) {
    if (this.debugStack) {console.log('PUSH:', item)}
    this.stack.push(item)
  }

  /**
   * トークンの末尾に達したか
   */
  isEOF () {
    return (this.index >= this.tokens.length)
  }

  /**
   * カーソル位置にある単語の型を確かめる
   */
  check (ttype) {
    return (this.tokens[this.index].type === ttype)
  }

  /**
   * カーソル位置以降にある単語の型を確かめる 2単語以上に対応
   * @param a [単語1の型, 単語2の型, ... ]
   */
  check2 (a) {
    for (let i = 0; i < a.length; i++) {
      const idx = i + this.index
      if (this.tokens.length <= idx) {return false}
      if (a[i] === '*') {continue} // ワイルドカード(どんなタイプも許容)
      const t = this.tokens[idx]
      if (a[i] instanceof Array) {
        if (a[i].indexOf(t.type) < 0) {return false}
        continue
      }
      if (t.type !== a[i]) {return false}
    }
    return true
  }

  /**
   * カーソル位置の型を確認するが、複数の種類を確かめられる
   */
  checkTypes (a) {
    const type = this.tokens[this.index].type
    return (a.indexOf(type) >= 0)
  }

  /**
   * check2の高度なやつ、型名の他にコールバック関数を指定できる
   * 型にマッチしなければ null を返し、カーソルを巻き戻す
   */
  accept (types) {
    const y = []
    const tmpIndex = this.index
    const rollback = () => {
      this.index = tmpIndex
      return false
    }
    for (let i = 0; i < types.length; i++) {
      if (this.isEOF()) {return rollback()}
      const type = types[i]
      if (typeof type === 'string') {
        const token = this.get()
        if (token.type !== type) {return rollback()}
        y[i] = token
        continue
      }
      if (typeof type === 'function') {
        const f = type.bind(this)
        const r = f(null)
        if (r === null) {return rollback()}
        y[i] = r
        continue
      }
      if (type instanceof Array) {
        if (!this.checkTypes(type)) {return rollback()}
        y[i] = this.get()
        continue
      }
      throw new Error('System Error : accept broken : ' + typeof type)
    }
    this.y = y
    return true
  }

  /**
   * カーソル語句を取得して、カーソルを後ろに移動する
   */
  get () {
    if (this.isEOF()) {return null}
    return this.tokens[this.index++]
  }

  unget () {
    if (this.index > 0) {this.index--}
  }

  peek (i = 0) {
    if (this.isEOF()) {return null}
    return this.tokens[this.index + i]
  }

  nodeToStr (node) {
    if (!node) {return `(NULL)`}
    let name = node.name
    if (node.type === 'op')
      {name = '演算子[' + node.operator + ']'}

    if (!name) {name = node.value}
    if (typeof name !== 'string') {name = node.type}
    if (this.debug)
      {name += '→' + JSON.stringify(node, null, 2)}
     else {
      if (name === 'number') {name = node.value + node.josi}
      if (node.type === 'string') {name = '「' + node.value + '」' + node.josi}
    }
    return `『${name}』`
  }
}

module.exports = {
  NakoParserBase,
  NakoSyntaxError
}
<commit_msg>エラーにファイル名を追加<commit_after>/**
 * なでしこの構文解析のためのユーティリティクラス
 */

const NakoSyntaxError = require('./nako_syntax_error')

class NakoParserBase {
  constructor () {
    this.debug = false
    this.debugStack = false
    this.stackList = [] // 関数定義の際にスタックが混乱しないように整理する
    this.filename = ''
    this.init()
  }

  init () {
    this.funclist = {} // 関数の一覧
    this.reset()
  }

  reset () {
    this.tokens = [] // 字句解析済みのトークンの一覧を保存
    this.index = 0 // tokens[] のどこまで読んだかを管理する
    this.stack = [] // 計算用のスタック ... 直接は操作せず、pushStack() popStack() を介して使う
    this.y = [] // accept()で解析済みのトークンを配列で得るときに使う
  }

  setFilename (fname) {
    this.filename = fname
  }

  setFuncList (funclist) {
    this.funclist = funclist
  }

  /**
   * 特定の助詞を持つ要素をスタックから一つ下ろす、指定がなければ末尾を下ろす
   * @param josiList 下ろしたい助詞の配列
   */
  popStack (josiList) {
    if (!josiList) {return this.stack.pop()}

    // josiList にマッチする助詞を探す
    for (let i = 0; i < this.stack.length; i++) {
      const t = this.stack[i]
      if (josiList.length === 0 || josiList.indexOf(t.josi) >= 0) {
        this.stack.splice(i, 1) // remove stack
        if (this.debugStack) {console.log('POP :', t)}
        return t
      }
    }
    // 該当する助詞が見つからなかった場合
    return null
  }

  /**
   * saveStack と loadStack は対で使う。
   * 関数定義などでスタックが混乱しないように配慮するためのもの
   */
  saveStack () {
    this.stackList.push(this.stack)
    this.stack = []
  }

  loadStack () {
    this.stack = this.stackList.pop()
  }

  /**
   * 計算用に要素をスタックに積む
   */
  pushStack (item) {
    if (this.debugStack) {console.log('PUSH:', item)}
    this.stack.push(item)
  }

  /**
   * トークンの末尾に達したか
   */
  isEOF () {
    return (this.index >= this.tokens.length)
  }

  /**
   * カーソル位置にある単語の型を確かめる
   */
  check (ttype) {
    return (this.tokens[this.index].type === ttype)
  }

  /**
   * カーソル位置以降にある単語の型を確かめる 2単語以上に対応
   * @param a [単語1の型, 単語2の型, ... ]
   */
  check2 (a) {
    for (let i = 0; i < a.length; i++) {
      const idx = i + this.index
      if (this.tokens.length <= idx) {return false}
      if (a[i] === '*') {continue} // ワイルドカード(どんなタイプも許容)
      const t = this.tokens[idx]
      if (a[i] instanceof Array) {
        if (a[i].indexOf(t.type) < 0) {return false}
        continue
      }
      if (t.type !== a[i]) {return false}
    }
    return true
  }

  /**
   * カーソル位置の型を確認するが、複数の種類を確かめられる
   */
  checkTypes (a) {
    const type = this.tokens[this.index].type
    return (a.indexOf(type) >= 0)
  }

  /**
   * check2の高度なやつ、型名の他にコールバック関数を指定できる
   * 型にマッチしなければ null を返し、カーソルを巻き戻す
   */
  accept (types) {
    const y = []
    const tmpIndex = this.index
    const rollback = () => {
      this.index = tmpIndex
      return false
    }
    for (let i = 0; i < types.length; i++) {
      if (this.isEOF()) {return rollback()}
      const type = types[i]
      if (typeof type === 'string') {
        const token = this.get()
        if (token.type !== type) {return rollback()}
        y[i] = token
        continue
      }
      if (typeof type === 'function') {
        const f = type.bind(this)
        const r = f(null)
        if (r === null) {return rollback()}
        y[i] = r
        continue
      }
      if (type instanceof Array) {
        if (!this.checkTypes(type)) {return rollback()}
        y[i] = this.get()
        continue
      }
      throw new Error('System Error : accept broken : ' + typeof type)
    }
    this.y = y
    return true
  }

  /**
   * カーソル語句を取得して、カーソルを後ろに移動する
   */
  get () {
    if (this.isEOF()) {return null}
    return this.tokens[this.index++]
  }

  unget () {
    if (this.index > 0) {this.index--}
  }

  peek (i = 0) {
    if (this.isEOF()) {return null}
    return this.tokens[this.index + i]
  }

  nodeToStr (node) {
    if (!node) {return `(NULL)`}
    let name = node.name
    if (node.type === 'op')
      {name = '演算子[' + node.operator + ']'}

    if (!name) {name = node.value}
    if (typeof name !== 'string') {name = node.type}
    if (this.debug)
      {name += '→' + JSON.stringify(node, null, 2)}
     else {
      if (name === 'number') {name = node.value + node.josi}
      if (node.type === 'string') {name = '「' + node.value + '」' + node.josi}
    }
    return `『${name}』`
  }
}

module.exports = {
  NakoParserBase,
  NakoSyntaxError
}
<|endoftext|>


<commit_before>
import Debug from 'debug/browser'
let debug = Debug('scintillator:loader')

import $ from 'jquery'
import url from 'url'
import promiseForPixi from './import-pixi'

import Resources from './resources'
import Compiler from './compiler'

/**
 * A Scintillator is Bemuse's graphics display engine based on PIXI.js.
 */
export class Scintillator {
  constructor({ PIXI, $xml, resources }) {
    this._PIXI = PIXI
    this._$xml = $xml
    this._resources = resources
  }
  compile(options={}) {
    new Compiler({ $xml }).compile()
    void options
  }
}

export function load(xmlPath) {
  debug('load XML from %s', xmlPath)
  let promiseForXml = loadXml(xmlPath)
  return Promise.all([promiseForPixi, promiseForXml])
  .then(([PIXI, $xml]) => {
    debug('PIXI and $xml loaded')
    let resources = new Resources()
    for (let image of Array.from($xml.children('image'))) {
      let src = $(image).attr('src')
      let imageUrl = url.resolve(xmlPath, src)
      resources.add(src, imageUrl)
    }
    return loadResources(resources).with(PIXI)
    .then(() => new Scintillator({ PIXI, $xml, resources }))
  })
}

function loadXml(url) {
  return Promise.resolve($.ajax({ url: url, dataType: 'xml' }))
    .then(xml => $(xml.documentElement))
}

function loadResources(resources) {
  return {
    with: function(PIXI) {
      debug('loading resources')
      return new Promise(function(resolve) {
        let loader = new PIXI.AssetLoader(resources.urls)
        loader.on('onComplete', function() {
          debug('resources finished loading')
          resolve()
        })
        loader.load()
      })
    }
  }
}

export default Scintillator
<commit_msg>fix(scintillator/index): add missing variable $xml<commit_after>
import Debug from 'debug/browser'
let debug = Debug('scintillator:loader')

import $ from 'jquery'
import url from 'url'
import promiseForPixi from './import-pixi'

import Resources from './resources'
import Compiler from './compiler'

/**
 * A Scintillator is Bemuse's graphics display engine based on PIXI.js.
 */
export class Scintillator {
  constructor({ PIXI, $xml, resources }) {
    this._PIXI = PIXI
    this._$xml = $xml
    this._resources = resources
  }
  compile(options={}) {
    let $xml = this._$xml
    new Compiler({ $xml }).compile()
    void options
  }
}

export function load(xmlPath) {
  debug('load XML from %s', xmlPath)
  let promiseForXml = loadXml(xmlPath)
  return Promise.all([promiseForPixi, promiseForXml])
  .then(([PIXI, $xml]) => {
    debug('PIXI and $xml loaded')
    let resources = new Resources()
    for (let image of Array.from($xml.children('image'))) {
      let src = $(image).attr('src')
      let imageUrl = url.resolve(xmlPath, src)
      resources.add(src, imageUrl)
    }
    return loadResources(resources).with(PIXI)
    .then(() => new Scintillator({ PIXI, $xml, resources }))
  })
}

function loadXml(url) {
  return Promise.resolve($.ajax({ url: url, dataType: 'xml' }))
    .then(xml => $(xml.documentElement))
}

function loadResources(resources) {
  return {
    with: function(PIXI) {
      debug('loading resources')
      return new Promise(function(resolve) {
        let loader = new PIXI.AssetLoader(resources.urls)
        loader.on('onComplete', function() {
          debug('resources finished loading')
          resolve()
        })
        loader.load()
      })
    }
  }
}

export default Scintillator
<|endoftext|>


<commit_before>const path = require('path')
const express = require('express')
const mongoose = require('mongoose')
const _ = require('lodash')
const prettyHrtime = require('pretty-hrtime')

const Manga = require('./models/manga')
const mangareader = require('./providers/mangareader')

const api = require('./api')

process.env.PORT = process.env.PORT || 8080
const app = express()

app.get('/api/mangas', api.mangaList)
app.get('/api/mangas/:id/chapters/:index', api.mangaChapter)
app.get('/api/mangas/:id', api.mangaDetail)

// XXX don't use this in production
if (process.env.NODE_ENV !== 'production' &&
    process.env.NODE_ENV !== 'debug' &&
    process.env.NODE_ENV !== 'testing'
   ) {
  const webpackMiddleware = require('../build/dev-server')
  webpackMiddleware(app, express.static('./static'))
} else {
  app.use('/', express.static('./dist'))
}

process.env.MONGOLAB_URI = process.env.MONGOLAB_URI || 'mongodb://localhost/mangare'
console.log(`Connecting on mongo to ${process.env.MONGOLAB_URI}`)
mongoose.connect(process.env.MONGOLAB_URI)
const db = mongoose.connection

db.on('error', console.error.bind(console, 'connection error:'))

db.once('open', () => {
  if (true) return
  console.log('Mongoose started')
  const start = process.hrtime()
  mangareader.getList()
    .then((mangaList) => Manga.populateMangaList(mangaList))
    .then((data) => {
      const end = process.hrtime(start)
      console.log(`Took ${prettyHrtime(end)} to get and populate(${data.time}) manga list(${data.data.insertedCount})`)
    })
    .catch((err) => {
      console.error(err)
    })
})

module.exports = app.listen(process.env.PORT, () => {
  console.log(`Listening on ${process.env.PORT}`)
})

<commit_msg>[skip ci] The env variable changed...<commit_after>const path = require('path')
const express = require('express')
const mongoose = require('mongoose')
const _ = require('lodash')
const prettyHrtime = require('pretty-hrtime')

const Manga = require('./models/manga')
const mangareader = require('./providers/mangareader')

const api = require('./api')

process.env.PORT = process.env.PORT || 8080
const app = express()

app.get('/api/mangas', api.mangaList)
app.get('/api/mangas/:id/chapters/:index', api.mangaChapter)
app.get('/api/mangas/:id', api.mangaDetail)

// XXX don't use this in production
if (process.env.NODE_ENV !== 'production' &&
    process.env.NODE_ENV !== 'debug' &&
    process.env.NODE_ENV !== 'testing'
   ) {
  const webpackMiddleware = require('../build/dev-server')
  webpackMiddleware(app, express.static('./static'))
} else {
  app.use('/', express.static('./dist'))
}

process.env.MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost/mangare'
console.log(`Connecting on mongo to ${process.env.MONGOLAB_URI}`)
mongoose.connect(process.env.MONGODB_URI)
const db = mongoose.connection

db.on('error', console.error.bind(console, 'connection error:'))

db.once('open', () => {
  if (true) return
  console.log('Mongoose started')
  const start = process.hrtime()
  mangareader.getList()
    .then((mangaList) => Manga.populateMangaList(mangaList))
    .then((data) => {
      const end = process.hrtime(start)
      console.log(`Took ${prettyHrtime(end)} to get and populate(${data.time}) manga list(${data.data.insertedCount})`)
    })
    .catch((err) => {
      console.error(err)
    })
})

module.exports = app.listen(process.env.PORT, () => {
  console.log(`Listening on ${process.env.PORT}`)
})

<|endoftext|>


<commit_before><commit_msg>fix bug 1.修复加载失败后，不会出发加载中阻塞的回调队列<commit_after><|endoftext|>


<commit_before>require('../ext/arrays.js')
require('../ext/functions.js')
require('../ext/globals.js')

var browserify = require('browserify-middleware')
var express = require('express')
var app = express()
var port = process.env.PORT || 4000
var host = process.env.HOST || 'http://localhost:' + port

//provide a browserified file at a path
var shared = ['mithril', './ext/functions.js']
app.get('/js/vendor.js', browserify(shared))
app.get('/js/app-bundle.js', browserify('./client/app-bundle/index.js', { external: shared }))

// Non-js static files
app.use(express.static('client/public'))

var session = require('cookie-session')
app.use(session({
  name: 'learn:session',
  secret: process.env.SESSION_SECRET || 'production',
  secure: (!! process.env.SESSION_SECRET),
  signed: true
}))

//enable express router resource which facilitate shared endpoint routing
var resource = require('express-resource');

// bodyparser for endpoint conversion of JSON objects
var bodyParser = require('body-parser')
var jsonParser = bodyParser.json()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }));

//API endpoint integration
require('./makerpass').mount(app, host);
require('./API/jobsAPI').mount(app);
require('./API/usersAPI').mount(app);
require('./API/companiesAPI').mount(app);
require('./API/groupsAPI').mount(app);
require('./API/applicationsAPI').mount(app);
require('./API/questionsAPI').mount(app);
require('./API/titlesAPI').mount(app);
require('./API/membershipsAPI').mount(app);
require('./API/interviewsAPI').mount(app);
require('./API/contactsAPI').mount(app);
require('./API/schoolsAPI').mount(app);

app.listen(80)
console.log("Listening on port", 80 )
<commit_msg>altered heroku options<commit_after>require('../ext/arrays.js')
require('../ext/functions.js')
require('../ext/globals.js')

var browserify = require('browserify-middleware')
var express = require('express')
var app = express()
var port = process.env.PORT || 4000
var host = process.env.HOST || 'http://localhost:' + port

//provide a browserified file at a path
var shared = ['mithril', './ext/functions.js']
app.get('/js/vendor.js', browserify(shared))
app.get('/js/app-bundle.js', browserify('./client/app-bundle/index.js', { external: shared }))

// Non-js static files
app.use(express.static('client/public'))

var session = require('cookie-session')
app.use(session({
  name: 'learn:session',
  secret: process.env.SESSION_SECRET || 'production',
  secure: (!! process.env.SESSION_SECRET),
  signed: true
}))

//enable express router resource which facilitate shared endpoint routing
var resource = require('express-resource');

// bodyparser for endpoint conversion of JSON objects
var bodyParser = require('body-parser')
var jsonParser = bodyParser.json()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }));

//API endpoint integration
require('./makerpass').mount(app, host);
require('./API/jobsAPI').mount(app);
require('./API/usersAPI').mount(app);
require('./API/companiesAPI').mount(app);
require('./API/groupsAPI').mount(app);
require('./API/applicationsAPI').mount(app);
require('./API/questionsAPI').mount(app);
require('./API/titlesAPI').mount(app);
require('./API/membershipsAPI').mount(app);
require('./API/interviewsAPI').mount(app);
require('./API/contactsAPI').mount(app);
require('./API/schoolsAPI').mount(app);

app.listen(port)
console.log("Listening on port", port)
<|endoftext|>


<commit_before><commit_msg>Change var style<commit_after><|endoftext|>


<commit_before>// dependencies
const express = require('express');
const parser = require('body-parser');
const path = require('path');
const cors = require('cors');
// file imports
// const router = require('./router/router.js');
const db = require('../db/config.js');
// express instantiation
const app = express();
const port = process.env.PORT || 8080;
// middleware
app.use(parser.json());
app.use(parser.urlencoded());
app.use(cors());
// app.use('/api', router);
app.use(express.static(__dirname + '../client/static/index.html'));
// sync db, start a UNIX socket and listen for connections
db.User.sync({force: true}).then(() => app.listen(port, () => console.log("Listening on port " + port)));<commit_msg>resolved path<commit_after>// dependencies
const express = require('express');
const parser = require('body-parser');
const path = require('path');
const cors = require('cors');
// file imports
// const router = require('./router/router.js');
const db = require('../db/config.js');
// express instantiation
const app = express();
const port = process.env.PORT || 8080;
// middleware
app.use(parser.json());
app.use(parser.urlencoded());
app.use(cors());
// app.use('/api', router);
app.use(express.static(path.resolve(__dirname, '../client/static/')));
// sync db, start a UNIX socket and listen for connections
db.User.sync({force: true}).then(() => app.listen(port, () => console.log("Listening on port " + port)));<|endoftext|>


<commit_before>import { GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLString } from 'graphql';

import models, { Op } from '../../../models';
import { OrderCollection } from '../collection/OrderCollection';
import { OrderStatus, TierAmountType, TierInterval, TierType } from '../enum';
import { idEncode } from '../identifiers';

import { Amount } from './Amount';

export const Tier = new GraphQLObjectType({
  name: 'Tier',
  description: 'Tier model',
  fields: () => {
    return {
      // _internal_id: {
      //   type: GraphQLInt,
      //   resolve(member) {
      //     return member.id;
      //   },
      // },
      id: {
        type: GraphQLString,
        resolve(tier) {
          return idEncode(tier.id, 'tier');
        },
      },
      slug: {
        type: GraphQLString,
      },
      name: {
        type: GraphQLString,
        resolve(tier) {
          return tier.slug;
        },
      },
      description: {
        type: GraphQLString,
      },
      orders: {
        description: 'Get all orders',
        type: OrderCollection,
        args: {
          limit: { type: GraphQLInt, defaultValue: 100 },
          offset: { type: GraphQLInt, defaultValue: 0 },
          status: { type: new GraphQLList(OrderStatus) },
        },
        async resolve(tier, args) {
          const where = { TierId: tier.id };

          if (args.status && args.status.length > 0) {
            where.status = {
              [Op.in]: args.status,
            };
          }

          const result = await models.Order.findAndCountAll({ where, limit: args.limit, offset: args.offset });

          return { nodes: result.rows, totalCount: result.count, limit: args.limit, offset: args.offset };
        },
      },
      amount: {
        type: Amount,
        resolve(tier) {
          return { value: tier.amount, currency: tier.currency };
        },
      },
      type: {
        type: new GraphQLNonNull(TierType),
      },
      interval: {
        type: TierInterval,
      },
      presets: {
        type: new GraphQLList(GraphQLInt),
      },
      amountType: {
        type: new GraphQLNonNull(TierAmountType),
      },
      minimumAmount: {
        type: Amount,
        resolve(tier) {
          return { value: tier.minimumAmount };
        },
      },
    };
  },
});
<commit_msg>feat(GQLV2/Tier): Add more fields<commit_after>import { GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLString } from 'graphql';
import GraphQLJSON from 'graphql-type-json';

import models, { Op } from '../../../models';
import { OrderCollection } from '../collection/OrderCollection';
import { OrderStatus, TierAmountType, TierInterval, TierType } from '../enum';
import { idEncode } from '../identifiers';

import { Amount } from './Amount';

export const Tier = new GraphQLObjectType({
  name: 'Tier',
  description: 'Tier model',
  fields: () => {
    return {
      // _internal_id: {
      //   type: GraphQLInt,
      //   resolve(member) {
      //     return member.id;
      //   },
      // },
      id: {
        type: GraphQLString,
        resolve(tier) {
          return idEncode(tier.id, 'tier');
        },
      },
      slug: {
        type: GraphQLString,
      },
      name: {
        type: GraphQLString,
        resolve(tier) {
          return tier.slug;
        },
      },
      description: {
        type: GraphQLString,
      },
      orders: {
        description: 'Get all orders',
        type: OrderCollection,
        args: {
          limit: { type: GraphQLInt, defaultValue: 100 },
          offset: { type: GraphQLInt, defaultValue: 0 },
          status: { type: new GraphQLList(OrderStatus) },
        },
        async resolve(tier, args) {
          const where = { TierId: tier.id };

          if (args.status && args.status.length > 0) {
            where.status = {
              [Op.in]: args.status,
            };
          }

          const result = await models.Order.findAndCountAll({ where, limit: args.limit, offset: args.offset });

          return { nodes: result.rows, totalCount: result.count, limit: args.limit, offset: args.offset };
        },
      },
      amount: {
        type: Amount,
        resolve(tier) {
          return { value: tier.amount, currency: tier.currency };
        },
      },
      type: {
        type: new GraphQLNonNull(TierType),
      },
      interval: {
        type: TierInterval,
      },
      presets: {
        type: new GraphQLList(GraphQLInt),
      },
      maxQuantity: {
        type: GraphQLInt,
      },
      customFields: {
        type: GraphQLJSON,
      },
      amountType: {
        type: new GraphQLNonNull(TierAmountType),
      },
      minimumAmount: {
        type: Amount,
        resolve(tier) {
          return { value: tier.minimumAmount };
        },
      },
    };
  },
});
<|endoftext|>


<commit_before>var navmenuApp = module.exports = App.subApp()

// require userApp, as default header use user-login box
require("../../msa-user/server")
// sheet
var sheetApp = require("../../msa-sheet/server")

// register navmenu sheets
sheetApp.registerSheet("navmenu", {
	creatableBy: {group: "admin"},
	boxType: "boxes",
	content: {
		owner: {group: "admin"},
		box: {
			style: { "margin":"0", "height":"100px", "border-bottom": "4px solid #4C9CF1", "box-shadow": "0 0 3px 2px #aaa" },
			boxes: {
				"1": {
					type: "text",
					style: { "position":"absolute", "top":"10px", "left":"30px" },
					html: "MySimpleApp"
				},
				"2": {
					type: "msa-user-login",
					style: { "position":"absolute", "bottom":"10px", "right":"10px", "min-height":null }
				}
			}
		}
	}
})

// read //////////////////////////////////////////////////////////////

var getNavmenuAsPartial = function(req, res, next) {
	sheetApp.getSheet("navmenu", "header", {user:req.user, ifNotExist:"create", insertInDb:true, forceInsertInDb:true}, function(err, sheet){
		if(err) return next(err)
		res.partial = sheetApp.renderSheetAsHtml(sheet)
		next()
	})
}

navmenuApp.get("/", getNavmenuAsPartial)
navmenuApp.getAsPartial = getNavmenuAsPartial
<commit_msg>Fix getAsPartial conflict<commit_after>var navmenuApp = module.exports = App.subApp()

// require userApp, as default header use user-login box
require("../../msa-user/server")
// sheet
var sheetApp = require("../../msa-sheet/server")

// register navmenu sheets
sheetApp.registerSheet("navmenu", {
	creatableBy: {group: "admin"},
	boxType: "boxes",
	content: {
		owner: {group: "admin"},
		box: {
			style: { "margin":"0", "height":"100px", "border-bottom": "4px solid #4C9CF1", "box-shadow": "0 0 3px 2px #aaa" },
			boxes: {
				"1": {
					type: "text",
					style: { "position":"absolute", "top":"10px", "left":"30px" },
					html: "MySimpleApp"
				},
				"2": {
					type: "msa-user-login",
					style: { "position":"absolute", "bottom":"10px", "right":"10px", "min-height":null }
				}
			}
		}
	}
})

// read //////////////////////////////////////////////////////////////

var getNavmenuAsPartial = function(req, res, next) {
	sheetApp.getSheet("navmenu", "header", {user:req.user, ifNotExist:"create", insertInDb:true, forceInsertInDb:true}, function(err, sheet){
		if(err) return next(err)
		res.partial = sheetApp.renderSheetAsHtml(sheet)
		next()
	})
}

navmenuApp.get("/", getNavmenuAsPartial)
navmenuApp.getPartial = getNavmenuAsPartial
<|endoftext|>


<commit_before>// Dependencies
var express = require("express"),
    compression = require("compression"),
    path = require("path"),
    multer = require("multer"),
    uuid = require("node-uuid"),
    mkdirp = require("mkdirp");

// Routes and middleware
var logger = require("../lib/logger/"),
    render = require("./render.js"),
    status = require("./status.js"),
    errorHandlers = require("./error.js");

// Settings
var serverSettings = require("../settings/");

var app = express();

app.use(compression());
app.use(logger.morgan());

// Options for where to store uploaded audio and max size
var fileOptions = {
  storage: multer.diskStorage({
    destination: function(req, file, cb) {

      var dir = path.join(serverSettings.workingDirectory, uuid.v1());

      mkdirp(dir, function(err) {
        return cb(err, dir);
      });
    },
    filename: function(req, file, cb) {
      cb(null, "audio");
    }
  })
};

if (serverSettings.maxUploadSize) {
  fileOptions.limits = {
    fileSize: +serverSettings.maxUploadSize
  };
}

if (typeof serverSettings.workingDirectory !== "string") {
  throw new TypeError("No workingDirectory set in settings/index.js");
}

// On submission, check upload, validate input, and start generating a video
app.post("/submit/", [multer(fileOptions).single("audio"), render.validate, render.route]);

// If not using S3, serve videos locally
if (!serverSettings.s3Bucket) {
  if (typeof serverSettings.storagePath !== "string") {
    throw new TypeError("No storagePath set in settings/index.js");
  }
  var storagePath =  path.isAbsolute(serverSettings.storagePath) ? serverSettings.storagePath : path.join(__dirname, "..", serverSettings.storagePath);
  app.use("/video/", express.static(path.join(storagePath, "video")));
}

// Check the status of a current video
app.get("/status/:id/", status);

// Serve background images and themes JSON statically
app.use("/settings/", function(req, res, next) {

  // Keep server settings off limits
  if (req.url.match(/\.js$/i)) {
    return res.status(404).send("Cannot GET " + path.join("/settings", req.url));
  }

  next();

}, express.static(path.join(__dirname, "..", "settings")));

// Serve editor files statically
app.use(express.static(path.join(__dirname, "..", "editor")));

app.use(errorHandlers);

module.exports = app;
<commit_msg>Limit routes<commit_after>// Dependencies
var express = require("express"),
    compression = require("compression"),
    path = require("path"),
    multer = require("multer"),
    uuid = require("node-uuid"),
    mkdirp = require("mkdirp");

// Routes and middleware
var logger = require("../lib/logger/"),
    render = require("./render.js"),
    status = require("./status.js"),
    errorHandlers = require("./error.js");

// Settings
var serverSettings = require("../settings/");

var app = express();

app.use(compression());
app.use(logger.morgan());

// Options for where to store uploaded audio and max size
var fileOptions = {
  storage: multer.diskStorage({
    destination: function(req, file, cb) {

      var dir = path.join(serverSettings.workingDirectory, uuid.v1());

      mkdirp(dir, function(err) {
        return cb(err, dir);
      });
    },
    filename: function(req, file, cb) {
      cb(null, "audio");
    }
  })
};

if (serverSettings.maxUploadSize) {
  fileOptions.limits = {
    fileSize: +serverSettings.maxUploadSize
  };
}

if (typeof serverSettings.workingDirectory !== "string") {
  throw new TypeError("No workingDirectory set in settings/index.js");
}

// On submission, check upload, validate input, and start generating a video
app.post("/submit/", [multer(fileOptions).single("audio"), render.validate, render.route]);

// If not using S3, serve videos locally
if (!serverSettings.s3Bucket) {
  if (typeof serverSettings.storagePath !== "string") {
    throw new TypeError("No storagePath set in settings/index.js");
  }
  var storagePath =  path.isAbsolute(serverSettings.storagePath) ? serverSettings.storagePath : path.join(__dirname, "..", serverSettings.storagePath);
  app.use("/video/", express.static(path.join(storagePath, "video")));
}

// Check the status of a current video
app.get("/status/:id/", status);

// Serve background images and themes JSON statically
app.use("/settings/", function(req, res, next) {

  // Limit to themes.json and bg images
  if (req.url.match(/^\/?themes.json$/i) || req.url.match(/^\/?backgrounds\/[^/]+$/i)) {
    return next();
  }

  return res.status(404).send("Cannot GET " + path.join("/settings", req.url));

}, express.static(path.join(__dirname, "..", "settings")));

// Serve editor files statically
app.use(express.static(path.join(__dirname, "..", "editor")));

app.use(errorHandlers);

module.exports = app;
<|endoftext|>


<commit_before>var mongoose = require('mongoose'),
  //LocalStrategy = require('passport-local').Strategy,
  //TwitterStrategy = require('passport-twitter').Strategy,
  FacebookTokenStrategy = require('passport-facebook-token').Strategy,
  //GitHubStrategy = require('passport-github').Strategy,
  //GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
  User = mongoose.model('User'),
  config = require('./config');

module.exports = function(passport) {
  //Serialize sessions
  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function(id, done) {
    User.findOne({
      _id: id
    }, function(err, user) {
      done(err, user);
    });
  });

  //Use local strategy
  /*
  passport.use(new LocalStrategy({
      usernameField: 'email',
      passwordField: 'password'
    },
    function(email, password, done) {
      User.findOne({
        email: email
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          return done(null, false, {
            message: 'Unknown user'
          });
        }
        if (!user.authenticate(password)) {
          return done(null, false, {
            message: 'Invalid password'
          });
        }
        return done(null, user);
      });
    }
  ));

  //Use twitter strategy
  passport.use(new TwitterStrategy({
      consumerKey: config.twitter.clientID,
      consumerSecret: config.twitter.clientSecret,
      callbackURL: config.twitter.callbackURL
    },
    function(token, tokenSecret, profile, done) {
      User.findOne({
        'twitter.id_str': profile.id
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          user = new User({
            name: profile.displayName,
            username: profile.username,
            provider: 'twitter',
            twitter: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));
  */
  //Use facebook strategy
  passport.use(new FacebookTokenStrategy({
      clientID: config.facebook.clientID,
      clientSecret: config.facebook.clientSecret
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({
        'facebook.id': profile.id
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.name.givenName[0]+"***"+profile.name.familyName[0]+profile.id.substr(-3),
            provider: 'facebook',
            facebook: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));

  /*
  //Use github strategy
  passport.use(new GitHubStrategy({
      clientID: config.github.clientID,
      clientSecret: config.github.clientSecret,
      callbackURL: config.github.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({
        'github.id': profile.id
      }, function(err, user) {
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.username,
            provider: 'github',
            github: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));

  //Use google strategy
  passport.use(new GoogleStrategy({
      clientID: config.google.clientID,
      clientSecret: config.google.clientSecret,
      callbackURL: config.google.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({
        'google.id': profile.id
      }, function(err, user) {
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.username,
            provider: 'google',
            google: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));*/
};<commit_msg>remove excess '***' from facebook generated username... no point<commit_after>var mongoose = require('mongoose'),
  //LocalStrategy = require('passport-local').Strategy,
  //TwitterStrategy = require('passport-twitter').Strategy,
  FacebookTokenStrategy = require('passport-facebook-token').Strategy,
  //GitHubStrategy = require('passport-github').Strategy,
  //GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
  User = mongoose.model('User'),
  config = require('./config');

module.exports = function(passport) {
  //Serialize sessions
  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function(id, done) {
    User.findOne({
      _id: id
    }, function(err, user) {
      done(err, user);
    });
  });

  //Use local strategy
  /*
  passport.use(new LocalStrategy({
      usernameField: 'email',
      passwordField: 'password'
    },
    function(email, password, done) {
      User.findOne({
        email: email
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          return done(null, false, {
            message: 'Unknown user'
          });
        }
        if (!user.authenticate(password)) {
          return done(null, false, {
            message: 'Invalid password'
          });
        }
        return done(null, user);
      });
    }
  ));

  //Use twitter strategy
  passport.use(new TwitterStrategy({
      consumerKey: config.twitter.clientID,
      consumerSecret: config.twitter.clientSecret,
      callbackURL: config.twitter.callbackURL
    },
    function(token, tokenSecret, profile, done) {
      User.findOne({
        'twitter.id_str': profile.id
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          user = new User({
            name: profile.displayName,
            username: profile.username,
            provider: 'twitter',
            twitter: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));
  */
  //Use facebook strategy
  passport.use(new FacebookTokenStrategy({
      clientID: config.facebook.clientID,
      clientSecret: config.facebook.clientSecret
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({
        'facebook.id': profile.id
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.name.givenName[0]+profile.name.familyName[0]+profile.id.substr(-3),
            provider: 'facebook',
            facebook: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));

  /*
  //Use github strategy
  passport.use(new GitHubStrategy({
      clientID: config.github.clientID,
      clientSecret: config.github.clientSecret,
      callbackURL: config.github.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({
        'github.id': profile.id
      }, function(err, user) {
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.username,
            provider: 'github',
            github: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));

  //Use google strategy
  passport.use(new GoogleStrategy({
      clientID: config.google.clientID,
      clientSecret: config.google.clientSecret,
      callbackURL: config.google.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({
        'google.id': profile.id
      }, function(err, user) {
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.username,
            provider: 'google',
            google: profile._json
          });
          user.save(function(err) {
            if (err) console.log(err);
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));*/
};<|endoftext|>