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

    var module = angular.module('messages.controllers', []);

    // Service to share data across the controllers
    module.factory('messages_list', function() {
        return {
            messages : []
        };
    });

    module.controller('NewMessageController', ['$scope', '$modal', '$window', 'Message', 'Student', 'StudentSearch', 'Class', 'messages_list', '$rootScope',
            function($scope, $modal, $window, Message, Student, StudentSearch, Class, messages_list, $rootScope) {
                $scope.course_id = parseInt($window.course_id, 10);
                $scope.messages = messages_list.messages;
                $scope.new_message = function () {
                    var modalInstance = $modal.open({
                        templateUrl: 'newMessageModal.html',
                        controller: ['$scope', '$modalInstance', 'course_id', SendMessageModalInstanceCtrl],
                        resolve: {
                            course_id: function () {
                                return $scope.course_id;
                            }
                        }
                    });
                    modalInstance.result.then(function (new_message) {
                        new_message.$save({}, function(new_message){
                            messages_list.messages.unshift(new_message);
                            $rootScope.$broadcast('newMessage');
                        });

                    });
                };
                var SendMessageModalInstanceCtrl = function ($scope, $modalInstance, course_id) {

                    $scope.new_message = new Message();
                    $scope.new_message.course = course_id;
                    $scope.new_message.users = [];
                    $scope.recipient_list = [];
                    $scope.empty_msg_subject_error = false;
                    $scope.empty_msg_body_error = false;

                    $scope.classes = Class.query({course: course_id}, function(classes){
                        classes.checked = [];
                        return classes;
                    });

                    // trick to user modal.all_checked in ng-model html tag
                    $scope.modal = {};
                    $scope.modal.all_checked = true;

                    $scope.send = function () {
                        // TODO validação dos campo: títle e message não podem ser vazios
                        if ($scope.modal.all_checked) {
                            $scope.new_message.users = [];
                            angular.forEach($scope.classes, function(klass) {
                                $scope.new_message.users = $scope.new_message.users.concat(klass.students);
                            });
                        } else if ($scope.classes.checked) {
                            angular.forEach($scope.classes.checked, function(klass) {
                                $scope.new_message.users = $scope.new_message.users.concat(klass);
                            });
                        }
                        if ($scope.new_message.message && $scope.new_message.subject) {
                            $modalInstance.close($scope.new_message);
                            $scope.empty_msg_subject_error = false;
                            $scope.empty_msg_body_error = false;
                        }
                        if (!$scope.new_message.message) {
                            $scope.empty_msg_body_error = true;
                        } else {
                            $scope.empty_msg_body_error = false;
                        }
                        if (!$scope.new_message.subject) {
                            $scope.empty_msg_subject_error = true;
                        } else {
                            $scope.empty_msg_subject_error = false;
                        }
                    };

                    $scope.cancel = function () {
                        $modalInstance.dismiss();
                    };
                    $scope.getUsers = function(val) {
                        return new StudentSearch(val, course_id);
                    };

                    $scope.on_select_student = function(model) {
                        $scope.new_message.users.unshift(model.id);
                        $scope.recipient_list.unshift(model);
                        $scope.asyncSelected = '';
                    };

                    $scope.remove_student = function(index) {
                        $scope.new_message.users.splice(index, 1);
                        $scope.recipient_list.splice(index, 1);
                    };

                };
            }
        ]);

    module.controller('MessagesListController', ['$scope', '$modal', '$window', 'Message', 'messages_list',
        function($scope, $modal, $window, Message, messages_list) {
            $scope.course_id = parseInt($window.course_id, 10);
            $scope.course_slug = $window.course_slug;
            messages_list.messages = Message.query({course: $scope.course_id});
            $scope.messages = messages_list.messages;
            $scope.$on('newMessage', function() {
                $scope.messages = messages_list.messages;
            });
        }
    ]);

    module.controller('MessageController', ['$scope', '$window', 'Message',
        function($scope, $window, Message) {
            $scope.course_id = parseInt($window.course_id, 10);
            $scope.message_id = document.location.href.match(/message\/([0-9]+)/)[1];
            $scope.message = Message.get({messageId: $scope.message_id}, function(message) {
            });
        }
    ]);
})(angular);
<commit_msg>fix module that sends emails<commit_after>(function(angular){
    'use strict';

    var module = angular.module('messages.controllers', []);

    // Service to share data across the controllers
    module.factory('messages_list', function() {
        return {
            messages : []
        };
    });

    module.controller('NewMessageController', ['$scope', '$modal', '$window', 'Message', 'Student', 'StudentSearch', 'Class', 'messages_list', '$rootScope',
            function($scope, $modal, $window, Message, Student, StudentSearch, Class, messages_list, $rootScope) {
                $scope.course_id = parseInt($window.course_id, 10);
                $scope.messages = messages_list.messages;
                $scope.new_message = function () {
                    var modalInstance = $modal.open({
                        templateUrl: 'newMessageModal.html',
                        controller: ['$scope', '$modalInstance', 'course_id', SendMessageModalInstanceCtrl],
                        resolve: {
                            course_id: function () {
                                return $scope.course_id;
                            }
                        }
                    });
                    modalInstance.result.then(function (new_message) {
                        new_message.$save({}, function(new_message){
                            messages_list.messages.unshift(new_message);
                            $rootScope.$broadcast('newMessage');
                        });

                    });
                };
                var SendMessageModalInstanceCtrl = function ($scope, $modalInstance, course_id) {

                    $scope.new_message = new Message();
                    $scope.new_message.course = course_id;
                    $scope.new_message.users = [];
                    $scope.recipient_list = [];
                    $scope.empty_msg_subject_error = false;
                    $scope.empty_msg_body_error = false;

                    $scope.classes = Class.query({course: course_id}, function(classes){
                        classes.checked = [];
                        return classes;
                    });

                    // trick to user modal.all_checked in ng-model html tag
                    $scope.modal = {};
                    $scope.modal.all_checked = true;

                    $scope.send = function () {
                        // TODO validação dos campo: títle e message não podem ser vazios
                        if ($scope.modal.all_checked) {
                            $scope.new_message.users = [];
                            angular.forEach($scope.classes, function(klass) {
                                angular.forEach(klass.students, function(student) {
                                    $scope.new_message.users = $scope.new_message.users.concat(student.id);
                                });
                            });
                        } else if ($scope.classes.checked) {
                            angular.forEach($scope.classes.checked, function(klass) {
                                angular.forEach(klass.students, function(student) {
                                    $scope.new_message.users = $scope.new_message.users.concat(student.id);
                                    console.log(student.id);
                                });
                            });
                        }
                        if ($scope.new_message.message && $scope.new_message.subject) {
                            $modalInstance.close($scope.new_message);
                            $scope.empty_msg_subject_error = false;
                            $scope.empty_msg_body_error = false;
                        }
                        if (!$scope.new_message.message) {
                            $scope.empty_msg_body_error = true;
                        } else {
                            $scope.empty_msg_body_error = false;
                        }
                        if (!$scope.new_message.subject) {
                            $scope.empty_msg_subject_error = true;
                        } else {
                            $scope.empty_msg_subject_error = false;
                        }
                    };

                    $scope.cancel = function () {
                        $modalInstance.dismiss();
                    };
                    $scope.getUsers = function(val) {
                        return new StudentSearch(val, course_id);
                    };

                    $scope.on_select_student = function(model) {
                        $scope.new_message.users.unshift(model.id);
                        $scope.recipient_list.unshift(model);
                        $scope.asyncSelected = '';
                    };

                    $scope.remove_student = function(index) {
                        $scope.new_message.users.splice(index, 1);
                        $scope.recipient_list.splice(index, 1);
                    };

                };
            }
        ]);

    module.controller('MessagesListController', ['$scope', '$modal', '$window', 'Message', 'messages_list',
        function($scope, $modal, $window, Message, messages_list) {
            $scope.course_id = parseInt($window.course_id, 10);
            $scope.course_slug = $window.course_slug;
            messages_list.messages = Message.query({course: $scope.course_id});
            $scope.messages = messages_list.messages;
            $scope.$on('newMessage', function() {
                $scope.messages = messages_list.messages;
            });
        }
    ]);

    module.controller('MessageController', ['$scope', '$window', 'Message',
        function($scope, $window, Message) {
            $scope.course_id = parseInt($window.course_id, 10);
            $scope.message_id = document.location.href.match(/message\/([0-9]+)/)[1];
            $scope.message = Message.get({messageId: $scope.message_id}, function(message) {
            });
        }
    ]);
})(angular);
<|endoftext|>


<commit_before>'use strict';

// Make our own plugin main interface an event emitter.
// This can be used to communicate and subscribe to others plugins events.
var EventEmitter = require('events').EventEmitter;

/**
 * Plugin Interface
 * @class Plugin
 *
 * @property {App} app
 * @property {[]} plugins
 * @property {ServerClient} server
 * @property {Players} players
 * @property {Maps} maps
 * @property {{}} models
 * @property {{}} config
 * @property {UIFacade} ui
 *
 */
module.exports = class extends EventEmitter {

  /**
   * Construct the plugin.
   */
  constructor() {
    super();

    // Will be injected by core
    this.app = null;

    this.plugins = null;
    this.server = null;
    this.players = null;
    this.maps = null;

    /**
     * Will hold the defined models for this plugin!
     *
     * @type {{}}
     */
    this.models = {};
  }

  /**
   * Inject Core App interface into the plugin.
   *
   * @param {App} app App context.
   * @param {object} config Plugin config.
   */
  inject(app, config) {
    this.app = app;
    this.config = config;

    this.server = app.server;

    // Expand app into separate parts.
    this.players = app.players;
    this.maps = app.maps;
    this.plugins = app.plugins;
    this.ui = app.ui;
  }
};
<commit_msg>Fix exports key<commit_after>'use strict';

// Make our own plugin main interface an event emitter.
// This can be used to communicate and subscribe to others plugins events.
var EventEmitter = require('events').EventEmitter;

/**
 * Plugin Interface
 * @class Plugin
 *
 * @property {App} app
 * @property {[]} plugins
 * @property {ServerClient} server
 * @property {Players} players
 * @property {Maps} maps
 * @property {{}} models
 * @property {{}} config
 * @property {UIFacade} ui
 *
 */
module.exports.default = class extends EventEmitter {

  /**
   * Construct the plugin.
   */
  constructor() {
    super();

    // Will be injected by core
    this.app = null;

    this.plugins = null;
    this.server = null;
    this.players = null;
    this.maps = null;

    /**
     * Will hold the defined models for this plugin!
     *
     * @type {{}}
     */
    this.models = {};
  }

  /**
   * Inject Core App interface into the plugin.
   *
   * @param {App} app App context.
   * @param {object} config Plugin config.
   */
  inject(app, config) {
    this.app = app;
    this.config = config;

    this.server = app.server;

    // Expand app into separate parts.
    this.players = app.players;
    this.maps = app.maps;
    this.plugins = app.plugins;
    this.ui = app.ui;
  }
};
<|endoftext|>


<commit_before>'use strict';

function fastbootExpressMiddleware(distPath, options) {
  let opts = options;

  if (arguments.length === 1) {
    if (typeof distPath === 'string') {
      opts = { distPath: distPath };
    } else {
      opts = distPath;
    }
  }

  opts = opts || {};

  let log = opts.log !== false ? _log : function() {};

  let fastboot = opts.fastboot;

  if (!fastboot) {
    let FastBoot = require('fastboot');
    fastboot = new FastBoot({
      distPath: opts.distPath,
      resilient: opts.resilient,
    });
  }

  return async function(req, res, next) {
    let path = req.url;

    try {
      let result = await fastboot.visit(path, { request: req, response: res });
      let responseBody = opts.chunkedResponse ? result.chunks() : result.html();

      let body = await responseBody;
      let headers = result.headers;
      let statusMessage = result.error ? 'NOT OK ' : 'OK ';

      for (var pair of headers.entries()) {
        res.append(pair[0], pair[1]);
      }

      if (result.error) {
        log('RESILIENT MODE CAUGHT:', result.error.stack);
        next(result.error);
      }

      log(result.statusCode, statusMessage + path);
      res.status(result.statusCode);

      if (typeof body === 'string') {
        res.send(body);
      } else if (result.error) {
        res.send(body[0]);
      } else {
        body.forEach(chunk => res.write(chunk));
        res.end();
      }
    } catch (error) {
      if (error.name === 'UnrecognizedURLError') {
        next();
      } else {
        res.status(500);
        next(error);
      }
    }
  };
}

let chalk;

function _log(statusCode, message, startTime) {
  chalk = chalk || require('chalk');
  let color = statusCode === 200 ? 'green' : 'red';
  let now = new Date();

  if (startTime) {
    let diff = Date.now() - startTime;
    message = message + chalk.blue(' ' + diff + 'ms');
  }

  console.log(chalk.blue(now.toISOString()) + ' ' + chalk[color](statusCode) + ' ' + message);
}

module.exports = fastbootExpressMiddleware;
<commit_msg>Handle resilient mode errors before accessing result.headers<commit_after>'use strict';

function fastbootExpressMiddleware(distPath, options) {
  let opts = options;

  if (arguments.length === 1) {
    if (typeof distPath === 'string') {
      opts = { distPath: distPath };
    } else {
      opts = distPath;
    }
  }

  opts = opts || {};

  let log = opts.log !== false ? _log : function() {};

  let fastboot = opts.fastboot;

  if (!fastboot) {
    let FastBoot = require('fastboot');
    fastboot = new FastBoot({
      distPath: opts.distPath,
      resilient: opts.resilient,
    });
  }

  return async function(req, res, next) {
    let path = req.url;

    try {
      let result = await fastboot.visit(path, { request: req, response: res });
      let body = opts.chunkedResponse ? await result.chunks() : await result.html();

      if (result.error) {
        log('RESILIENT MODE CAUGHT:', result.error.stack);
        next(result.error);
      }

      let headers = result.headers;
      let statusMessage = result.error ? 'NOT OK ' : 'OK ';

      for (var pair of headers.entries()) {
        res.append(pair[0], pair[1]);
      }

      log(result.statusCode, statusMessage + path);
      res.status(result.statusCode);

      if (typeof body === 'string') {
        res.send(body);
      } else if (result.error) {
        res.send(body[0]);
      } else {
        body.forEach(chunk => res.write(chunk));
        res.end();
      }
    } catch (error) {
      if (error.name === 'UnrecognizedURLError') {
        next();
      } else {
        res.status(500);
        next(error);
      }
    }
  };
}

let chalk;

function _log(statusCode, message, startTime) {
  chalk = chalk || require('chalk');
  let color = statusCode === 200 ? 'green' : 'red';
  let now = new Date();

  if (startTime) {
    let diff = Date.now() - startTime;
    message = message + chalk.blue(' ' + diff + 'ms');
  }

  console.log(chalk.blue(now.toISOString()) + ' ' + chalk[color](statusCode) + ' ' + message);
}

module.exports = fastbootExpressMiddleware;
<|endoftext|>


<commit_before>/**
 * @file Popup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import TriggerPop from '../_TriggerPop';
import Theme from '../Theme';

import Position from '../_statics/Position';

import Event from '../_vendors/Event';
import Dom from '../_vendors/Dom';
import Util from '../_vendors/Util';
import PopManagement from '../_vendors/PopManagement';

class Popup extends Component {

    static Position = Position;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.closeTimeout = null;

    }

    /**
     * public
     */
    resetPosition = () => {
        this.refs.popup && this.refs.popup.resetPosition();
    };

    clearCloseTimeout = () => {
        if (this.closeTimeout) {
            clearTimeout(this.closeTimeout);
            this.closeTimeout = null;
        }
    };

    triggerHandler = (el, triggerEl, popupEl, currentVisible, isBlurClose) => {

        while (el) {
            if (el == popupEl) {
                return currentVisible;
            }
            el = el.parentNode;
        }

        return isBlurClose ? false : currentVisible;

    };

    mouseDownHandler = e => {

        const {visible, triggerEl, isBlurClose, triggerHandler, onRequestClose} = this.props,
            popupEl = this.refs.popup.getEl();

        if (!triggerEl) {
            return;
        }

        let currVisible;

        if (triggerHandler) {
            currVisible = triggerHandler(e.target, triggerEl, popupEl, visible, isBlurClose);
        } else if (!Dom.isParent(e.target, triggerEl)) {
            currVisible = this.triggerHandler(e.target, triggerEl, popupEl, visible, isBlurClose);
        }

        if (currVisible === false) {
            this.clearCloseTimeout();
            this.closeTimeout = setTimeout(() => {
                onRequestClose && onRequestClose(e);
            });
        }

    };

    componentDidMount() {
        Event.addEvent(document, 'mousedown', this.mouseDownHandler);
    }

    componentWillReceiveProps(nextProps) {

        const {visible, isEscClose} = nextProps;

        if (isEscClose && visible) {
            PopManagement.push(this);
        }

    }

    componentWillUnmount() {

        this.clearCloseTimeout();
        Event.removeEvent(document, 'mousedown', this.mouseDownHandler);

        PopManagement.pop(this);

    }

    render() {

        const {

                className, contentClassName,

                // not passing down these props
                triggerHandler, onRequestClose,

                ...restProps

            } = this.props,

            popupClassName = classNames('popup', {
                [className]: className
            }),

            popupContentClassName = classNames('popup-content', {
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        ref="popup"
                        className={popupClassName}
                        contentClassName={popupContentClassName}/>
        );
    }

}

Popup.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popup alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    /**
     * If true,popup will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,
    isEscClose: PropTypes.bool,
    shouldPreventContainerScroll: PropTypes.bool,
    isTriggerPositionFixed: PropTypes.bool,
    showModal: PropTypes.bool,

    /**
     * The function of popup event handler.
     */
    triggerHandler: PropTypes.func,

    /**
     * The function of popup render.
     */
    onRender: PropTypes.func,

    /**
     * The function of popup rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of popup destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of popup destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Popup.defaultProps = {

    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,

    isBlurClose: true,
    isEscClose: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    showModal: false

};

export default Popup;<commit_msg>update Popup<commit_after>/**
 * @file Popup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import TriggerPop from '../_TriggerPop';
import Theme from '../Theme';

import Position from '../_statics/Position';

import Event from '../_vendors/Event';
import Dom from '../_vendors/Dom';
import Util from '../_vendors/Util';
import PopManagement from '../_vendors/PopManagement';

class Popup extends Component {

    static Position = Position;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.closeTimeout = null;

    }

    /**
     * public
     */
    resetPosition = () => {
        this.refs.popup && this.refs.popup.resetPosition();
    };

    clearCloseTimeout = () => {
        if (this.closeTimeout) {
            clearTimeout(this.closeTimeout);
            this.closeTimeout = null;
        }
    };

    triggerHandler = (el, triggerEl, popupEl, currentVisible, isBlurClose) => {

        while (el) {
            if (el == popupEl) {
                return currentVisible;
            }
            el = el.parentNode;
        }

        return isBlurClose ? false : currentVisible;

    };

    closeHandler = e => {

        const {visible, triggerEl, isBlurClose, triggerHandler, onRequestClose} = this.props,
            popupEl = this.refs.popup.getEl();

        if (!triggerEl) {
            return;
        }

        let currVisible;

        if (triggerHandler) {
            currVisible = triggerHandler(e.target, triggerEl, popupEl, visible, isBlurClose);
        } else if (!Dom.isParent(e.target, triggerEl)) {
            currVisible = this.triggerHandler(e.target, triggerEl, popupEl, visible, isBlurClose);
        }

        if (currVisible === false) {
            this.clearCloseTimeout();
            this.closeTimeout = setTimeout(() => {
                onRequestClose && onRequestClose(e);
            });
        }

    };

    componentDidMount() {
        Event.addEvent(document, 'click', this.closeHandler);
    }

    componentWillReceiveProps(nextProps) {

        const {visible, isEscClose} = nextProps;

        if (isEscClose && visible) {
            PopManagement.push(this);
        }

    }

    componentWillUnmount() {

        this.clearCloseTimeout();
        Event.removeEvent(document, 'click', this.closeHandler);

        PopManagement.pop(this);

    }

    render() {

        const {

                className, contentClassName,

                // not passing down these props
                triggerHandler, onRequestClose,

                ...restProps

            } = this.props,

            popupClassName = classNames('popup', {
                [className]: className
            }),

            popupContentClassName = classNames('popup-content', {
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        ref="popup"
                        className={popupClassName}
                        contentClassName={popupContentClassName}/>
        );
    }

}

Popup.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popup alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    /**
     * If true,popup will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,
    isEscClose: PropTypes.bool,
    shouldPreventContainerScroll: PropTypes.bool,
    isTriggerPositionFixed: PropTypes.bool,
    showModal: PropTypes.bool,

    /**
     * The function of popup event handler.
     */
    triggerHandler: PropTypes.func,

    /**
     * The function of popup render.
     */
    onRender: PropTypes.func,

    /**
     * The function of popup rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of popup destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of popup destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Popup.defaultProps = {

    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,

    isBlurClose: true,
    isEscClose: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    showModal: false

};

export default Popup;<|endoftext|>


<commit_before>import React, { useEffect, useRef, useState } from 'react'
import ReactDOM from 'react-dom'
import { Anchor, grommet as defaultGrommet, Grommet, Header, Heading, Box, Main, Avatar, Paragraph, ResponsiveContext, Text } from 'grommet'
import { deepMerge } from 'grommet/utils'

const profilePic = require('./img/mo.jpeg')
const githubIcon = require('./img/github.png')
const instagramIcon = require('./img/instagram.png')
const linkedInIcon = require('./img/linkedin.png')
const twitterIcon = require('./img/twitter.png')
const resume = require('./CV_Mohamed_Gharsallah.pdf')

const grommet = deepMerge(defaultGrommet, {
  global: {
    breakpoints: {
      small: {
        value: 900,
      },
      medium: {
        value: 1600,
      },
      large: {
        value: 2000,
      },
    },
  },
})

const WordShuffle = ({ words }) => {
  const duration = 3000
  const [wordIndex, setWordIndex] = useState(0)
  const interval = useRef(null)
  useEffect(() => {
    interval.current = setTimeout(() => {
      setWordIndex(wordIndex < words.length - 1 ? wordIndex + 1 : 0)
    }, duration)

    return () => {
      clearInterval(interval.current)
    }
  }, [wordIndex])

  return (
    <span key={words[wordIndex]} className="shuffle-animation" style={{ '--duration': `${duration / 1000}s` }}>
      {words[wordIndex]}

  )
}

const App = () => {
  const [knowMore, setKnowMore] = useState(false)
  return (
    <Grommet theme={grommet}>
      <ResponsiveContext.Consumer>
        {(size) => (
          <>

              <Heading level="4">Mohamed Gharsallah</Heading>
              <Box direction="row" textAlign="right" gap="medium">
                <Anchor href="#profile" color="dark-1">
                  Profile
                </Anchor>
                <Anchor href="#hire" color="dark-1">
                  Hire
                </Anchor>
                <Anchor target="_blanc" href={resume} color="dark-1">
                  Resume
                </Anchor>
                <Anchor target="_blanc" href="https://medium.com/@gharsallah" color="dark-1">
                  Blog
                </Anchor>
              </Box>

              <Box justify="center" pad={{ top: 'xlarge', bottom: 'large' }} className="page-height">
                <Box animation="slideDown" align="start" justify="center" direction={size !== 'small' ? 'row' : 'column'} gap="large" wrap>
                  <Box width="200px" gap="medium" align="center">
                    <Avatar key="profile" size="300px" src={profilePic} round="medium" />
                    <Box direction="row" gap="medium">

                        <Avatar key="linkedIn" size="24px" round={false} src={linkedInIcon} />

                        <Avatar key="github" size="24px" round={false} src={githubIcon} />

                        <Avatar key="twitter" size="24px" round={false} src={twitterIcon} />

                        <Avatar key="instagram" size="24px" round={false} src={instagramIcon} />

                    </Box>
                  </Box>
                  <Box width={{ max: '500px', min: '350px' }} gap="small">
                    <Heading color="dark-3" level="3">
                      Hey there 👋🏻{' '}
                    </Heading>
                    <Heading level="2">I'm Mohamed Gharsallah</Heading>
                    <Heading color="dark-3" level="3">
                      I am a Software engineer with full-stack experience
                    </Heading>
                    <Box animation={['fadeIn', 'slideDown']}>
                      <Paragraph color="dark-3">
                        I'm also an avid reader, cook and currently trying to get into woodcraft without loosing my fingers.
                      </Paragraph>
                      <Paragraph color="dark-3">
                        I grow up playing with the south Tunisian dunes and swam through the mediterranean.
                      </Paragraph>
                      <Paragraph color="dark-3">
                        With a passion for travel and IT, I am settled in Germany and traveling across Europe when no pandemic is
                        undergoing.
                      </Paragraph>
                      <Box pad={{ top: 'small' }} direction="row">
                        <Anchor target="_blanc" color="dark-1" href={resume}>
                          👉🏻 Check my Resume
                        </Anchor>
                      </Box>
                    </Box>
                  </Box>
                </Box>
              </Box>
              <Box id="hire" animation="slideDown" pad="large" justify="center" className="page-height">
                <Heading style={{ maxWidth: '100%' }} color="dark-3" level="2">
                  <WordShuffle words={['E-commerce solution', 'Api', 'Mobile app', 'Business platform']} />{' '}
                </Heading>
                <Heading level="1">Can do! How can I be of help?</Heading>
                <Box pad={{ top: 'medium' }}>
                  <Text color="dark-3">
                    Send me an email on: <Anchor label="hire@gharsallah.com" href="mailto:hire@gharsallah.com" />
                  </Text>
                  <Text color="dark-3">
                    Or drop a message on:
                    <Anchor label="linkedIn.com/in/gharsallah-m" href="https://www.linkedin.com/in/gharsallah-m/" />
                  </Text>
                </Box>
              </Box>

          </>
        )}
      </ResponsiveContext.Consumer>
    </Grommet>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))
<commit_msg>align social icons with resume link<commit_after>import React, { useEffect, useRef, useState } from 'react'
import ReactDOM from 'react-dom'
import { Anchor, grommet as defaultGrommet, Grommet, Header, Heading, Box, Main, Avatar, Paragraph, ResponsiveContext, Text } from 'grommet'
import { deepMerge } from 'grommet/utils'

const profilePic = require('./img/mo.jpeg')
const githubIcon = require('./img/github.png')
const instagramIcon = require('./img/instagram.png')
const linkedInIcon = require('./img/linkedin.png')
const twitterIcon = require('./img/twitter.png')
const resume = require('./CV_Mohamed_Gharsallah.pdf')

const grommet = deepMerge(defaultGrommet, {
  global: {
    breakpoints: {
      small: {
        value: 900,
      },
      medium: {
        value: 1600,
      },
      large: {
        value: 2000,
      },
    },
  },
})

const WordShuffle = ({ words }) => {
  const duration = 3000
  const [wordIndex, setWordIndex] = useState(0)
  const interval = useRef(null)
  useEffect(() => {
    interval.current = setTimeout(() => {
      setWordIndex(wordIndex < words.length - 1 ? wordIndex + 1 : 0)
    }, duration)

    return () => {
      clearInterval(interval.current)
    }
  }, [wordIndex])

  return (
    <span key={words[wordIndex]} className="shuffle-animation" style={{ '--duration': `${duration / 1000}s` }}>
      {words[wordIndex]}

  )
}

const App = () => {
  const [knowMore, setKnowMore] = useState(false)
  return (
    <Grommet theme={grommet}>
      <ResponsiveContext.Consumer>
        {(size) => (
          <>

              <Heading level="4">Mohamed Gharsallah</Heading>
              <Box direction="row" textAlign="right" gap="medium">
                <Anchor href="#profile" color="dark-1">
                  Profile
                </Anchor>
                <Anchor href="#hire" color="dark-1">
                  Hire
                </Anchor>
                <Anchor target="_blanc" href={resume} color="dark-1">
                  Resume
                </Anchor>
                <Anchor target="_blanc" href="https://medium.com/@gharsallah" color="dark-1">
                  Blog
                </Anchor>
              </Box>

              <Box justify="center" pad={{ top: 'xlarge', bottom: 'large' }} className="page-height">
                <Box animation="slideDown" align="start" justify="center" direction={size !== 'small' ? 'row' : 'column'} gap="large" wrap>
                  <Box width="218px" gap="medium" align="center">
                    <Avatar key="profile" size="328px" src={profilePic} round="medium" />
                    <Box direction="row" gap="medium">

                        <Avatar key="linkedIn" size="24px" round={false} src={linkedInIcon} />

                        <Avatar key="github" size="24px" round={false} src={githubIcon} />

                        <Avatar key="twitter" size="24px" round={false} src={twitterIcon} />

                        <Avatar key="instagram" size="24px" round={false} src={instagramIcon} />

                    </Box>
                  </Box>
                  <Box width={{ max: '500px', min: '350px' }} gap="small">
                    <Heading color="dark-3" level="3">
                      Hey there 👋🏻{' '}
                    </Heading>
                    <Heading level="2">I'm Mohamed Gharsallah</Heading>
                    <Heading color="dark-3" level="3">
                      I am a Software engineer with full-stack experience
                    </Heading>
                    <Box animation={['fadeIn', 'slideDown']}>
                      <Paragraph color="dark-3">
                        I'm also an avid reader, cook and currently trying to get into woodcraft without loosing my fingers.
                      </Paragraph>
                      <Paragraph color="dark-3">
                        I grow up playing with the south Tunisian dunes and swam through the mediterranean.
                      </Paragraph>
                      <Paragraph color="dark-3">
                        With a passion for travel and IT, I am settled in Germany and traveling across Europe when no pandemic is
                        undergoing.
                      </Paragraph>
                      <Box pad={{ top: 'small' }} direction="row">
                        <Anchor target="_blanc" color="dark-1" href={resume}>
                          👉🏻 Check my Resume
                        </Anchor>
                      </Box>
                    </Box>
                  </Box>
                </Box>
              </Box>
              <Box id="hire" animation="slideDown" pad="large" justify="center" className="page-height">
                <Heading style={{ maxWidth: '100%' }} color="dark-3" level="2">
                  <WordShuffle words={['E-commerce solution', 'Api', 'Mobile app', 'Business platform']} />{' '}
                </Heading>
                <Heading level="1">Can do! How can I be of help?</Heading>
                <Box pad={{ top: 'medium' }}>
                  <Text color="dark-3">
                    Send me an email on: <Anchor label="hire@gharsallah.com" href="mailto:hire@gharsallah.com" />
                  </Text>
                  <Text color="dark-3">
                    Or drop a message on:
                    <Anchor label="linkedIn.com/in/gharsallah-m" href="https://www.linkedin.com/in/gharsallah-m/" />
                  </Text>
                </Box>
              </Box>

          </>
        )}
      </ResponsiveContext.Consumer>
    </Grommet>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))
<|endoftext|>


<commit_before>
var cljsLoad = require("./cljs-load");

var srcFile = "outsite/public/js/main.js";
var outputDirectory = "outsite/public/js/out/";
var moduleName = "devsetup";

var beep = "\u0007";

if (typeof location === "undefined") {
    // figwheel wants js/location to exist, even if it doesn't run,
    // for some reason
    global.location = {};
}

var gensite = function () {
    console.log("Loading " + srcFile);
    var optNone = cljsLoad.load(srcFile, outputDirectory, moduleName);
    sitetools.genpages({"opt-none": optNone});
}

var compileFail = function () {
  var msg = process.argv[process.argv.length - 1];
  if (msg && msg.match(/failed/)) {
    console.log("Compilation failed" + beep);
    return true;
  }
};

if (!compileFail()) {
  try {
    gensite();
  } catch (e) {
    console.log(e + beep);
    console.error(e.stack);
  }
}
<commit_msg>Make sure gen-site exists, even when intervals are running<commit_after>
var cljsLoad = require("./cljs-load");

var srcFile = "outsite/public/js/main.js";
var outputDirectory = "outsite/public/js/out/";
var moduleName = "devsetup";

var beep = "\u0007";

if (typeof location === "undefined") {
    // figwheel wants js/location to exist, even if it doesn't run,
    // for some reason
    global.location = {};
}

var gensite = function () {
    console.log("Loading " + srcFile);
    var optNone = cljsLoad.load(srcFile, outputDirectory, moduleName);
    sitetools.genpages({"opt-none": optNone});
}

var compileFail = function () {
  var msg = process.argv[process.argv.length - 1];
  if (msg && msg.match(/failed/)) {
    console.log("Compilation failed" + beep);
    return true;
  }
};

if (!compileFail()) {
  try {
    gensite();
  } catch (e) {
    console.log(e + beep);
    console.error(e.stack);
    process.exit(1);
  }
}
process.exit(0);
<|endoftext|>


<commit_before>import got from 'got';
import getArtistTitle, { fallBackToArtist } from 'get-artist-title';

function normalizeMedia(media) {
  const [artist, title] = getArtistTitle(media.title, [
    'base',
    fallBackToArtist(media.soundtrack_artist || media['owner.username'])
  ]);

  return {
    sourceID: media.id,
    artist, title,
    duration: media.duration,
    thumbnail: media.thumbnail_360_url,
    restricted: []
  };
}

export function getVideoID(url) {
  const match = /\/video\/([kx][a-zA-Z0-9]+)($|_)/.exec(url);
  if (match) {
    return match[1];
  }
  return null;
}

const defaultOptions = {
  api: 'https://api.dailymotion.com/',
  fields: [
    'id',
    'title',
    'owner.username',
    'allow_embed',
    'duration',
    'explicit',
    'soundtrack_artist',
    'thumbnail_360_url'
  ]
};

export default function dailymotionSource(uw, userOptions = {}) {
  const opts = {
    ...defaultOptions,
    ...userOptions
  };

  async function getOne(sourceID) {
    const { body } = await got(`${opts.api}video/${sourceID}`, {
      json: true,
      query: {
        fields: opts.fields.join(',')
      }
    });

    return normalizeMedia(body);
  }

  async function get(sourceIDs) {
    // Private videos don't show up in the /videos endpoint. They will normally
    // only be added one at a time, though, because the search can only find one
    // at a time. The /video/{id} endpoint _does_ return private videos, so
    // we'll use that instead when we're requesting just one video. This should
    // work most of the time, at least.
    // A more robust way would be to attempt to hit the /video/{id} endpoints
    // for any videos that were not returned from the /videos request below 👇,
    // but I'm not sure that it's necessary. We can change it if it turns out to
    // be a problem.
    if (sourceIDs.length === 1) {
      return [await getOne(sourceIDs[0])];
    }

    const { body } = await got(`${opts.api}videos`, {
      json: true,
      query: {
        limit: sourceIDs.length,
        ids: sourceIDs.join(','),
        fields: opts.fields.join(',')
      }
    });

    const videos = {};
    for (const video of body.list) {
      videos[video.id] = normalizeMedia(video);
    }

    return sourceIDs.map(id => videos[id]);
  }

  async function search(query, page = {}) {
    const id = getVideoID(query);
    if (id) {
      return [await getOne(id)];
    }

    const { body } = await got(`${opts.api}videos`, {
      json: true,
      query: {
        search: query,
        limit: 50,
        fields: opts.fields.join(',')
      }
    });
    return body.list.map(normalizeMedia);
  }

  return {
    get: get, // eslint-disable-line object-shorthand
    search
  };
}
<commit_msg>make sure private videos are identified by their k-ID<commit_after>import got from 'got';
import getArtistTitle, { fallBackToArtist } from 'get-artist-title';

function normalizeMedia(media) {
  const [artist, title] = getArtistTitle(media.title, [
    'base',
    fallBackToArtist(media.soundtrack_artist || media['owner.username'])
  ]);

  return {
    sourceID: media.id,
    artist, title,
    duration: media.duration,
    thumbnail: media.thumbnail_360_url,
    restricted: []
  };
}

export function getVideoID(url) {
  const match = /\/video\/([kx][a-zA-Z0-9]+)($|_)/.exec(url);
  if (match) {
    return match[1];
  }
  return null;
}

const defaultOptions = {
  api: 'https://api.dailymotion.com/',
  fields: [
    'id',
    'title',
    'owner.username',
    'allow_embed',
    'duration',
    'explicit',
    'soundtrack_artist',
    'thumbnail_360_url'
  ]
};

export default function dailymotionSource(uw, userOptions = {}) {
  const opts = {
    ...defaultOptions,
    ...userOptions
  };

  async function getOne(sourceID) {
    const { body } = await got(`${opts.api}video/${sourceID}`, {
      json: true,
      query: {
        fields: opts.fields.join(',')
      }
    });

    // Private videos return their x-ID ("x8yd34t"), but can only be accessed
    // using their k-ID ("k7dtszqBcKiDg952dNz"). We'll override the returned
    // x-ID with the original sourceID, so k-IDs will stay k-IDs.
    return Object.assign(normalizeMedia(body), {
      sourceID
    });
  }

  async function get(sourceIDs) {
    // Private videos don't show up in the /videos endpoint. They will normally
    // only be added one at a time, though, because the search can only find one
    // at a time. The /video/{id} endpoint _does_ return private videos, so
    // we'll use that instead when we're requesting just one video. This should
    // work most of the time, at least.
    // A more robust way would be to attempt to hit the /video/{id} endpoints
    // for any videos that were not returned from the /videos request below 👇,
    // but I'm not sure that it's necessary. We can change it if it turns out to
    // be a problem.
    if (sourceIDs.length === 1) {
      return [await getOne(sourceIDs[0])];
    }

    const { body } = await got(`${opts.api}videos`, {
      json: true,
      query: {
        limit: sourceIDs.length,
        ids: sourceIDs.join(','),
        fields: opts.fields.join(',')
      }
    });

    const videos = {};
    for (const video of body.list) {
      videos[video.id] = normalizeMedia(video);
    }

    return sourceIDs.map(id => videos[id]);
  }

  async function search(query, page = {}) {
    const id = getVideoID(query);
    if (id) {
      return [await getOne(id)];
    }

    const { body } = await got(`${opts.api}videos`, {
      json: true,
      query: {
        search: query,
        limit: 50,
        fields: opts.fields.join(',')
      }
    });
    return body.list.map(normalizeMedia);
  }

  return {
    get: get, // eslint-disable-line object-shorthand
    search
  };
}
<|endoftext|>


<commit_before>YUI.add("shaker/metaMojits", function(Y, NAME) {
YUI.namespace("_mojito._cache.shaker");
YUI._mojito._cache.shaker.meta =
{
	"mojits": {
		"ShakerHTMLFrameMojit": {
			"*": {
				"shaken": {
					"common": [],
					"common-action": [],
					"common-action-device": [],
					"common-action-device-skin": [],
					"common-action-device-skin-region": []
				},
				"meta": {
					"order": [
						"common-action-device-skin-region"
					],
					"dependencies": []
				}
			}
		},
		"master": {
			"*": {
				"shaken": {
					"common": [
						"../../shakerdemo/mojits/master/assets/common/master.css"
					],
					"common-action": [
						"../../shakerdemo/mojits/master/assets/common/master.css"
					],
					"common-action-smartphone": [
						"../../shakerdemo/mojits/master/assets/common/master.css",
						"../../shakerdemo/mojits/master/assets/device/smartphone/master-smartphone.css"
					],
					"common-action-device": [
						"../../shakerdemo/mojits/master/assets/common/master.css"
					],
					"common-action-smartphone-grey": [
						"../../shakerdemo/mojits/master/assets/common/master.css",
						"../../shakerdemo/mojits/master/assets/device/smartphone/master-smartphone.css",
						"../../shakerdemo/mojits/master/assets/skin/grey/master-grey.css"
					],
					"common-action-smartphone-skin": [
						"../../shakerdemo/mojits/master/assets/common/master.css",
						"../../shakerdemo/mojits/master/assets/device/smartphone/master-smartphone.css"
					],
					"common-action-device-grey": [
						"../../shakerdemo/mojits/master/assets/common/master.css",
						"../../shakerdemo/mojits/master/assets/skin/grey/master-grey.css"
					],
					"common-action-device-skin": [
						"../../shakerdemo/mojits/master/assets/common/master.css"
					]
				},
				"meta": {
					"order": [
						"common-action-device-skin-region"
					],
					"dependencies": []
				}
			}
		},
		"secondary": {
			"*": {
				"shaken": {
					"common": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css"
					],
					"common-action": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css"
					],
					"common-action-smartphone": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/device/smartphone/secondary-smartphone.css"
					],
					"common-action-device": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css"
					],
					"common-action-smartphone-grey": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/device/smartphone/secondary-smartphone.css",
						"../../shakerdemo/mojits/secondary/assets/skin/grey/secondary-grey.css"
					],
					"common-action-smartphone-skin": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/device/smartphone/secondary-smartphone.css"
					],
					"common-action-device-grey": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/skin/grey/secondary-grey.css"
					],
					"common-action-device-skin": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css"
					],
					"common-action-smartphone-grey-CA": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/device/smartphone/secondary-smartphone.css",
						"../../shakerdemo/mojits/secondary/assets/skin/grey/secondary-grey.css",
						"../../shakerdemo/mojits/secondary/assets/region/CA/secondary-CA.css"
					],
					"common-action-smartphone-grey-region": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/device/smartphone/secondary-smartphone.css",
						"../../shakerdemo/mojits/secondary/assets/skin/grey/secondary-grey.css"
					],
					"common-action-smartphone-skin-CA": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/device/smartphone/secondary-smartphone.css",
						"../../shakerdemo/mojits/secondary/assets/region/CA/secondary-CA.css"
					],
					"common-action-smartphone-skin-region": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/device/smartphone/secondary-smartphone.css"
					],
					"common-action-device-grey-CA": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/skin/grey/secondary-grey.css",
						"../../shakerdemo/mojits/secondary/assets/region/CA/secondary-CA.css"
					],
					"common-action-device-grey-region": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/skin/grey/secondary-grey.css"
					],
					"common-action-device-skin-CA": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css",
						"../../shakerdemo/mojits/secondary/assets/region/CA/secondary-CA.css"
					],
					"common-action-device-skin-region": [
						"../../shakerdemo/mojits/secondary/assets/common/secondary.css"
					]
				},
				"meta": {
					"order": [
						"common-action-device-skin-region"
					],
					"dependencies": []
				}
			}
		},
		"primary": {
			"*": {
				"shaken": {
					"common": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css"
					],
					"common-action": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css"
					],
					"common-action-device": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css"
					],
					"common-action-device-grey": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css",
						"../../shakerdemo/mojits/primary/assets/skin/grey/primary-grey.css"
					],
					"common-action-device-skin": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css"
					],
					"common-action-device-grey-CA": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css",
						"../../shakerdemo/mojits/primary/assets/skin/grey/primary-grey.css",
						"../../shakerdemo/mojits/primary/assets/region/CA/primary-CA.css"
					],
					"common-action-device-grey-region": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css",
						"../../shakerdemo/mojits/primary/assets/skin/grey/primary-grey.css"
					],
					"common-action-device-skin-CA": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css",
						"../../shakerdemo/mojits/primary/assets/region/CA/primary-CA.css"
					],
					"common-action-device-skin-region": [
						"../../shakerdemo/mojits/primary/assets/common/primary.css"
					]
				},
				"meta": {
					"order": [
						"common-action-device-skin-region"
					],
					"dependencies": []
				}
			}
		}
	},
	"app": {
		"*": {
			"shaken": {
				"common": [
					"../../shakerdemo/assets/common/utils.css",
					"../../shakerdemo/assets/common/yui-base.css",
					"../../shakerdemo/assets/common/yui-fonts.css",
					"../../shakerdemo/assets/common/yui-reset.css"
				],
				"common-action": [
					"../../shakerdemo/assets/common/utils.css",
					"../../shakerdemo/assets/common/yui-base.css",
					"../../shakerdemo/assets/common/yui-fonts.css",
					"../../shakerdemo/assets/common/yui-reset.css"
				],
				"common-action-device": [
					"../../shakerdemo/assets/common/utils.css",
					"../../shakerdemo/assets/common/yui-base.css",
					"../../shakerdemo/assets/common/yui-fonts.css",
					"../../shakerdemo/assets/common/yui-reset.css"
				],
				"common-action-device-skin": [
					"../../shakerdemo/assets/common/utils.css",
					"../../shakerdemo/assets/common/yui-base.css",
					"../../shakerdemo/assets/common/yui-fonts.css",
					"../../shakerdemo/assets/common/yui-reset.css"
				],
				"common-action-device-skin-region": [
					"../../shakerdemo/assets/common/utils.css",
					"../../shakerdemo/assets/common/yui-base.css",
					"../../shakerdemo/assets/common/yui-fonts.css",
					"../../shakerdemo/assets/common/yui-reset.css"
				]
			},
			"meta": {
				"order": [
					"common-action-device-skin-region"
				],
				"dependencies": []
			}
		}
	}
};

});<commit_msg>removed meta<commit_after><|endoftext|>


<commit_before>var Promise = require('bluebird');
var path = require('path');
var chalk = require('chalk');
var ncp = Promise.promisify(require('ncp').ncp);
var rename = Promise.promisify(require('fs').rename);
var fs = Promise.promisifyAll(require('fs'));
var finder = require('fs-finder');
var exec = require('child_process').exec;

ncp.limit = 16;

var newProjectDir = process.cwd();
var generatorFilesPath = path.join(__dirname, '../generated');

// rename files
// make a promise
var noDb = process.argv[2] === "nodb";

var renameNoDbFiles = function renameNoDbFiles() {
  var paths = finder.from(newProjectDir).findFiles('*.nodb*');
  var newPaths = [];

  for (var i = 0; i < paths.length; i++) {
      var oldPath = paths[i];
      var targetString = '.nodb';
      var startPos = oldPath.indexOf(targetString);
      var newPath = oldPath.slice(0, startPos) + oldPath.slice(startPos + targetString.length);
      newPaths.push(rename(oldPath, newPath));
  }

  return Promise.all(newPaths);
};

var removeDbFiles = function removeDbFiles() {
  return new Promise(function(resolve, reject) {
    exec('rm -r ./client/pre-build/modules/ ./seed.js ./server/api/ ./server/db.js', function(error, stdout, stderr) {
      if(error) return reject(stderr);
      else return resolve(stdout);
    });
  });
};

var removeNoDbFiles = function removeNoDbFiles() {
  return new Promise(function(resolve, reject) {
    exec('find . -type f -name "*.nodb*" -delete', function(error, stdout, stderr) {
      if(error) return reject(stderr);
      else return resolve(stdout);
    });
  });

};

var copyFiles = function () {
    return ncp(generatorFilesPath, newProjectDir);
};

var renameGitignore = function () {
    var oldPath = path.join(newProjectDir, 'gitignore.txt');
    var newPath = path.join(newProjectDir, '.gitignore');
    return rename(oldPath, newPath);
};

console.log(chalk.green('Meaniscule is generating your new miniscule MEAN stack app.'));
console.log(chalk.green('You\'ll be up and running in no time!'));

copyFiles()
.then(function() {
  if(noDb) {
    return renameNoDbFiles()
    .then(removeDbFiles);
  }
  else {
    return removeNoDbFiles();
  }
})
.then(renameGitignore)
.then(function () {
    console.log(chalk.green('Your app is ready!'));
    console.log(chalk.yellow('Run the following commands to get set up:'));
    console.log(chalk.white.bgBlack('- [Terminal 1] npm install '));
    console.log(chalk.white.bgBlack('- [Terminal 1] npm start   '));
    if(!noDb) console.log(chalk.white.bgBlack('- [Terminal 2] gulp seedDB '));
    console.log(chalk.white.bgBlack('- [Terminal 2] gulp        '));
})
.catch(function(err) {
    console.log(err);
});

<commit_msg>added an alternative set of execs for non POSIX, i.e. windows, systems<commit_after>var Promise = require('bluebird');
var path = require('path');
var chalk = require('chalk');
var ncp = Promise.promisify(require('ncp').ncp);
var rename = Promise.promisify(require('fs').rename);
var fs = Promise.promisifyAll(require('fs'));
var finder = require('fs-finder');
var exec = require('child_process').exec;
var isWin = (process.platform.indexOf('win32') != -1); //are we windowsing?

ncp.limit = 16;

var newProjectDir = process.cwd();
var generatorFilesPath = path.join(__dirname, '../generated');

// rename files
// make a promise
var noDb = process.argv[2] === "nodb";

var renameNoDbFiles = function renameNoDbFiles() {
    var paths = finder.from(newProjectDir).findFiles('*.nodb*');
    var newPaths = [];

    for (var i = 0; i < paths.length; i++) {
        var oldPath = paths[i];
        var targetString = '.nodb';
        var startPos = oldPath.indexOf(targetString);
        var newPath = oldPath.slice(0, startPos) + oldPath.slice(startPos + targetString.length);
        newPaths.push(rename(oldPath, newPath));
    }

    return Promise.all(newPaths);
};

var removeDbFiles = function removeDbFiles() {

    return new Promise(function(resolve, reject) {
        if (!isWin) {
            //user's POSIXy
            exec('rm -r ./client/pre-build/modules/ ./seed.js ./server/api/ ./server/db.js', function(error, stdout, stderr) {
                if (error) return reject(stderr);
                else return resolve(stdout);
            });
        } else {
            /*notes:
            cmd doesn't seem to like it when we delete without confirming, so /q says 'quiet mode'. In other words, delete without confirm.
            /s says delete whole tree (this folder and its contents)
            note BACKslash, not forward!
            If you're wondering "why the loops?",
            A) congrats, you don't suck @ programming, and
            B), Windows' rd (remove directory) command apparently does not allow deleting of multiple, independent loops.
            So instead, we delete each folder on its own.
            */
            exec('rd /s /q .\client\pre-build\modules', function(error, stdout, stderr) {
                if (error) return reject(stderr);
                exec('del /q seed.js .\server\db.js', function(error, stdout, stderr) {
                    if (error) return reject(stderr);
                    exec('rd .\server\api .\server\db.js', function(error, stdout, stderr) {
                        console.log(error, stdout, stderr)
                        if (error) return reject(stderr);
                        else return resolve(stdout);
                    });
                });
            });
        }
    });
};

var removeNoDbFiles = function removeNoDbFiles() {
    return new Promise(function(resolve, reject) {
        if (!isWin) {
            exec('find . -type f -name "*.nodb*" -delete', function(error, stdout, stderr) {
                if (error) return reject(stderr);
                else return resolve(stdout);
            });
        } else {
            //need to find way to do this in Win
            exec('del /s /q .\*.nodb*', function(error, stdout, stderr) {
                if (error) return reject(stderr);
                else return resolve(stdout);
            });
        }
    });
};

var copyFiles = function() {
    return ncp(generatorFilesPath, newProjectDir);
};

var renameGitignore = function() {
    var oldPath = path.join(newProjectDir, 'gitignore.txt');
    var newPath = path.join(newProjectDir, '.gitignore');
    return rename(oldPath, newPath);
};

console.log(chalk.green('Meaniscule is generating your new miniscule MEAN stack app.'));
console.log(chalk.green('You\'ll be up and running in no time!'));

copyFiles()
    .then(function() {
        if (noDb) {
            return renameNoDbFiles()
                .then(removeDbFiles);
        } else {
            return removeNoDbFiles();
        }
    })
    .then(renameGitignore)
    .then(function() {
        console.log(chalk.green('Your app is ready!'));
        console.log(chalk.yellow('Run the following commands to get set up:'));
        console.log(chalk.white.bgBlack('- [Terminal 1] npm install '));
        console.log(chalk.white.bgBlack('- [Terminal 1] npm start   '));
        if (!noDb) console.log(chalk.white.bgBlack('- [Terminal 2] gulp seedDB '));
        console.log(chalk.white.bgBlack('- [Terminal 2] gulp        '));
    })
    .catch(function(err) {
        console.log(err);
    });<|endoftext|>


<commit_before>import postcss from 'postcss';
import _ from 'lodash';
import {
	defaults,
	prepareFilterBy,
	prepareGroupBy,
	extractImages,
	applyFilterBy,
	applyGroupBy,
	setTokens,
	runSpritesmith,
	saveSpritesheets,
	mapSpritesheetProps,
	updateReferences
} from './core';

/**
 * Plugin registration.
 */
export default postcss.plugin('postcss-sprites', (opts = {}) => {
	return (css, result) => {
		// Extend defaults
		opts = _.merge({}, defaults, opts);

		// Prepare filter & group functions
		prepareFilterBy(opts, result);
		prepareGroupBy(opts);

		// Process it
		return extractImages(css, opts, result)
			.spread((opts, images) => applyFilterBy(opts, images))
			.spread((opts, images) => applyGroupBy(opts, images))
			.spread((opts, images) => setTokens(css, opts, images))
			.spread((root, opts, images) => runSpritesmith(opts, images))
			.spread((opts, images, spritesheets) => saveSpritesheets(opts, images, spritesheets))
			.spread((opts, images, spritesheets) => mapSpritesheetProps(opts, images, spritesheets))
			.spread((opts, images, spritesheets) => updateReferences(css, opts, images, spritesheets))
			.spread((root, opts, images, spritesheets) => {
				result.warn(`${spritesheets.length} ${spritesheets.length > 1 ? 'spritesheets' : 'spritesheet'} generated.`);
			})
			.catch((err) => {
				console.error(`postcss-sprites: An error occurred while processing files - ${err.message}`);
				console.error(err.stack);
				throw err;
			});
	}
});
<commit_msg>Fix options merging<commit_after>import postcss from 'postcss';
import _ from 'lodash';
import {
	defaults,
	prepareFilterBy,
	prepareGroupBy,
	extractImages,
	applyFilterBy,
	applyGroupBy,
	setTokens,
	runSpritesmith,
	saveSpritesheets,
	mapSpritesheetProps,
	updateReferences
} from './core';

/**
 * Plugin registration.
 */
export default postcss.plugin('postcss-sprites', (options = {}) => {
	return (css, result) => {
		// Extend defaults
		const opts = _.merge({}, defaults, options);

		// Prepare filter & group functions
		prepareFilterBy(opts, result);
		prepareGroupBy(opts);

		// Process it
		return extractImages(css, opts, result)
			.spread((opts, images) => applyFilterBy(opts, images))
			.spread((opts, images) => applyGroupBy(opts, images))
			.spread((opts, images) => setTokens(css, opts, images))
			.spread((root, opts, images) => runSpritesmith(opts, images))
			.spread((opts, images, spritesheets) => saveSpritesheets(opts, images, spritesheets))
			.spread((opts, images, spritesheets) => mapSpritesheetProps(opts, images, spritesheets))
			.spread((opts, images, spritesheets) => updateReferences(css, opts, images, spritesheets))
			.spread((root, opts, images, spritesheets) => {
				result.warn(`${spritesheets.length} ${spritesheets.length > 1 ? 'spritesheets' : 'spritesheet'} generated.`);
			})
			.catch((err) => {
				console.error(`postcss-sprites: An error occurred while processing files - ${err.message}`);
				console.error(err.stack);
				throw err;
			});
	}
});
<|endoftext|>


<commit_before>import AtomControl from './components/AtomControl';
import CardControl from './components/CardControl';
import { classToDOMCard } from './utils/classToCard';
import Container, { EMPTY_MOBILEDOC } from './components/Container';
import DropWrapper from './components/DropWrapper';
import Editor from './components/Editor';
import LinkControl from './components/LinkControl';
import LinkForm from './components/LinkForm';
import MarkupControl from './components/MarkupControl';
import SectionControl from './components/SectionControl';
import Toolbar from './components/Toolbar';

export {
  AtomControl,
  CardControl,
  classToDOMCard,
  Container,
  DropWrapper,
  Editor,
  EMPTY_MOBILEDOC,
  LinkControl,
  LinkForm,
  MarkupControl,
  SectionControl,
  Toolbar
};
<commit_msg>Remove drop wrapper from exports<commit_after>import AtomControl from './components/AtomControl';
import CardControl from './components/CardControl';
import { classToDOMCard } from './utils/classToCard';
import Container, { EMPTY_MOBILEDOC } from './components/Container';
import Editor from './components/Editor';
import LinkControl from './components/LinkControl';
import LinkForm from './components/LinkForm';
import MarkupControl from './components/MarkupControl';
import SectionControl from './components/SectionControl';
import Toolbar from './components/Toolbar';

export {
  AtomControl,
  CardControl,
  classToDOMCard,
  Container,
  Editor,
  EMPTY_MOBILEDOC,
  LinkControl,
  LinkForm,
  MarkupControl,
  SectionControl,
  Toolbar
};
<|endoftext|>


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

require('colorful').colorful();
var List = require('prompt-list');
var rimraf = require('rimraf');

var path = require('path');
var ora = require('ora');
var home = require('user-home');
var program = require('commander');
var logger = require('../src/logger');
var generate = require('../src/util/generate');
var download = require('download-git-repo');

program
  .usage('<project-name> <git-url>')
  .parse(process.argv);

program.on('--help', function () {
  console.log()
  console.log('    # create a new project with a template')
  console.log('    - template: Simple');
  console.log('    - template: HeyUI');
  console.log('    - template: Vue');
  console.log('    - template: React');
  console.log('    - template: ElementUI');
  console.log('    - template: iViewUI');
  console.log()
  console.log('    # create a new project with github');
  console.log('    - hey init test heyui/hey-cli-template');
  console.log()
})

function help() {
  program.parse(process.argv)
  if (program.args.length < 1) return program.help()
}
help()

var rawName = program.args[0];
var gitUrl = program.args[1];

function dl(template, tmplType) {
  var inPlace = !rawName || rawName === '.';
  var name = inPlace ? path.relative('../', process.cwd()) : rawName;
  var tmp = path.join(home, '.hey-cli', template);
  rimraf(tmp, () => {
    var to = path.resolve(rawName || '.');
    var spinner = ora('downloading template....')
    spinner.start()
    download(template, tmp, { clone: false }, function (err) {
      spinner.stop()
      if (err){
        logger.fatal('Failed to download repo ' + template + ': ' + err.message.trim())
        return;
      }
      generate(name, tmplType, tmp, to, function (err) {
        if (err) logger.fatal(err)
        logger.info('Project %s generation success.', name);
        console.log('====================================');
        console.log('  cd %s', name);
        if(gitUrl) {
          console.log('');
          console.log('  If this is a webpack project, please use use the following commands: ');
          console.log('');
        }
        console.log('  npm install');
        console.log('  hey dev');
        console.log('====================================');
      })
    })
  })

}

if(!gitUrl) {
  var enquirer = new List({
    name: 'Templates',
    message: 'Which template would you like to choose?',
    choices: [
      'Simple',
      'HeyUI',
      'Vue',
      'React',
      'ElementUI',
      'iViewUI'
    ]
  });

  enquirer.run()
  .then(function(answers) {
    logger.info('Use Template ' + answers);
    // download template
    var tmplType = answers.toLowerCase();
    dl('heyui/hey-cli-template', tmplType);
  })
  .catch(function(err) {
    console.log(err);
  });
} else {
  dl(gitUrl, '');
}
<commit_msg>feat: Add HeyAdmin template<commit_after>#!/usr/bin/env node

require('colorful').colorful();
var List = require('prompt-list');
var rimraf = require('rimraf');

var path = require('path');
var ora = require('ora');
var home = require('user-home');
var program = require('commander');
var logger = require('../src/logger');
var generate = require('../src/util/generate');
var download = require('download-git-repo');

program
  .usage('<project-name> <git-url>')
  .parse(process.argv);

program.on('--help', function () {
  console.log()
  console.log('    # create a new project with a template')
  console.log('    - template: Simple');
  console.log('    - template: HeyUI');
  console.log('    - template: HeyAdmin');
  console.log('    - template: Vue');
  console.log('    - template: React');
  console.log('    - template: ElementUI');
  console.log('    - template: iViewUI');
  console.log()
  console.log('    # create a new project with github');
  console.log('    - hey init test heyui/hey-cli-template');
  console.log()
})

function help() {
  program.parse(process.argv)
  if (program.args.length < 1) return program.help()
}
help()

var rawName = program.args[0];
var gitUrl = program.args[1];

function dl(template, tmplType) {
  var inPlace = !rawName || rawName === '.';
  var name = inPlace ? path.relative('../', process.cwd()) : rawName;
  var tmp = path.join(home, '.hey-cli', template);
  rimraf(tmp, () => {
    var to = path.resolve(rawName || '.');
    var spinner = ora('downloading template....')
    spinner.start()
    download(template, tmp, { clone: false }, function (err) {
      spinner.stop()
      if (err){
        logger.fatal('Failed to download repo ' + template + ': ' + err.message.trim())
        return;
      }
      generate(name, tmplType, tmp, to, function (err) {
        if (err) logger.fatal(err)
        logger.info('Project %s generation success.', name);
        console.log('====================================');
        console.log('  cd %s', name);
        if(gitUrl) {
          console.log('');
          console.log('  If this is a webpack project, please use use the following commands: ');
          console.log('');
        }
        console.log('  npm install');
        console.log('  hey dev');
        console.log('====================================');
      })
    })
  })

}

if(!gitUrl) {
  var enquirer = new List({
    name: 'Templates',
    message: 'Which template would you like to choose?',
    choices: [
      'Simple',
      'HeyUI',
      'HeyAdmin',
      'Vue',
      'React',
      'ElementUI',
      'iViewUI'
    ]
  });

  enquirer.run()
  .then(function(answers) {
    logger.info('Use Template ' + answers);
    // download template
    var tmplType = answers.toLowerCase();
    dl('heyui/hey-cli-template', tmplType);
  })
  .catch(function(err) {
    console.log(err);
  });
} else {
  dl(gitUrl, '');
}
<|endoftext|>


<commit_before>import React from 'react';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import CustomDate from '../../util/CustomDate';
import { Segment,Item,Icon,Label,Image, TextArea} from 'semantic-ui-react';
import ISO6391 from 'iso-639-1';
import {Microservices} from '../../../../configs/microservices';
import updateSelectedDeck  from '../../../../actions/attachSubdeck/updateSelectedDeck';

class AttachDeckList extends React.Component {
    constructor(props){
        /* Receives:
          user: user info
          decks: array with the decks to showSlides
          selectedDeckId: initial selected deck...if it was previosly selected
          destinationDeckId: deck in which data will be appended.
          actionButtonId: buttonId which receives the focus. It was not possible to use ref to do that.

        */
        super(props);

        this.state = {
            selectedDeckId: this.props.selectedDeckId,
        };
    }

    handleOnclick(selectedDeck){

        this.setState({
            selectedItem:selectedDeck.keyIndex,
            selectedDeckId:selectedDeck.selectedDeckId
        });
        let payload ={
            selectedDeckId:selectedDeck.selectedDeckId,
            selectedDeckTitle:selectedDeck.selectedDeckTitle
        };
        this.context.executeAction(updateSelectedDeck,payload,null);

        $(this.props.actionButtonId).focus();

    }
    handleKeyPress(event,selectedDeck){

        if(event.key === 'Enter'){
            event.preventDefault();
            this.handleOnclick(selectedDeck);
        }
    }

    render() {

        let decks_to_show = this.props.decks;
        let deck_list;
        let activeItemStyle = {
            backgroundColor:'#f8ffff',
            color:'#2185d0'

        };
       //Order decks by updated data
        decks_to_show = decks_to_show.sort((a,b) => new Date(b.updated).getTime() - new Date(a.updated).getTime());

        if (decks_to_show.length){
            deck_list =
                decks_to_show.map((deck, index) => {

                    if(this.props.destinationDeckId.toString() !== deck.deckID.toString()){
                      //From deck users, data is in props.user. From slideWiki, data is in the deck
                        let deckCreatorid = deck.deckCreatorid === undefined ? this.props.user.userId : deck.deckCreatorid;
                        let deckCreator = deck.deckCreator === undefined ? this.props.user.username:deck.deckCreator;

                        let deckDate = CustomDate.format(deck.creationDate, 'Do MMMM YYYY');
                        let deckLanguageCode = deck.language === undefined ? 'en' : deck.language;
                        let deckLanguage = deckLanguageCode === undefined ? '' : ISO6391.getName(deckLanguageCode);
                        // default English
                        deckLanguage = (deckLanguage === '' ? 'English' : deckLanguage);
                        //let countryFlag = deckLanguageCode === 'en' ? 'gb' : deckLanguageCode;
                        let deckTheme = deck.theme === undefined ? 'Simple' : deck.theme;
                        let selectedDeck = {
                            selectedDeckTitle:deck.title,
                            selectedDeckId: deck.deckID+'-'+deck.countRevisions
                        };
                        return (
                           <Item key={index}
                                  onClick={this.handleOnclick.bind(this,selectedDeck)}
                                  onKeyPress={(e) => { this.handleKeyPress(e,selectedDeck);}}
                                  style ={this.state.selectedDeckId === selectedDeck.selectedDeckId ?activeItemStyle:{}}
                                  role="listitem"
                                  aria-selected ={this.state.selectedDeckId === selectedDeck.selectedDeckId}
                                  tabIndex="0">
                                <Item.Image src={Microservices.file.uri + '/slideThumbnail/' +deck.firstSlide+'.jpeg'} size="small"/>
                                <Item.Content verticalAlign="middle" >
                                  <Item.Header style ={this.state.selectedDeckId === selectedDeck.selectedDeckId ?activeItemStyle:{}}>
                                      {deck.title}
                                  </Item.Header>

                                  <Item.Meta>
                                    Creator: {deckCreator}

                                    Date: {deckDate}
                                  </Item.Meta>

                                 <Item.Extra>

                                      <Icon name="comments outline" aria-label="Language"/>
                                      {deckLanguage}

                                       <Icon name="fork" aria-label="Number of versions"/>
                                       {deck.countRevisions}

                                 </Item.Extra>
                                </Item.Content>
                            </Item>

                        );
                    }
                });
        }

        return (
          <Item.Group divided relaxed style={{maxHeight:this.props.maxHeight,minHeight:'320px',overflowY:'auto'}}
             role="listbox" aria-expanded="true"  aria-describedby="listInstructions">
             <TextArea className="sr-only" id="listInstructions" value="Use tab to navigate through the list and then enter to select a deck." tabIndex ='-1'/>

                {deck_list}
          </Item.Group>
        );
    }
}

AttachDeckList.contextTypes = {
    executeAction: React.PropTypes.func.isRequired
};

export default AttachDeckList;
<commit_msg>SWIK-1447-MoveAcrossGrid Added the title of each deck as the tag of each image in the deck list<commit_after>import React from 'react';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import CustomDate from '../../util/CustomDate';
import { Segment,Item,Icon,Label,Image, TextArea} from 'semantic-ui-react';
import ISO6391 from 'iso-639-1';
import {Microservices} from '../../../../configs/microservices';
import updateSelectedDeck  from '../../../../actions/attachSubdeck/updateSelectedDeck';

class AttachDeckList extends React.Component {
    constructor(props){
        /* Receives:
          user: user info
          decks: array with the decks to showSlides
          selectedDeckId: initial selected deck...if it was previosly selected
          destinationDeckId: deck in which data will be appended.
          actionButtonId: buttonId which receives the focus. It was not possible to use ref to do that.

        */
        super(props);

        this.state = {
            selectedDeckId: this.props.selectedDeckId,
        };
    }

    handleOnclick(selectedDeck){

        this.setState({
            selectedItem:selectedDeck.keyIndex,
            selectedDeckId:selectedDeck.selectedDeckId
        });
        let payload ={
            selectedDeckId:selectedDeck.selectedDeckId,
            selectedDeckTitle:selectedDeck.selectedDeckTitle
        };
        this.context.executeAction(updateSelectedDeck,payload,null);

        $(this.props.actionButtonId).focus();

    }
    handleKeyPress(event,selectedDeck){

        if(event.key === 'Enter'){
            event.preventDefault();
            this.handleOnclick(selectedDeck);
        }
    }

    render() {

        let decks_to_show = this.props.decks;
        let deck_list;
        let activeItemStyle = {
            backgroundColor:'#f8ffff',
            color:'#2185d0'

        };
       //Order decks by updated data
        decks_to_show = decks_to_show.sort((a,b) => new Date(b.updated).getTime() - new Date(a.updated).getTime());

        if (decks_to_show.length){
            deck_list =
                decks_to_show.map((deck, index) => {

                    if(this.props.destinationDeckId.toString() !== deck.deckID.toString()){
                      //From deck users, data is in props.user. From slideWiki, data is in the deck
                        let deckCreatorid = deck.deckCreatorid === undefined ? this.props.user.userId : deck.deckCreatorid;
                        let deckCreator = deck.deckCreator === undefined ? this.props.user.username:deck.deckCreator;

                        let deckDate = CustomDate.format(deck.creationDate, 'Do MMMM YYYY');
                        let deckLanguageCode = deck.language === undefined ? 'en' : deck.language;
                        let deckLanguage = deckLanguageCode === undefined ? '' : ISO6391.getName(deckLanguageCode);
                        // default English
                        deckLanguage = (deckLanguage === '' ? 'English' : deckLanguage);
                        //let countryFlag = deckLanguageCode === 'en' ? 'gb' : deckLanguageCode;
                        let deckTheme = deck.theme === undefined ? 'Simple' : deck.theme;
                        let selectedDeck = {
                            selectedDeckTitle:deck.title,
                            selectedDeckId: deck.deckID+'-'+deck.countRevisions
                        };
                        return (
                           <Item key={index}
                                  onClick={this.handleOnclick.bind(this,selectedDeck)}
                                  onKeyPress={(e) => { this.handleKeyPress(e,selectedDeck);}}
                                  style ={this.state.selectedDeckId === selectedDeck.selectedDeckId ?activeItemStyle:{}}
                                  role="listitem"
                                  aria-selected ={this.state.selectedDeckId === selectedDeck.selectedDeckId}
                                  tabIndex="0">
                                <Item.Image src={Microservices.file.uri + '/slideThumbnail/' +deck.firstSlide+'.jpeg'} alt={deck.title} size="small"/>
                                <Item.Content verticalAlign="middle" >
                                  <Item.Header style ={this.state.selectedDeckId === selectedDeck.selectedDeckId ?activeItemStyle:{}}>
                                      {deck.title}
                                  </Item.Header>

                                  <Item.Meta>
                                    Creator: {deckCreator}

                                    Date: {deckDate}
                                  </Item.Meta>

                                 <Item.Extra>

                                      <Icon name="comments outline" aria-label="Language"/>
                                      {deckLanguage}

                                       <Icon name="fork" aria-label="Number of versions"/>
                                       {deck.countRevisions}

                                 </Item.Extra>
                                </Item.Content>
                            </Item>

                        );
                    }
                });
        }

        return (
          <Item.Group divided relaxed style={{maxHeight:this.props.maxHeight,minHeight:'320px',overflowY:'auto'}}
             role="listbox" aria-expanded="true"  aria-describedby="listInstructions">
             <TextArea className="sr-only" id="listInstructions" value="Use tab to navigate through the list and then enter to select a deck." tabIndex ='-1'/>

                {deck_list}
          </Item.Group>
        );
    }
}

AttachDeckList.contextTypes = {
    executeAction: React.PropTypes.func.isRequired
};

export default AttachDeckList;
<|endoftext|>


<commit_before>function Player(x, y) {
    this.x = x;
    this.y = y;
    this.z = null;
    this.shapes = [];
    for(var i = 0; i < 4; i++) {
        this.shapes.push(ZilShape.load_shape("creatures", "player2", i));
    }
    this.last_x = x;
    this.last_y = y;
    this.shape_index = 2;
    this.shape = this.shapes[this.shape_index];
}

Player.prototype.move_to = function(map_shape, nx, ny, nz) {
    this.remove(map_shape);
    this.x = nx;
    this.y = ny;
    this.z = nz;
    if(this.x > this.last_x) this.set_shape(ZIL_UTIL.W);
    else if(this.x < this.last_x) this.set_shape(ZIL_UTIL.E);
    else if(this.y > this.last_y) this.set_shape(ZIL_UTIL.N);
    else if(this.y < this.last_y) this.set_shape(ZIL_UTIL.S);
    this.last_x = this.x;
    this.last_y = this.y;
    this.move(map_shape);
};

Player.prototype.set_shape = function(index) {
    this.shape_index = index;
    this.shape = this.shapes[this.shape_index];
};

Player.prototype.remove = function(map_shape) {
    map_shape.del_shape(this.x, this.y, this.z, this.shape);
};

Player.prototype.move = function(map_shape) {
    if(this.z == null) this.z = map_shape.get_highest_empty_space(this.x, this.y, this.shape);
    map_shape.set_shape(this.x, this.y, this.z, this.shape);
};
<commit_msg>rotate player when moving in a direction<commit_after>function Player(x, y) {
    this.x = x;
    this.y = y;
    this.z = null;
    this.shapes = [];
    for(var i = 0; i < 4; i++) {
        this.shapes.push(ZilShape.load_shape("creatures", "player2", i));
    }
    this.last_x = x;
    this.last_y = y;
    this.shape_index = 2;
    this.shape = this.shapes[this.shape_index];
}

Player.prototype.move_to = function(map_shape, nx, ny, nz) {
    this.remove(map_shape);
    this.x = nx;
    this.y = ny;
    this.z = nz;

    // todo: add smooth rotation here...
    if(this.x > this.last_x) this.set_shape(ZIL_UTIL.W);
    else if(this.x < this.last_x) this.set_shape(ZIL_UTIL.E);
    else if(this.y > this.last_y) this.set_shape(ZIL_UTIL.N);
    else if(this.y < this.last_y) this.set_shape(ZIL_UTIL.S);
    this.last_x = this.x;
    this.last_y = this.y;
    this.move(map_shape);
};

Player.prototype.set_shape = function(index) {
    this.shape_index = index;
    this.shape = this.shapes[this.shape_index];
};

Player.prototype.remove = function(map_shape) {
    map_shape.del_shape(this.x, this.y, this.z, this.shape);
};

Player.prototype.move = function(map_shape) {
    if(this.z == null) this.z = map_shape.get_highest_empty_space(this.x, this.y, this.shape);
    map_shape.set_shape(this.x, this.y, this.z, this.shape);
};
<|endoftext|>


<commit_before>var _ = require('lodash');
var λ = require('contra');
var url = require('url');
var path = require('path');
var http = require('http');
var levelup = require('levelup');
var evalRule = require('./evalRule');
var HttpHashRouter = require('http-hash-router');
var queryRulesetFn = require('./queryRulesetFn');
var selectRulesToEval = require('./selectRulesToEval');

var db = levelup(path.resolve(__dirname, '../db'), {
  keyEncoding: require('bytewise'),
  valueEncoding: 'json'
});

var port = process.env.PORT || 8080;

var router = HttpHashRouter();

var rulesets = {
  'rid1x0': require('./rulesets/hello_world'),
  'rid2x0': require('./rulesets/store_name')
};

var picos = {
  'pico1': {
    id: 'pico1',
    rulesets: ['rid1x0', 'rid2x0'],
    channels: ['chan0']
  }
};

var getPicoByECI = function(eci){
  return _.find(picos, function(pico){
    return _.includes(pico.channels, eci);
  });
};

var errResp = function(res, err){
  res.statusCode = err.statusCode || 500;
  res.end(err.message);
};

router.set('/sky/event/:eci/:eid/:domain/:type', function(req, res, route){
  var event = {
    eci: route.params.eci,
    eid: route.params.eid,
    domain: route.params.domain,
    type: route.params.type,
    attrs: route.data
  };
  var pico = getPicoByECI(event.eci);

  selectRulesToEval(picos, rulesets, event, function(err, to_eval){
    if(err) return errResp(res, err);

    λ.map(to_eval, function(e, callback){

      var ctx = {
        pico: pico,
        db: db,
        vars: {},
        event: event,
        meta: {
          rule_name: e.rule_name,
          txn_id: 'TODO',//TODO transactions
          rid: e.rid,
          eid: event.eid
        }
      };

      evalRule(e.rule, ctx, callback);

    }, function(err, directives){
      if(err) return errResp(res, err);
      res.end(JSON.stringify({
        directives: directives
      }, undefined, 2));
    });
  });
});

router.set('/sky/cloud/:rid/:function', function(req, res, route){
  var eci = route.data['_eci'];
  var rid = route.params.rid;
  var args = _.omit(route.data, '_eci');
  var fn_name = route.params['function'];

  var pico = getPicoByECI(eci);
  if(!pico){
    return errResp(res, new Error('Bad eci'));
  }
  if(!_.includes(pico.rulesets, rid)){
    return errResp(res, new Error('Pico does not have that rid'));
  }

  var ctx = {
    pico: pico,
    db: db,
    rid: rid,
    fn_name: fn_name,
    args: args
  };

  queryRulesetFn(ctx, rulesets, function(err, data){
    if(err) return errResp(res, err);
    res.end(JSON.stringify(data, undefined, 2));
  });
});

var server = http.createServer(function(req, res){
  router(req, res, {
    data: url.parse(req.url, true).query
  }, function(err){
    if(err){
      errResp(res, err);
    }
  });
});

server.listen(port, function(){
  console.log('http://localhost:' + server.address().port);
});
<commit_msg>page to dump out db contents<commit_after>var _ = require('lodash');
var λ = require('contra');
var url = require('url');
var path = require('path');
var http = require('http');
var levelup = require('levelup');
var evalRule = require('./evalRule');
var HttpHashRouter = require('http-hash-router');
var queryRulesetFn = require('./queryRulesetFn');
var selectRulesToEval = require('./selectRulesToEval');

var db = levelup(path.resolve(__dirname, '../db'), {
  keyEncoding: require('bytewise'),
  valueEncoding: 'json'
});

var port = process.env.PORT || 8080;

var router = HttpHashRouter();

var rulesets = {
  'rid1x0': require('./rulesets/hello_world'),
  'rid2x0': require('./rulesets/store_name')
};

var picos = {
  'pico1': {
    id: 'pico1',
    rulesets: ['rid1x0', 'rid2x0'],
    channels: ['chan0']
  }
};

var getPicoByECI = function(eci){
  return _.find(picos, function(pico){
    return _.includes(pico.channels, eci);
  });
};

var errResp = function(res, err){
  res.statusCode = err.statusCode || 500;
  res.end(err.message);
};

router.set('/sky/event/:eci/:eid/:domain/:type', function(req, res, route){
  var event = {
    eci: route.params.eci,
    eid: route.params.eid,
    domain: route.params.domain,
    type: route.params.type,
    attrs: route.data
  };
  var pico = getPicoByECI(event.eci);

  selectRulesToEval(picos, rulesets, event, function(err, to_eval){
    if(err) return errResp(res, err);

    λ.map(to_eval, function(e, callback){

      var ctx = {
        pico: pico,
        db: db,
        vars: {},
        event: event,
        meta: {
          rule_name: e.rule_name,
          txn_id: 'TODO',//TODO transactions
          rid: e.rid,
          eid: event.eid
        }
      };

      evalRule(e.rule, ctx, callback);

    }, function(err, directives){
      if(err) return errResp(res, err);
      res.end(JSON.stringify({
        directives: directives
      }, undefined, 2));
    });
  });
});

router.set('/sky/cloud/:rid/:function', function(req, res, route){
  var eci = route.data['_eci'];
  var rid = route.params.rid;
  var args = _.omit(route.data, '_eci');
  var fn_name = route.params['function'];

  var pico = getPicoByECI(eci);
  if(!pico){
    return errResp(res, new Error('Bad eci'));
  }
  if(!_.includes(pico.rulesets, rid)){
    return errResp(res, new Error('Pico does not have that rid'));
  }

  var ctx = {
    pico: pico,
    db: db,
    rid: rid,
    fn_name: fn_name,
    args: args
  };

  queryRulesetFn(ctx, rulesets, function(err, data){
    if(err) return errResp(res, err);
    res.end(JSON.stringify(data, undefined, 2));
  });
});

router.set('/', function(req, res, route){
  var html = '';
  html += '<pre>';
  db.createReadStream()
    .on('data', function (data) {
      html += JSON.stringify(data.key) + ' ->\n';
      html += '    ' + JSON.stringify(data.value) + '\n\n';
    })
    .on('end', function () {
      html += '</pre>';
      res.end(html);
    });
});

var server = http.createServer(function(req, res){
  router(req, res, {
    data: url.parse(req.url, true).query
  }, function(err){
    if(err){
      errResp(res, err);
    }
  });
});

server.listen(port, function(){
  console.log('http://localhost:' + server.address().port);
});
<|endoftext|>


<commit_before>var url = require('url')
var dashButton = require('node-dash-button');
var request = require('request')

function DasherButton(button) {
  var options = {headers: button.headers, body: button.body, json: button.json}

  this.dashButton = dashButton(button.address, button.interface)

  this.dashButton.on("detected", function() {
    console.log(button.name + " pressed.")
    doRequest(button.url, button.method, options)
  })

  console.log(button.name + " added.")
}

function doRequest(requestUrl, method, options, callback) {
  options = options || {}
  options.query = options.query || {}
  options.json = options.json || false
  options.headers = options.headers || {}

  var reqOpts = {
    url: url.parse(requestUrl),
    method: method || 'GET',
    qs: options.query,
    body: options.body,
    json: options.json,
    headers: options.headers
  }

  request(reqOpts, function onResponse(error, response, body) {
    if (error) {
      console.log("there was an error");
      console.log(error);
    }
    if (response.statusCode === 401) {
      console.log("Not authenticated");
      console.log(error);
    }
    if (response.statusCode !== 200) {
      console.log("Not a 200");
      console.log(error);
    }

    if (callback) {
      callback(error, response, body)
    }
  })
}

module.exports = DasherButton
<commit_msg>Add check for nil response<commit_after>var url = require('url')
var dashButton = require('node-dash-button');
var request = require('request')

function DasherButton(button) {
  var options = {headers: button.headers, body: button.body, json: button.json}

  this.dashButton = dashButton(button.address, button.interface)

  this.dashButton.on("detected", function() {
    console.log(button.name + " pressed.")
    doRequest(button.url, button.method, options)
  })

  console.log(button.name + " added.")
}

function doRequest(requestUrl, method, options, callback) {
  options = options || {}
  options.query = options.query || {}
  options.json = options.json || false
  options.headers = options.headers || {}

  var reqOpts = {
    url: url.parse(requestUrl),
    method: method || 'GET',
    qs: options.query,
    body: options.body,
    json: options.json,
    headers: options.headers
  }

  request(reqOpts, function onResponse(error, response, body) {
    if (error) {
      console.log("there was an error");
      console.log(error);
    }
    if (response && response.statusCode === 401) {
      console.log("Not authenticated");
      console.log(error);
    }
    if (response && response.statusCode !== 200) {
      console.log("Not a 200");
      console.log(error);
    }

    if (callback) {
      callback(error, response, body)
    }
  })
}

module.exports = DasherButton
<|endoftext|>