<commit_before>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

define(function (require, exports, module) {
    "use strict";

    // Dependencies
    var $ = require('jquery'),
        _ = require('underscore'),
        Backbone = require('backbone'),
        moment = require('moment'),
        ListModel = require('models/list'),
        DetailsTemplate = require('text!templates/lists/details.html'),
        LinksManagerView = require('views/links/manager'),
        PictureManagerView = require('views/pictures/manager'),
        state = require('state'),
        User = require('models/user'),
        user = new User();

    require('bootstrap');
    require('ckeditor-core');
    require('datepicker');
    require('datepicker-lang-no');

    // Module
    return Backbone.View.extend({

        template: _.template(DetailsTemplate),

        availableTags: [
            'SjekkUTDev'
        ],

        el: '[data-view="list-details"]',

        bindings: {
            '[name="list-details-field-navn"]': {
                observe: 'navn'
            },
            '[name="list-details-field-url"]': {
                observe: 'url'
            },
            '[name="list-details-field-beskrivelse"]': {
                observe: 'beskrivelse'
            },
            '[name="list-details-field-start"]': {
                observe: 'start',
                onGet: function(value) {
                    if (value) {
                        return moment(value).format('DD.MM.YYYY');
                    }
                },
                onSet: function(value) {
                    if (value) {
                        return moment(value, 'DD.MM.YYYY').toISOString();
                    }
                }
            },
            '[name="list-details-field-stopp"]': {
                observe: 'stopp',
                onGet: function(value) {
                    if (value) {
                        return moment(value).format('DD.MM.YYYY');
                    }
                },
                onSet: function(value) {
                    if (value) {
                        return moment(value, 'DD.MM.YYYY').toISOString();
                    }
                }
            },
            '[name="list-details-field-kategori"]': {
                observe: 'tags',
                setOptions: {
                    validate: true
                },
                onGet: function(value) {
                    // onGet called after tags change, and returns the first value in the array
                    return value[0];
                },
                onSet: function(value) {
                    // When input field value changes, set tags to an array with the
                    return [value];
                }
            }
        },

        events: {},

        initialize: function (options) {

            this.model = options.list || new ListModel();

            this.model.on('change:navn', this.updateListNamePlaceholders, this);
            this.model.on('sync', this.render, this);

            this.editor = options.editor;
            this.user = user;

        },

        render: function () {

            var html = this.template({
                model: this.model.toJSON(),
                availableTags: this.availableTags
            });
            this.$el.html(html);

            // Beskrivelse
            this.setupCkeditor();

            // Dates
            $('input[name="list-details-field-start"]').datepicker({
                forceParse: false, // AFAICS forceparse fails and causes existing date to be cleared when picker is dismissed
                format: 'dd.mm.yyyy',
                weekStart: 1,
                startDate: moment().format('DD.MM.YYYY'),
                language: 'no'
            });
            $('input[name="list-details-field-stopp"]').datepicker({
                forceParse: false, // AFAICS forceparse fails and causes existing date to be cleared when picker is dismissed
                format: 'dd.mm.yyyy',
                weekStart: 1,
                startDate: moment().format('DD.MM.YYYY'),
                language: 'no'
            });

            // Links Manager
            var linksManagerView = new LinksManagerView({
                model: this.model,
                linksField: 'lenker',
                el: '[data-view="list-details-lenker"]'
            }).render();

            // Pictures manager
            this.pictureManagerView = new PictureManagerView({
                el: '[data-view="list-pictures"]',
                pictures: this.model.bilder,
                stripped: true,
                messages: {
                    empty: 'Husk å legge inn bilder.',
                    info: 'Det første bildet vil bli brukt som hovedbilde og det andre vil bli brukt som bakgrunnsbilde i SjekkUT-appen.'
                },
                defaults: {
                    status: 'Offentlig'
                }
            }).render();

            this.setupGrupperSelect();

            // Set up view bindings and validation
            this.stickit(); // Uses view.bindings and view.model to setup bindings
            Backbone.Validation.bind(this);

            return this;

        },

        remove: function() {
            // Remove the validation binding
            // See: http://thedersen.com/projects/backbone-validation/#using-form-model-validation/unbinding
            Backbone.Validation.unbind(this);
            return Backbone.View.prototype.remove.apply(this, arguments);
        },

        setupCkeditor: function () {
            var descriptionEditor = CKEDITOR.replace($('textarea[name="list-details-field-beskrivelse"]')[0], {
                language: 'no',
                // Define the toolbar groups as it is a more accessible solution.
                toolbarGroups: [
                    {name: 'basicstyles', groups: ['basicstyles']},
                    {name: 'paragraph', groups: ['list']},
                    {name: 'styles', groups: ['styles']},
                    {name: 'links'}
                ],
                format_tags: 'p;h2;h3',
                // Remove the redundant buttons from toolbar groups defined above.
                removeButtons: 'Subscript,Superscript,Strike,Styles',
                // Remove elements path in footer
                removePlugins: 'elementspath',
                // Whether to use HTML entities in the output.
                entities: false
            });

            descriptionEditor.on('change', $.proxy(function (e) {
                var data = e.editor.getData();
                this.model.set('beskrivelse', data);
            }, this));
        },

        setupGrupperSelect: function () {
            var userGroups = user.get('grupper');
            if (userGroups.length > 0) {
                var select2Groups = [];

                for (var j = 0; j < userGroups.length; j++) {
                    select2Groups[j] = {};
                    select2Groups[j].id = userGroups[j].object_id;
                    select2Groups[j].text = userGroups[j].navn;
                }

                $('input[name="list-details-field-grupper"]').select2({
                    tags: select2Groups,
                    createSearchChoice: function () { return null; } // This will prevent the user from entering custom tags
                }).on('change', $.proxy(function (e) {
                    var routeGroups = e.val;
                    this.model.set('grupper', routeGroups);
                }, this));

                this.$('[name="list-details-field-grupper"]').select2('val', this.model.get('grupper'));

            } else {
                // If user does not belong to any groups, do not show groups field.
                this.$('.form-group.list-details-field-grupper').remove();
            }
        }

    });
});
<commit_msg>chore(lists): updated help text in photos section<commit_after>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

define(function (require, exports, module) {
    "use strict";

    // Dependencies
    var $ = require('jquery'),
        _ = require('underscore'),
        Backbone = require('backbone'),
        moment = require('moment'),
        ListModel = require('models/list'),
        DetailsTemplate = require('text!templates/lists/details.html'),
        LinksManagerView = require('views/links/manager'),
        PictureManagerView = require('views/pictures/manager'),
        state = require('state'),
        User = require('models/user'),
        user = new User();

    require('bootstrap');
    require('ckeditor-core');
    require('datepicker');
    require('datepicker-lang-no');

    // Module
    return Backbone.View.extend({

        template: _.template(DetailsTemplate),

        availableTags: [
            'SjekkUTDev'
        ],

        el: '[data-view="list-details"]',

        bindings: {
            '[name="list-details-field-navn"]': {
                observe: 'navn'
            },
            '[name="list-details-field-url"]': {
                observe: 'url'
            },
            '[name="list-details-field-beskrivelse"]': {
                observe: 'beskrivelse'
            },
            '[name="list-details-field-start"]': {
                observe: 'start',
                onGet: function(value) {
                    if (value) {
                        return moment(value).format('DD.MM.YYYY');
                    }
                },
                onSet: function(value) {
                    if (value) {
                        return moment(value, 'DD.MM.YYYY').toISOString();
                    }
                }
            },
            '[name="list-details-field-stopp"]': {
                observe: 'stopp',
                onGet: function(value) {
                    if (value) {
                        return moment(value).format('DD.MM.YYYY');
                    }
                },
                onSet: function(value) {
                    if (value) {
                        return moment(value, 'DD.MM.YYYY').toISOString();
                    }
                }
            },
            '[name="list-details-field-kategori"]': {
                observe: 'tags',
                setOptions: {
                    validate: true
                },
                onGet: function(value) {
                    // onGet called after tags change, and returns the first value in the array
                    return value[0];
                },
                onSet: function(value) {
                    // When input field value changes, set tags to an array with the
                    return [value];
                }
            }
        },

        events: {},

        initialize: function (options) {

            this.model = options.list || new ListModel();

            this.model.on('change:navn', this.updateListNamePlaceholders, this);
            this.model.on('sync', this.render, this);

            this.editor = options.editor;
            this.user = user;

        },

        render: function () {

            var html = this.template({
                model: this.model.toJSON(),
                availableTags: this.availableTags
            });
            this.$el.html(html);

            // Beskrivelse
            this.setupCkeditor();

            // Dates
            $('input[name="list-details-field-start"]').datepicker({
                forceParse: false, // AFAICS forceparse fails and causes existing date to be cleared when picker is dismissed
                format: 'dd.mm.yyyy',
                weekStart: 1,
                startDate: moment().format('DD.MM.YYYY'),
                language: 'no'
            });
            $('input[name="list-details-field-stopp"]').datepicker({
                forceParse: false, // AFAICS forceparse fails and causes existing date to be cleared when picker is dismissed
                format: 'dd.mm.yyyy',
                weekStart: 1,
                startDate: moment().format('DD.MM.YYYY'),
                language: 'no'
            });

            // Links Manager
            var linksManagerView = new LinksManagerView({
                model: this.model,
                linksField: 'lenker',
                el: '[data-view="list-details-lenker"]'
            }).render();

            // Pictures manager
            this.pictureManagerView = new PictureManagerView({
                el: '[data-view="list-pictures"]',
                pictures: this.model.bilder,
                stripped: true,
                messages: {
                    empty: 'Husk å legge inn bilder.',
                    info: 'Det første bildet vil bli brukt som hovedbilde i SjekkUT-appen.'
                },
                defaults: {
                    status: 'Offentlig'
                }
            }).render();

            this.setupGrupperSelect();

            // Set up view bindings and validation
            this.stickit(); // Uses view.bindings and view.model to setup bindings
            Backbone.Validation.bind(this);

            return this;

        },

        remove: function() {
            // Remove the validation binding
            // See: http://thedersen.com/projects/backbone-validation/#using-form-model-validation/unbinding
            Backbone.Validation.unbind(this);
            return Backbone.View.prototype.remove.apply(this, arguments);
        },

        setupCkeditor: function () {
            var descriptionEditor = CKEDITOR.replace($('textarea[name="list-details-field-beskrivelse"]')[0], {
                language: 'no',
                // Define the toolbar groups as it is a more accessible solution.
                toolbarGroups: [
                    {name: 'basicstyles', groups: ['basicstyles']},
                    {name: 'paragraph', groups: ['list']},
                    {name: 'styles', groups: ['styles']},
                    {name: 'links'}
                ],
                format_tags: 'p;h2;h3',
                // Remove the redundant buttons from toolbar groups defined above.
                removeButtons: 'Subscript,Superscript,Strike,Styles',
                // Remove elements path in footer
                removePlugins: 'elementspath',
                // Whether to use HTML entities in the output.
                entities: false
            });

            descriptionEditor.on('change', $.proxy(function (e) {
                var data = e.editor.getData();
                this.model.set('beskrivelse', data);
            }, this));
        },

        setupGrupperSelect: function () {
            var userGroups = user.get('grupper');
            if (userGroups.length > 0) {
                var select2Groups = [];

                for (var j = 0; j < userGroups.length; j++) {
                    select2Groups[j] = {};
                    select2Groups[j].id = userGroups[j].object_id;
                    select2Groups[j].text = userGroups[j].navn;
                }

                $('input[name="list-details-field-grupper"]').select2({
                    tags: select2Groups,
                    createSearchChoice: function () { return null; } // This will prevent the user from entering custom tags
                }).on('change', $.proxy(function (e) {
                    var routeGroups = e.val;
                    this.model.set('grupper', routeGroups);
                }, this));

                this.$('[name="list-details-field-grupper"]').select2('val', this.model.get('grupper'));

            } else {
                // If user does not belong to any groups, do not show groups field.
                this.$('.form-group.list-details-field-grupper').remove();
            }
        }

    });
});
<|endoftext|>


<commit_before>
/*!
 * Sync Listeners, v0.1
 *
 * Copyright (c) 2013-2014 Dave Olsen, http://dmolsen.com
 * Licensed under the MIT license
 *
 * The JavaScript component of the WebSocket set-up that supports syncing
 * navigation between browsers and content updates with the server.
 *
 * The WebSocket test is from Modernizr. It might be a little too strict for our purposes.
 * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/websockets.js
 *
 */

var wsn;
var wsnConnected = false;
var wsc;
var wscConnected = false;
var host = (window.location.host !== "") ? window.location.host : "127.0.0.1";

// handle page updates from one browser to another
function connectNavSync() {

	if ('WebSocket' in window && window.WebSocket.CLOSING === 2) {

		var navSyncCopy = "Page Follow";
		wsn = new WebSocket("ws://"+host+":"+navSyncPort+"/navsync");

		// when trying to open a connection to WebSocket update the pattern lab nav bar
		wsn.onopen = function () {
			wsnConnected = true;
			$('#navSyncButton').attr("data-state","on");
			$('#navSyncButton').addClass("connected");
			$('#navSyncButton').addClass("active");
			$('#navSyncButton').html(navSyncCopy+' On');
		};

		// when closing a connection (or failing to make a connection) to WebSocket update the pattern lab nav bar
		wsn.onclose = function () {
			wsnConnected = false;
			$('#navSyncButton').attr("data-state","off");
			if ($('#navSyncButton').hasClass("connected")) {
				$('#navSyncButton').removeClass("connected");
				$('#navSyncButton').removeClass("active");
			}
			$('#navSyncButton').html(navSyncCopy+' Disabled');
		};

		// when receiving a message from WebSocket update the iframe source
		wsn.onmessage = function (event) {

			var data = JSON.parse(event.data);
			var vpLocation  = document.getElementById('sg-viewport').contentWindow.location.href;
			var mLocation   = "http://"+host+data.url;

			if (vpLocation != mLocation) {

				document.getElementById('sg-viewport').contentWindow.location.replace(mLocation);

				// make sure the pop doesn't fire and push the pattern
				urlHandler.doPop = false;
				urlHandler.pushPattern(data.patternpartial);

				// reset the defaults
				urlHandler.doPop    = true;
				urlHandler.skipBack = false;

			}
		};

		// when there's an error update the pattern lab nav bar
		wsn.onerror = function () {
			wsnConnected = false;
			$('#navSyncButton').attr("data-state","off");
			if ($('#navSyncButton').hasClass("connected")) {
				$('#navSyncButton').removeClass("connected");
				$('#navSyncButton').removeClass("active");
			}
			$('#navSyncButton').html(navSyncCopy+' Disabled');
		};

	}

}
connectNavSync();

// handle content updates generated by the watch
function connectContentSync() {

	if ('WebSocket' in window && window.WebSocket.CLOSING === 2) {

		var contentSyncCopy = "Auto-reload";

		wsc = new WebSocket("ws://"+host+":"+contentSyncPort+"/contentsync");

		// when trying to open a connection to WebSocket update the pattern lab nav bar
		wsc.onopen = function () {
			wscConnected = true;
			$('#contentSyncButton').attr("data-state","on");
			$('#contentSyncButton').addClass("connected");
			$('#contentSyncButton').addClass("active");
			$('#contentSyncButton').html(contentSyncCopy+' On');
		};

		// when closing a connection (or failing to make a connection) to WebSocket update the pattern lab nav bar
		wsc.onclose = function () {
			wscConnected = false;
			$('#contentSyncButton').attr("data-state","off");
			if ($('#contentSyncButton').hasClass("connected")) {
				$('#contentSyncButton').removeClass("connected");
				$('#contentSyncButton').removeClass("active");
			}
			$('#contentSyncButton').html(contentSyncCopy+' Disabled');
		};

		// when receiving a message from WebSocket reload the current frame adding the received timestamp
		// as a request var to, hopefully, bust caches... cachi(?)
		wsc.onmessage = function () {
			var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host;
			document.getElementById('sg-viewport').contentWindow.postMessage( { "reload": true }, targetOrigin);
		};

		// when there's an error update the pattern lab nav bar
		wsc.onerror = function () {
			wscConnected = false;
			$('#contentSyncButton').attr("data-state","off");
			if ($('#contentSyncButton').hasClass("connected")) {
				$('#contentSyncButton').removeClass("connected");
				$('#contentSyncButton').removeClass("active");
			}
			$('#contentSyncButton').html(contentSyncCopy+' Disabled');
		};

	}

}
connectContentSync();

// handle when a user manually turns navSync and contentSync on & off
$('#navSyncButton').click(function() {
	if ($(this).attr("data-state") == "on") {
		wsn.close();
		$(this).attr("data-state","off");
		$(this).removeClass("connected");
		$(this).removeClass("active");
		$(this).html('Nav Sync Off');
	} else {
		connectNavSync();
		$(this).attr("data-state","on");
		$(this).addClass("connected");
		$(this).addClass("active");
		$(this).html('Nav Sync On');
	}
});

$('#contentSyncButton').click(function() {
	if ($(this).attr("data-state") == "on") {
		wsc.close();
		$(this).attr("data-state","off");
		$(this).removeClass("connected");
		$(this).removeClass("active");
		$(this).html('Content Sync Off');
	} else {
		connectContentSync();
		$(this).attr("data-state","on");
		$(this).addClass("connected");
		$(this).addClass("active");
		$(this).html('Content Sync On');
	}
});
<commit_msg>renaming the ports<commit_after>
/*!
 * Sync Listeners, v0.1
 *
 * Copyright (c) 2013-2014 Dave Olsen, http://dmolsen.com
 * Licensed under the MIT license
 *
 * The JavaScript component of the WebSocket set-up that supports syncing
 * navigation between browsers and content updates with the server.
 *
 * The WebSocket test is from Modernizr. It might be a little too strict for our purposes.
 * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/websockets.js
 *
 */

var wsn;
var wsnConnected = false;
var wsc;
var wscConnected = false;
var host = (window.location.host !== "") ? window.location.host : "127.0.0.1";

// handle page updates from one browser to another
function connectPageFollowSync() {

	if ('WebSocket' in window && window.WebSocket.CLOSING === 2) {

		var navSyncCopy = "Page Follow";
		wsn = new WebSocket("ws://"+host+":"+navSyncPort+"/pagefollow");

		// when trying to open a connection to WebSocket update the pattern lab nav bar
		wsn.onopen = function () {
			wsnConnected = true;
			$('#navSyncButton').attr("data-state","on");
			$('#navSyncButton').addClass("connected");
			$('#navSyncButton').addClass("active");
			$('#navSyncButton').html(navSyncCopy+' On');
		};

		// when closing a connection (or failing to make a connection) to WebSocket update the pattern lab nav bar
		wsn.onclose = function () {
			wsnConnected = false;
			$('#navSyncButton').attr("data-state","off");
			if ($('#navSyncButton').hasClass("connected")) {
				$('#navSyncButton').removeClass("connected");
				$('#navSyncButton').removeClass("active");
			}
			$('#navSyncButton').html(navSyncCopy+' Disabled');
		};

		// when receiving a message from WebSocket update the iframe source
		wsn.onmessage = function (event) {

			var data = JSON.parse(event.data);
			var vpLocation  = document.getElementById('sg-viewport').contentWindow.location.href;
			var mLocation   = "http://"+host+data.url;

			if (vpLocation != mLocation) {

				document.getElementById('sg-viewport').contentWindow.location.replace(mLocation);

				// make sure the pop doesn't fire and push the pattern
				urlHandler.doPop = false;
				urlHandler.pushPattern(data.patternpartial);

				// reset the defaults
				urlHandler.doPop    = true;
				urlHandler.skipBack = false;

			}
		};

		// when there's an error update the pattern lab nav bar
		wsn.onerror = function () {
			wsnConnected = false;
			$('#navSyncButton').attr("data-state","off");
			if ($('#navSyncButton').hasClass("connected")) {
				$('#navSyncButton').removeClass("connected");
				$('#navSyncButton').removeClass("active");
			}
			$('#navSyncButton').html(navSyncCopy+' Disabled');
		};

	}

}
connectPageFollowSync();

// handle content updates generated by the watch
function connectAutoReloadSync() {

	if ('WebSocket' in window && window.WebSocket.CLOSING === 2) {

		var contentSyncCopy = "Auto-reload";

		wsc = new WebSocket("ws://"+host+":"+contentSyncPort+"/autoreload");

		// when trying to open a connection to WebSocket update the pattern lab nav bar
		wsc.onopen = function () {
			wscConnected = true;
			$('#contentSyncButton').attr("data-state","on");
			$('#contentSyncButton').addClass("connected");
			$('#contentSyncButton').addClass("active");
			$('#contentSyncButton').html(contentSyncCopy+' On');
		};

		// when closing a connection (or failing to make a connection) to WebSocket update the pattern lab nav bar
		wsc.onclose = function () {
			wscConnected = false;
			$('#contentSyncButton').attr("data-state","off");
			if ($('#contentSyncButton').hasClass("connected")) {
				$('#contentSyncButton').removeClass("connected");
				$('#contentSyncButton').removeClass("active");
			}
			$('#contentSyncButton').html(contentSyncCopy+' Disabled');
		};

		// when receiving a message from WebSocket reload the current frame adding the received timestamp
		// as a request var to, hopefully, bust caches... cachi(?)
		wsc.onmessage = function () {
			var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host;
			document.getElementById('sg-viewport').contentWindow.postMessage( { "reload": true }, targetOrigin);
		};

		// when there's an error update the pattern lab nav bar
		wsc.onerror = function () {
			wscConnected = false;
			$('#contentSyncButton').attr("data-state","off");
			if ($('#contentSyncButton').hasClass("connected")) {
				$('#contentSyncButton').removeClass("connected");
				$('#contentSyncButton').removeClass("active");
			}
			$('#contentSyncButton').html(contentSyncCopy+' Disabled');
		};

	}

}
connectAutoReloadSync();

// handle when a user manually turns navSync and contentSync on & off
$('#navSyncButton').click(function() {
	if ($(this).attr("data-state") == "on") {
		wsn.close();
		$(this).attr("data-state","off");
		$(this).removeClass("connected");
		$(this).removeClass("active");
		$(this).html('Nav Sync Off');
	} else {
		connectNavSync();
		$(this).attr("data-state","on");
		$(this).addClass("connected");
		$(this).addClass("active");
		$(this).html('Nav Sync On');
	}
});

$('#contentSyncButton').click(function() {
	if ($(this).attr("data-state") == "on") {
		wsc.close();
		$(this).attr("data-state","off");
		$(this).removeClass("connected");
		$(this).removeClass("active");
		$(this).html('Content Sync Off');
	} else {
		connectContentSync();
		$(this).attr("data-state","on");
		$(this).addClass("connected");
		$(this).addClass("active");
		$(this).html('Content Sync On');
	}
});
<|endoftext|>


<commit_before>/* global app:true, io:false */

var socket;
var myname;
var block_id;

(function() {
  'use strict';

  /*socket = io.connect();
  socket.on('connect', function(){
  	socket.emit('/replay/#join');
  });

  socket.on('message', function (message) {
      console.log(message);
  });

  socket.on('disconnect', function() {
      console.log('>>> DB disconnected');
  });*/

  app = app || {};

  app.Reset = Backbone.Model.extend({
    defaults: {
      success: false,
      errors: [],
      errfor: {},
      blockid: undefined,
      confitm: ''
    },
    url: function(){
      return '/account/pattern/' + this.get('block_id') +'/';
    }
  });

  app.PatternView = Backbone.View.extend({
    el: '#pattern_menu',
    template: _.template( $('#tmpl-pattern_menu').html() ),
    events: {
      'click .btn-check': 'reqCheck',
      'click .btn-submit': 'reqSubmit'
    },
    initialize: function() {
      //this.model = new app.Blocks();
      //this.listenTo(this.model, 'sync', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template);
    },
    reqCheck: function() {
      console.log("Check");
    },
    reqSubmit: function() {
      console.log("Submit");
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      'account/pattern/': 'default',
      'account/pattern/load/:block/': 'load'
    },
    default: function(){
      console.log(" >>default view, nothing loaded");
    },
    load: function(block) {
      console.log(">> loading block "+block);
      block_id = block;
      var info_div = document.getElementById("info_box");
      var info_text = document.createElement("h6");
      var block_node = document.createTextNode("Pattern for [ block # "+block_id+" ]");
      var pattern_node = document.createTextNode(" -  [ pattern # "+" ]");
	info_text.appendChild(block_node);
	info_text.appendChild(pattern_node);
	info_div.appendChild(info_text);
      document.getElementById("btn_submit").disabled = true;
      //socket.emit('/replay/#callblock', { targetBlock: block});
    }
  });

  $(document).ready(function() {
    app.patternView = new app.PatternView();
    app.router = new app.Router();
    Backbone.history.start({ pushState: true });
  });
}());<commit_msg>pattern page<commit_after>/* global app:true, io:false */

var socket;
var myname;
var block_id;

(function() {
  'use strict';

  /*socket = io.connect();
  socket.on('connect', function(){
  	socket.emit('/replay/#join');
  });

  socket.on('message', function (message) {
      console.log(message);
  });

  socket.on('disconnect', function() {
      console.log('>>> DB disconnected');
  });*/

  app = app || {};

  app.Reset = Backbone.Model.extend({
    defaults: {
      success: false,
      errors: [],
      errfor: {},
      blockid: undefined,
      confitm: ''
    },
    url: function(){
      return '/account/pattern/' + this.get('block_id') +'/';
    }
  });

  app.PatternView = Backbone.View.extend({
    el: '#pattern_menu',
    template: _.template( $('#tmpl-pattern_menu').html() ),
    events: {
      'click .btn-check': 'reqCheck',
      'click .btn-submit': 'reqSubmit'
    },
    initialize: function() {
      //this.model = new app.Blocks();
      //this.listenTo(this.model, 'sync', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template);
    },
    reqCheck: function() {
      var input = document.getElementById("pattern_input").value;
      console.log(input);
    },
    reqSubmit: function() {
      console.log("Submit");
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      'account/pattern/': 'default',
      'account/pattern/load/:block/': 'load'
    },
    default: function(){
      console.log(" >>default view, nothing loaded");
    },
    load: function(block) {
      console.log(">> loading block "+block);
      block_id = block;
      var info_div = document.getElementById("info_box");
      var info_text = document.createElement("h6");
      var block_node = document.createTextNode("Pattern for [ block # "+block_id+" ]");
      var pattern_node = document.createTextNode(" -  [ pattern # "+" ]");
	info_text.appendChild(block_node);
	info_text.appendChild(pattern_node);
	info_div.appendChild(info_text);
      document.getElementById("btn_submit").disabled = true;
      //socket.emit('/replay/#callblock', { targetBlock: block});
    }
  });

  $(document).ready(function() {
    app.patternView = new app.PatternView();
    app.router = new app.Router();
    Backbone.history.start({ pushState: true });
  });
}());<|endoftext|>


<commit_before>function callAjax(url, callbackFunction) {

    var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            callbackFunction(xmlhttp.responseText);
        }
    }

    xmlhttp.open("GET", url, true);
    xmlhttp.send();
}

function visitArray(arr, visitor) {
    var result = [];

    for (var i = 0; i < arr.length; i++) {
        result[i] = visitor(arr[i]);
    }

    return result;
}

function renderBadge(key, badgeData)
{
	var outString="

"+key+"
";
	var all=badgeData.split(";");
	outString+="";
	outString+="
"+all[1]+"

";

	return outString;
}

function createBadgeJSON(badgeData)
{
	var all=badgeData.split(";");
	var imageUrl="\"imageUrl\":\""+all[0]+"\"";
	var all2="{"+imageUrl+",\"authorList\":"+"[\""+all[1].split(",").join("\",\"")+"\"]}";

	return all2;
}

function insertCSS()
{
	return ".paper-badge {float: left; width: 10em; height: 20em; overflow: hidden; border-top: 1px solid #ccc; height 15em; padding: 2%; margin-right: 1%; margin-top: 2%}.badge-span {width: 15em; display: inline-block; font-size: 88%; line-height: 1.2; color: #333; padding: 0.4em; cursor: hand; cursor: pointer}.paper-badge img {margin-left: 10%}.badges-active {color: #fff !important; background: #7ab441}";
}

function showLine()
{
	var bindBadge=this.getAttribute("data-bind-badge");

	//var boundElem=$(".badge span[data-bind-badge="+bindBadge+"]");
	//boundElem.attr("title", "badge count: "+boundElem.length+"; ORCID: "+bindBadge.split("\_").join(" "));
	var allElems=document.getElementsByClassName("badge-span");
	visitArray(allElems, function(item){if(item.getAttribute("data-bind-badge") == bindBadge){item.className = "badge-span badges-active"; item.setAttribute("title", "ORCID: "+bindBadge.split("\_").join(" "));}else item.className = "badge-span";});
}

function nextAction()
{
	var bindBadge=this.getAttribute("data-bind-badge");
	window.open("http://orcid.org/"+bindBadge, "orcid");
}

function splitArray(arr, lookGroup)
{
	var ttt="";

	for(var i=0, arrLen=arr.length; i<arrLen; i++)
		{
		var noIn=lookGroup[arr[i]];
		ttt+=""+noIn.split("_").join(" ")+"";
		}

	return ttt;
}

function showBadges(confIn){

	var k="";

	var containerClass=(confIn["container-class"]) ? confIn["container-class"] : "badge-container";
	var doi=confIn["article-doi"];

	callAjax("https://badges.mozillascience.org/papers/"+doi+"/badges", function( entryData ) {

	var outCount=0;
	var pos=0, end=0;
	var excludeChars="\" :\{\}\n\r";

	var mode=0;
	var modeString=find=(!mode) ? "orcid" : "evidenceUrl";
	var look=new Object(), lookGroupOrcidFromBadge=new Object(), lookGroup=new Object(), lookGroupNo=new Object(), lookTemporaryValue=new Array(2);

	look[modeString]=0;
	look["authorName"]=1;
	look["slug"]=2;
	var lastTempVal=look["imageUrl"]=3;

	var group=1;
	var arrayNumber=1;

	while((pos=entryData.indexOf(find, pos))>0)
		{
		end=entryData.indexOf("\,", pos);

		var str=entryData.substring(pos+find.length, end);

		var i=0, k=0, ind=0;

		for(; ind>=0; ){ind=excludeChars.indexOf(str.charAt(i)); if(ind>=0) i++;}
		for(ind=0, j=str.length-1; ind>=0;){ind=excludeChars.indexOf(str.charAt(j)); if(ind>=0) j--;}

		arrayNumber=look[find];

		find=(find == modeString) ? "authorName" : (find == "authorName") ? "slug" : (find == "slug") ? "imageUrl" : modeString;

		lookTemporaryValue[arrayNumber]=str.substring(i, j+1);

		if(arrayNumber == lastTempVal) {

			if(lookTemporaryValue[lastTempVal] != "null")
				{
				var key=lookTemporaryValue[2].split(" ").join("");
				var lookTempVal=lookTemporaryValue[0];

				if(lookGroupOrcidFromBadge[key])
					{
					if(new String(lookGroupOrcidFromBadge[key]).indexOf(lookTempVal)<0)
					lookGroupOrcidFromBadge[key]+=","+lookTempVal;
					}
				else
					{
					lookGroupOrcidFromBadge[key]=lookTemporaryValue[3]+";"+lookTemporaryValue[0];
					}
				lookGroup[lookTempVal]=lookTemporaryValue[1].split(" ").join("_");
				}
			}
		}

		var allJson="";
		var JSONarray=new Array(), iArr=0;

		for (var k in lookGroupOrcidFromBadge) {
			// use hasOwnProperty to filter out keys from the Object.prototype
			if (lookGroupOrcidFromBadge.hasOwnProperty(k)) {JSONarray[iArr++]=createBadgeJSON(lookGroupOrcidFromBadge[k]);}
			}

		var containerClassQuery=document.querySelector("."+containerClass);
		var parsedJSON=JSON.parse("["+JSONarray.join(",")+"]");

		if(containerClassQuery)
			{
			containerClassQuery.appendChild(document.createElement("style")).innerHTML=insertCSS();

			for(var i=0; i<parsedJSON.length; i++)
				{
				var returnString="";

				returnString+="";
				returnString+=splitArray(parsedJSON[i]["authorList"], lookGroup);

				var newNode=document.createElement("div");
				newNode.setAttribute("class", "paper-badge");

				containerClassQuery.appendChild(newNode).innerHTML=returnString;
				}
			}

		visitArray(document.getElementsByClassName("badge-span"), function(elem){
			if(elem){
			elem.addEventListener("mouseover", showLine);
			elem.addEventListener("click", showLine);
			elem.addEventListener("click", nextAction);
			}
			});
	});
}
<commit_msg>New method to show hidden site furniture on publisher pages connected to Paper Badge widget.<commit_after>function callAjax(url, callbackFunction) {

    var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            callbackFunction(xmlhttp.responseText);
        }
    }

    xmlhttp.open("GET", url, true);
    xmlhttp.send();
}

function visitArray(arr, visitor) {
    var result = [];

    for (var i = 0; i < arr.length; i++) {
        result[i] = visitor(arr[i]);
    }

    return result;
}

function renderBadge(key, badgeData)
{
	var outString="

"+key+"
";
	var all=badgeData.split(";");
	outString+="";
	outString+="
"+all[1]+"

";

	return outString;
}

function createBadgeJSON(badgeData)
{
	var all=badgeData.split(";");
	var imageUrl="\"imageUrl\":\""+all[0]+"\"";
	var all2="{"+imageUrl+",\"authorList\":"+"[\""+all[1].split(",").join("\",\"")+"\"]}";

	return all2;
}

function insertCSS()
{
	return ".paper-badge {float: left; width: 10em; height: 20em; overflow: hidden; border-top: 1px solid #ccc; height 15em; padding: 2%; margin-right: 1%; margin-top: 2%}.badge-span {width: 15em; display: inline-block; font-size: 88%; line-height: 1.2; color: #333; padding: 0.4em; cursor: hand; cursor: pointer}.paper-badge img {margin-left: 10%}.badges-active {color: #fff !important; background: #7ab441}";
}

function showLine()
{
	var bindBadge=this.getAttribute("data-bind-badge");

	//var boundElem=$(".badge span[data-bind-badge="+bindBadge+"]");
	//boundElem.attr("title", "badge count: "+boundElem.length+"; ORCID: "+bindBadge.split("\_").join(" "));
	var allElems=document.getElementsByClassName("badge-span");
	visitArray(allElems, function(item){if(item.getAttribute("data-bind-badge") == bindBadge){item.className = "badge-span badges-active"; item.setAttribute("title", "ORCID: "+bindBadge.split("\_").join(" "));}else item.className = "badge-span";});
}

function nextAction()
{
	var bindBadge=this.getAttribute("data-bind-badge");
	window.open("http://orcid.org/"+bindBadge, "orcid");
}

function splitArray(arr, lookGroup)
{
	var ttt="";

	for(var i=0, arrLen=arr.length; i<arrLen; i++)
		{
		var noIn=lookGroup[arr[i]];
		ttt+=""+noIn.split("_").join(" ")+"";
		}

	return ttt;
}

function showBadgeFurniture(confIn)
{
	var furnitureClass=(confIn["furniture-class"]) ? confIn["furniture-class"] : "paper-badges-hidden";
	var doi=confIn["article-doi"];

	callAjax("https://badges.mozillascience.org/papers/"+doi+"/badges/count", function(dataItem){
		var badgesCount=(dataItem) ? dataItem : 0;

		if(badgesCount && dataItem/dataItem)
			{
			visitArray(document.querySelectorAll("."+furnitureClass), function(elem){

				if(elem.classList.contains(furnitureClass))
					{
					elem.classList.remove(furnitureClass);
					}
			});
			}
	});
}

function showBadges(confIn){

	var k="";

	var containerClass=(confIn["container-class"]) ? confIn["container-class"] : "badge-container";
	var doi=confIn["article-doi"];

	callAjax("https://badges.mozillascience.org/papers/"+doi+"/badges", function( entryData ) {

	var outCount=0;
	var pos=0, end=0;
	var excludeChars="\" :\{\}\n\r";

	var mode=0;
	var modeString=find=(!mode) ? "orcid" : "evidenceUrl";
	var look=new Object(), lookGroupOrcidFromBadge=new Object(), lookGroup=new Object(), lookGroupNo=new Object(), lookTemporaryValue=new Array(2);

	look[modeString]=0;
	look["authorName"]=1;
	look["slug"]=2;
	var lastTempVal=look["imageUrl"]=3;

	var group=1;
	var arrayNumber=1;

	while((pos=entryData.indexOf(find, pos))>0)
		{
		end=entryData.indexOf("\,", pos);

		var str=entryData.substring(pos+find.length, end);

		var i=0, k=0, ind=0;

		for(; ind>=0; ){ind=excludeChars.indexOf(str.charAt(i)); if(ind>=0) i++;}
		for(ind=0, j=str.length-1; ind>=0;){ind=excludeChars.indexOf(str.charAt(j)); if(ind>=0) j--;}

		arrayNumber=look[find];

		find=(find == modeString) ? "authorName" : (find == "authorName") ? "slug" : (find == "slug") ? "imageUrl" : modeString;

		lookTemporaryValue[arrayNumber]=str.substring(i, j+1);

		if(arrayNumber == lastTempVal) {

			if(lookTemporaryValue[lastTempVal] != "null")
				{
				var key=lookTemporaryValue[2].split(" ").join("");
				var lookTempVal=lookTemporaryValue[0];

				if(lookGroupOrcidFromBadge[key])
					{
					if(new String(lookGroupOrcidFromBadge[key]).indexOf(lookTempVal)<0)
					lookGroupOrcidFromBadge[key]+=","+lookTempVal;
					}
				else
					{
					lookGroupOrcidFromBadge[key]=lookTemporaryValue[3]+";"+lookTemporaryValue[0];
					}
				lookGroup[lookTempVal]=lookTemporaryValue[1].split(" ").join("_");
				}
			}
		}

		var allJson="";
		var JSONarray=new Array(), iArr=0;

		for (var k in lookGroupOrcidFromBadge) {
			// use hasOwnProperty to filter out keys from the Object.prototype
			if (lookGroupOrcidFromBadge.hasOwnProperty(k)) {JSONarray[iArr++]=createBadgeJSON(lookGroupOrcidFromBadge[k]);}
			}

		var containerClassQuery=document.querySelector("."+containerClass);
		var parsedJSON=JSON.parse("["+JSONarray.join(",")+"]");

		if(containerClassQuery)
			{
			containerClassQuery.appendChild(document.createElement("style")).innerHTML=insertCSS();

			for(var i=0; i<parsedJSON.length; i++)
				{
				var returnString="";

				returnString+="";
				returnString+=splitArray(parsedJSON[i]["authorList"], lookGroup);

				var newNode=document.createElement("div");
				newNode.setAttribute("class", "paper-badge");

				containerClassQuery.appendChild(newNode).innerHTML=returnString;
				}
			}

		visitArray(document.getElementsByClassName("badge-span"), function(elem){
			if(elem){
			elem.addEventListener("mouseover", showLine);
			elem.addEventListener("click", showLine);
			elem.addEventListener("click", nextAction);
			}
			});
	});
}
<|endoftext|>


<commit_before>'use strict';

/* demo: quickStart */
(function () {
  var _spritejs = spritejs,
      Scene = _spritejs.Scene,
      Sprite = _spritejs.Sprite;

  var scene = new Scene('#demo-quickStart', {
    viewport: ['770', '200'],
    resolution: [3080, 800]
  });

  var layer = scene.layer();

  var robot = new Sprite('https://p5.ssl.qhimg.com/t01c33383c0e168c3c4.png');

  robot.attr({
    anchor: [0, 0.5],
    pos: [0, 0]
  });

  robot.animate([{ pos: [0, 0] }, { pos: [0, 300] }, { pos: [2700, 300] }, { pos: [2700, 0] }], {
    duration: 5000,
    iterations: Infinity,
    direction: 'alternate'
  });

  layer.append(robot);
})();
<commit_msg>update<commit_after>'use strict';

/* demo: quickStart */
(function () {
  var _spritejs = spritejs,
      Scene = _spritejs.Scene,
      Sprite = _spritejs.Sprite;

  var scene = new Scene('#demo-quickStart', {
    viewport: ['auto', 'auto'],
    resolution: [3080, 800]
  });

  var layer = scene.layer();

  var robot = new Sprite('https://p5.ssl.qhimg.com/t01c33383c0e168c3c4.png');

  robot.attr({
    anchor: [0, 0.5],
    pos: [0, 0]
  });

  robot.animate([{ pos: [0, 0] }, { pos: [0, 300] }, { pos: [2700, 300] }, { pos: [2700, 0] }], {
    duration: 5000,
    iterations: Infinity,
    direction: 'alternate'
  });

  layer.append(robot);
})();<|endoftext|>


<commit_before>import HypertyDiscovery from './hyperty-discovery/HypertyDiscovery';

export default HypertyDiscovery;
<commit_msg>Remove hyperty-discovery reference lib<commit_after><|endoftext|>


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

	var L = require('leaflet');
	var corslite = require('corslite');
	var polyline = require('polyline');

	L.Routing = L.Routing || {};

	L.Routing.Mapbox = L.Class.extend({
		options: {
			serviceUrl: '//api.tiles.mapbox.com/v4/directions/',
			timeout: 30 * 1000,
			profile: 'mapbox.driving'
		},

		initialize: function(accessToken, options) {
			L.Util.setOptions(this, options);
			this._accessToken = accessToken;
		},

		route: function(waypoints, callback, context, options) {
			var timedOut = false,
				wps = [],
				url,
				timer,
				wp,
				i;

			options = options || {};
			url = this.buildRouteUrl(waypoints, options);

			timer = setTimeout(function() {
								timedOut = true;
								callback.call(context || callback, {
									status: -1,
									message: 'OSRM request timed out.'
								});
							}, this.options.timeout);

			// Create a copy of the waypoints, since they
			// might otherwise be asynchronously modified while
			// the request is being processed.
			for (i = 0; i < waypoints.length; i++) {
				wp = waypoints[i];
				wps.push({
					latLng: wp.latLng,
					name: wp.name,
					options: wp.options
				});
			}

			corslite(url, L.bind(function(err, resp) {
				var data;

				clearTimeout(timer);
				if (!timedOut) {
					if (!err) {
						data = JSON.parse(resp.responseText);
						this._routeDone(data, wps, callback, context);
					} else {
						callback.call(context || callback, {
							status: -1,
							message: 'HTTP request failed: ' + err
						});
					}
				}
			}, this), true);

			return this;
		},

		_routeDone: function(response, inputWaypoints, callback, context) {
			var alts = [],
				route,
				coordinates,
			    actualWaypoints,
			    i;

			context = context || callback;

			actualWaypoints = this._toWaypoints(inputWaypoints,
				[response.origin].concat(response.waypoints).concat([response.destination]));

			for (i = 0; i < response.routes.length; i++) {
				route = response.routes[i];
				coordinates = polyline.decode(route.geometry, 6);
				alts.push({
					name: route.summary,
					coordinates: coordinates,
					instructions: this._convertInstructions(route.steps),
					summary: this._convertSummary(route),
					inputWaypoints: inputWaypoints,
					waypoints: actualWaypoints,
					waypointIndices: this._mapWaypointIndices(actualWaypoints, route.steps, coordinates)
				});
			}

			callback.call(context, undefined, alts);
		},

		_toWaypoints: function(inputWaypoints, vias) {
			var wps = [],
			    i,
			    c;
			for (i = 0; i < vias.length; i++) {
				c = vias[i].geometry.coordinates;
				wps.push({
					latLng: L.latLng(c[1], c[0]),
					name: vias[i].properties.name,
					options: inputWaypoints[i].options
				});
			}

			return wps;
		},

		buildRouteUrl: function(waypoints, options) {
			var locs = [],
			    computeInstructions,
			    computeAlternative,
			    locationKey;

			for (var i = 0; i < waypoints.length; i++) {
				locationKey = this._locationKey(waypoints[i].latLng);
				locs.push((i ? ';' : '') + locationKey);
			}

			computeAlternative = computeInstructions =
				!(options && options.geometryOnly);

			return this.options.serviceUrl + this.options.profile + '/' + locs + '.json?' +
				'instructions=' + computeInstructions + '&' +
				'alternatives=' + computeAlternative + '&' +
				'geometry=polyline&access_token=' + this._accessToken;
		},

		_locationKey: function(location) {
			return location.lng + ',' + location.lat;
		},

		_convertSummary: function(route) {
			return {
				totalDistance: route.distance,
				totalTime: route.duration
			};
		},

		_convertInstructions: function(steps) {
			var result = [],
			    i,
			    step,
			    type;

			for (i = 0; i < steps.length; i++) {
				step = steps[i];
				type = this._drivingDirectionType(step.maneuver);
				if (type) {
					result.push({
						type: type,
						distance: step.distance,
						time: step.duration,
						road: step.way_name,
						direction: step.direction,
						index: step[3]
					});
				}
			}

			return result;
		},

		_drivingDirectionType: function(maneuver) {
			switch (maneuver.type) {
			case 'continue':
				return 'Straight';
			case 'bear right':
				return 'SlightRight';
			case 'turn right':
				return 'Right';
			case 'sharp right':
				return 'SharpRight';
			case 'u-turn':
				return 'TurnAround';
			case 'sharp left':
				return 'SharpLeft';
			case 'turn left':
				return 'Left';
			case 'bear left':
				return 'SlightLeft';
			case 'waypoint':
				return 'WaypointReached';
			case 'depart':
				// TODO: "Head on"
				// https://github.com/DennisOSRM/Project-OSRM/blob/master/DataStructures/TurnInstructions.h#L48
				return 'Straight';
			case 'enter roundabout':
				return 'Roundabout';
			case 'arrive':
				return 'DestinationReached';
			default:
				return null;
			}
		},

		_mapWaypointIndices: function(waypoints, instructions, coordinates) {
			var wpIndices = [],
				wpIndex = 0,
				wp = waypoints[wpIndex],
			    i,
			    c;

			for (i = 0; i < coordinates.length; i++) {
				c = coordinates[i];
				if (Math.abs(c[0] - wp.latLng.lat) < 1e-5 &&
					Math.abs(c[1] - wp.latLng.lng) < 1e-5) {
					wpIndices.push(i);
					wp = waypoints[++wpIndex];
				}
			}

			return wpIndices;
		}
	});

	L.Routing.mapbox = function(accessToken, options) {
		return new L.Routing.Mapbox(accessToken, options);
	};

	module.exports = L.Routing.Mapbox;
})();
<commit_msg>Include coordinate indices for instructions<commit_after>(function() {
	'use strict';

	var L = require('leaflet');
	var corslite = require('corslite');
	var polyline = require('polyline');

	L.Routing = L.Routing || {};

	L.Routing.Mapbox = L.Class.extend({
		options: {
			serviceUrl: '//api.tiles.mapbox.com/v4/directions/',
			timeout: 30 * 1000,
			profile: 'mapbox.driving'
		},

		initialize: function(accessToken, options) {
			L.Util.setOptions(this, options);
			this._accessToken = accessToken;
		},

		route: function(waypoints, callback, context, options) {
			var timedOut = false,
				wps = [],
				url,
				timer,
				wp,
				i;

			options = options || {};
			url = this.buildRouteUrl(waypoints, options);

			timer = setTimeout(function() {
								timedOut = true;
								callback.call(context || callback, {
									status: -1,
									message: 'OSRM request timed out.'
								});
							}, this.options.timeout);

			// Create a copy of the waypoints, since they
			// might otherwise be asynchronously modified while
			// the request is being processed.
			for (i = 0; i < waypoints.length; i++) {
				wp = waypoints[i];
				wps.push({
					latLng: wp.latLng,
					name: wp.name,
					options: wp.options
				});
			}

			corslite(url, L.bind(function(err, resp) {
				var data;

				clearTimeout(timer);
				if (!timedOut) {
					if (!err) {
						data = JSON.parse(resp.responseText);
						this._routeDone(data, wps, callback, context);
					} else {
						callback.call(context || callback, {
							status: -1,
							message: 'HTTP request failed: ' + err
						});
					}
				}
			}, this), true);

			return this;
		},

		_routeDone: function(response, inputWaypoints, callback, context) {
			var alts = [],
				route,
				coordinates,
			    actualWaypoints,
			    indices,
			    i;

			context = context || callback;

			actualWaypoints = this._toWaypoints(inputWaypoints,
				[response.origin].concat(response.waypoints).concat([response.destination]));

			for (i = 0; i < response.routes.length; i++) {
				route = response.routes[i];
				coordinates = polyline.decode(route.geometry, 6);
				indices = this._mapWaypointIndices(actualWaypoints, route.steps, coordinates);
				alts.push({
					name: route.summary,
					coordinates: coordinates,
					instructions: this._convertInstructions(route.steps, indices.stepIndices),
					summary: this._convertSummary(route),
					inputWaypoints: inputWaypoints,
					waypoints: actualWaypoints,
					waypointIndices: indices.waypointIndices
				});
			}

			callback.call(context, undefined, alts);
		},

		_toWaypoints: function(inputWaypoints, vias) {
			var wps = [],
			    i,
			    c;
			for (i = 0; i < vias.length; i++) {
				c = vias[i].geometry.coordinates;
				wps.push({
					latLng: L.latLng(c[1], c[0]),
					name: vias[i].properties.name,
					options: inputWaypoints[i].options
				});
			}

			return wps;
		},

		buildRouteUrl: function(waypoints, options) {
			var locs = [],
			    computeInstructions,
			    computeAlternative,
			    locationKey;

			for (var i = 0; i < waypoints.length; i++) {
				locationKey = this._locationKey(waypoints[i].latLng);
				locs.push((i ? ';' : '') + locationKey);
			}

			computeAlternative = computeInstructions =
				!(options && options.geometryOnly);

			return this.options.serviceUrl + this.options.profile + '/' + locs + '.json?' +
				'instructions=' + computeInstructions + '&' +
				'alternatives=' + computeAlternative + '&' +
				'geometry=polyline&access_token=' + this._accessToken;
		},

		_locationKey: function(location) {
			return location.lng + ',' + location.lat;
		},

		_convertSummary: function(route) {
			return {
				totalDistance: route.distance,
				totalTime: route.duration
			};
		},

		_convertInstructions: function(steps, stepIndices) {
			var result = [],
			    i,
			    step,
			    type;

			for (i = 0; i < steps.length; i++) {
				step = steps[i];
				type = this._drivingDirectionType(step.maneuver);
				if (type) {
					result.push({
						type: type,
						distance: step.distance,
						time: step.duration,
						road: step.way_name,
						direction: step.direction,
						index: stepIndices[i]
					});
				}
			}

			return result;
		},

		_drivingDirectionType: function(maneuver) {
			switch (maneuver.type) {
			case 'continue':
				return 'Straight';
			case 'bear right':
				return 'SlightRight';
			case 'turn right':
				return 'Right';
			case 'sharp right':
				return 'SharpRight';
			case 'u-turn':
				return 'TurnAround';
			case 'sharp left':
				return 'SharpLeft';
			case 'turn left':
				return 'Left';
			case 'bear left':
				return 'SlightLeft';
			case 'waypoint':
				return 'WaypointReached';
			case 'depart':
				return 'Straight';
			case 'enter roundabout':
				return 'Roundabout';
			case 'arrive':
				return 'DestinationReached';
			default:
				return null;
			}
		},

		_mapWaypointIndices: function(waypoints, instructions, coordinates) {
			var wpIndices = [],
				stepIndices = [],
				wpIndex = 0,
				stepIndex = 0,
				wp = waypoints[wpIndex],
				stepCoord = instructions[stepIndex].maneuver.location.coordinates,
			    i,
			    c;

			for (i = 0; i < coordinates.length; i++) {
				c = coordinates[i];
				if (Math.abs(c[0] - wp.latLng.lat) < 1e-5 &&
					Math.abs(c[1] - wp.latLng.lng) < 1e-5) {
					wpIndices.push(i);
					wp = waypoints[++wpIndex];
				}
				if (stepCoord && Math.abs(c[0] - stepCoord[1]) < 1e-5 &&
					Math.abs(c[1] - stepCoord[0]) < 1e-5) {
					stepIndices.push(i);
					stepIndex++;
					stepCoord = instructions[stepIndex] && instructions[stepIndex].maneuver.location.coordinates;
				}
			}

			return {
				waypointIndices: wpIndices,
				stepIndices: stepIndices
			};
		}
	});

	L.Routing.mapbox = function(accessToken, options) {
		return new L.Routing.Mapbox(accessToken, options);
	};

	module.exports = L.Routing.Mapbox;
})();
<|endoftext|>


<commit_before>/**
 * IrcPostController
 *
 * @description :: Server-side logic for managing ircposts
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */
var Promise = require('bluebird');
var ValidationError = require('../lib/exceptions/ValidationError');

module.exports = {

  /**
   * `IrcPostController.index()`
   */
  index: function (req, res) {
    return IrcRequestValidatorService.validate(req.body)
      .catch(ValidationError, res.badRequest)
      .tap(this.process_operation)
      .tap(this.process_bed_counts)
      .catch(res.serverError)
      .finally(function () {
        return res.ok();
      });
  },

  process_operation: function (request_body) {
    return this['process_operation_' + request_body.operation];
  },

  process_operation_ooc: function (request_body) {
    return request_body;
  },
  process_operation_bic: function (request_body) {
    return request_body;
  },
  process_operation_in: function (request_body) {
    return request_body;
  },
  process_operation_out: function (request_body) {
    return request_body;
  },
  process_operation_tra: function (request_body) {
    return request_body;
  },
  process_bed_counts: function (request_body) {
    return Centre.findOne({name: request_body.centre})
      .then(function (centre) {
        centre.male_in_use = request_body.bed_counts.male;
        centre.female_in_use = request_body.bed_counts.female;
        centre.male_out_of_commission = request_body.bed_counts.out_of_commission.ooc_male;
        centre.female_out_of_commission = request_body.bed_counts.out_of_commission.ooc_female;
        return centre.save();
      }).finally(function () {
        return request_body;
      });
  },
};
<commit_msg>better flow control through exception handlers for irc receiver<commit_after>/**
 * IrcPostController
 *
 * @description :: Server-side logic for managing ircposts
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */
var Promise = require('bluebird');
var ValidationError = require('../lib/exceptions/ValidationError');

module.exports = {

  /**
   * `IrcPostController.index()`
   */
  index: function (req, res) {
    var response = IrcRequestValidatorService.validate(req.body)
      .tap(this.process_operation)
      .tap(this.process_bed_counts)
      .catch(ValidationError, function (error) {
        res.badRequest(error.message);
        return response.cancel();
      })
      .catch(function (error) {
        res.serverError(error.message);
        return response.cancel();
      })
      .then(res.ok);
    return response;
  },

  process_operation: function (request_body) {
    return this['process_operation_' + request_body.operation];
  },

  process_operation_ooc: function (request_body) {
    return request_body;
  },
  process_operation_bic: function (request_body) {
    return request_body;
  },
  process_operation_in: function (request_body) {
    return request_body;
  },
  process_operation_out: function (request_body) {
    return request_body;
  },
  process_operation_tra: function (request_body) {
    return request_body;
  },
  process_bed_counts: function (request_body) {
    return Centre.findOne({name: request_body.centre})
      .then(function (centre) {
        centre.male_in_use = request_body.bed_counts.male;
        centre.female_in_use = request_body.bed_counts.female;
        centre.male_out_of_commission = request_body.bed_counts.out_of_commission.ooc_male;
        centre.female_out_of_commission = request_body.bed_counts.out_of_commission.ooc_female;
        return centre.save();
      }).finally(function () {
        return request_body;
      });
  },
};
<|endoftext|>


<commit_before>module.exports = {

  destroy: function(req, res) {
    req.session.authenticated = false;

    // now sign out of Play! janky janky janky.
    res.redirect('/logout');
  }

}<commit_msg>log out properly<commit_after>module.exports = {

  destroy: function(req, res) {
    req.session.destroy();

    // now sign out of Play! janky janky janky.
    res.redirect('/logout');
  }

}<|endoftext|>


<commit_before>/**
 * UpdatesController
 *
 * @description :: Server-side logic for managing Updates
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

module.exports = {

    update: function (req, res) {
        var update = req.body;
        var userId = update.message.from.id;
        var userName = update.message.from.first_name;
        if (update.message.text) {
            var text = update.message.text;

            sails.log.debug("Message: ", update.message.text);
            var command = commands.processIt(text);
            sails.log.debug("Command: ", command);

            if (command) {
                telegram.sendMessage(userId, "Comando procesado correctamente, commandID: " + command).then(
                    function (response) {

                    }, function (error) {
                        sails.log.error("Failed", error);
                    }
                );
            }

        } else if (update.message.photo) {
            sails.log.info("Photo content: ", update.message.photo);
            telegram.sendMessage(userId, "Ahora clasifica la foto...", "",true, null, null).then(
                function (response) {

                }, function (error) {
                    sails.log.error("Failed", error);
                }
            ).then(
                telegram.sendMessage(userId, "Si la información está relacionada con:" +
                    "```Campañas de comunicación institucionales o con medios de comunicación, *pulsa A*.``" +
                    "```Acceso y permanencia en el sistema educativo o con el Tercer Sector, *pulsa B*.``" +
                    "```Reducción de las desigualdades y la exclusión social, *pulsa C*.``" +
                    "```Transparencia, participación ciudadanía o rendición de cuentas, *pulsa D*.```","Markdown", true, null, keyboards.createKeyboard()).then(
                    function (response) {

                    }, function (error) {
                        sails.log.error("Failed", error);
                    }
                )
            );
        } else {
            telegram.sendMessage(userId, "Ups, eso no me lo esperaba... ¿Te has equivocado?").then(
                function (response) {

                }, function (error) {
                    sails.log.error("Failed", error);
                }
            );
        }
        res.json(200);

        /*
         Updates.create(req.body).exec(function(err, message){
         if (err) {
         sails.log.error("Web Hook --> Error", err)
         }
         if (message) {
         sails.log("OK");
         }
         })
         */
    }
};

<commit_msg>Fixes<commit_after>/**
 * UpdatesController
 *
 * @description :: Server-side logic for managing Updates
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

module.exports = {

    update: function (req, res) {
        var update = req.body;
        var userId = update.message.from.id;
        var userName = update.message.from.first_name;
        if (update.message.text) {
            var text = update.message.text;

            sails.log.debug("Message: ", update.message.text);
            var command = commands.processIt(text);
            sails.log.debug("Command: ", command);

            if (command) {
                telegram.sendMessage(userId, "Comando procesado correctamente, commandID: " + command).then(
                    function (response) {

                    }, function (error) {
                        sails.log.error("Failed", error);
                    }
                );
            }

        } else if (update.message.photo) {
            sails.log.info("Photo content: ", update.message.photo);
            telegram.sendMessage(userId, "Ahora clasifica la foto...", "",true, null, null).then(
                function (response) {
                    telegram.sendMessage(userId, "Si la información está relacionada con:" +
                        "```Campañas de comunicación institucionales o con medios de comunicación, *pulsa A*.``" +
                        "```Acceso y permanencia en el sistema educativo o con el Tercer Sector, *pulsa B*.``" +
                        "```Reducción de las desigualdades y la exclusión social, *pulsa C*.``" +
                        "```Transparencia, participación ciudadanía o rendición de cuentas, *pulsa D*.```","Markdown", true, null, keyboards.createKeyboard()).then(
                        function (response) {

                        }, function (error) {
                            sails.log.error("Failed", error);
                        }
                    )

                }, function (error) {
                    sails.log.error("Failed", error);
                }
            );

        } else {
            telegram.sendMessage(userId, "Ups, eso no me lo esperaba... ¿Te has equivocado?").then(
                function (response) {

                }, function (error) {
                    sails.log.error("Failed", error);
                }
            );
        }
        res.json(200);

        /*
         Updates.create(req.body).exec(function(err, message){
         if (err) {
         sails.log.error("Web Hook --> Error", err)
         }
         if (message) {
         sails.log("OK");
         }
         })
         */
    }
};

<|endoftext|>


<commit_before>var largeCircle = new Path.Circle([676, 433], 100);

largeCircle.fillColor = 'black';
largeCircle.strokeColor = 'black';
largeCircle.strokeWidth = 8;
largeCircle.visible = false;

var placed = false;

var text = new PointText(view.center);
text.fillColor = 'white';
text.characterStyle.fontSize = 35;
text.paragraphStyle.justification = 'center';
text.content = 'PubNub';

var group = new Group([largeCircle, text]);

function onMouseMove(event) {
  if (placed === false) {
    largeCircle.position = event.point;
    text.position = largeCircle.bounds.center;
  }
}

function onFrame(event) {
  if (placed === false) {
    largeCircle.rotate(1);
  }
  else {
    group.scale(.99);
  }
}

function onMouseDown(event) {

  if (placed === true) {
    hit_result = group.hitTest(event.point);
    if ((hit_result !== null) && (hit_result !== undefined)) {
      group.scale(1.5);
    }
  }

  if (placed === false) {
    placed = true;
    largeCircle.opacity = 1;
    largeCircle.position = event.point;
    largeCircle.dashArray = [14, 0];
    text.position = event.point;
  }
}

$("#place").click( function(e) {
  e.preventDefault();
  placed = false;
  text.content = $("#bubble_text").val();
  largeCircle.visible = true;
  largeCircle.dashArray = [14, 4];
  largeCircle.opacity = .5;
});

<commit_msg>I like underscores more than camelCase<commit_after>var placed = false;

var large_circle = new Path.Circle([676, 433], 100);
large_circle.fillColor = 'black';
large_circle.strokeColor = 'black';
large_circle.strokeWidth = 8;
large_circle.visible = false;

var text = new PointText(view.center);
text.fillColor = 'white';
text.characterStyle.fontSize = 35;
text.paragraphStyle.justification = 'center';
text.content = 'PubNub';

var group = new Group([large_circle, text]);

function onMouseMove(event) {
  if (placed === false) {
    large_circle.position = event.point;
    text.position = large_circle.bounds.center;
  }
}

function onFrame(event) {
  if (placed === false) {
    large_circle.rotate(1);
  }
  else {
    group.scale(.99);
  }
}

function onMouseDown(event) {

  if (placed === true) {
    hit_result = group.hitTest(event.point);
    if ((hit_result !== null) && (hit_result !== undefined)) {
      group.scale(1.5);
    }
  }

  if (placed === false) {
    placed = true;
    large_circle.opacity = 1;
    large_circle.position = event.point;
    large_circle.dashArray = [14, 0];
    text.position = event.point;
  }
}

$("#place").click( function(e) {
  e.preventDefault();

  placed = false;

  text.content = $("#bubble_text").val();
  large_circle.visible = true;
  large_circle.dashArray = [14, 4];
  large_circle.opacity = .5;
});

<|endoftext|>


<commit_before>var m = require('mithril');
var header = require('./header');
var DefaultSettings = require('./models/default-settings');

var defaultSettings = {
  controller: function() {
    this.settings = DefaultSettings.get();

    this.onChange = function(cb) {
      return function(event) {
        cb(event);
        this.settings.save();
      }.bind(this);
    };

    this.circumference = function() {
      return '42,000,000 KM';
    };

    this.bikeOptions = [2, 4];
    this.unitsOfMeasureOptions = [
      {label: 'US', value: 'us'},
      {label: 'Metric', value: 'metric'}
    ];
  },
  view: function(ctrl) {
    return m('.container-fluid', [
      m.component(header),
      m('.container', [
        m('h4', 'Default Settings'),

        m('.row', [
          // # of Bikes Select
          m('.col-xs-12 col-sm-6', [
            m('.input-group.inline', [
              m('label', [
                'Number of Bikes ',
                m('select', {
                  onchange: ctrl.onChange(function(event) {
                    ctrl.settings.bikes = parseInt(event.target.value);
                  })
                },
                ctrl.bikeOptions.map(function(option){
                  return m('option', {
                    selected: option === ctrl.settings.bikes,
                    value: option
                  }, option);
                }))
              ])
            ])
          ]),

          // Distance/Speed Select
          m('.col-xs-12 col-sm-6', [
            m('.input-group.inline', [
              m('label', [
                'Distance/Speed Units ',
                m('select', {
                  onchange: ctrl.onChange(function(event) {
                    ctrl.settings.unitsOfMeasure = event.target.value;
                  })
                },
                ctrl.unitsOfMeasureOptions.map(function(option) {
                  return m('option', {
                    selected: option.value === ctrl.settings.unitsOfMeasure,
                    value: option.value
                  }, option.label);
                }))
              ])
            ])
          ])
        ]),

        m('.row', [
          m('.col-xs-12 col-sm-6', [
            m('.input-group.inline', [
              m('label', [
                'Roller Diameter ',
                m('input', {type: 'text'})
              ]),
              m('select', [
                m('option', 'in'),
                m('option', 'cm')
              ])
            ])
          ]),
          m('.col-xs-12 col-sm-6', [
            m('.input-group.inline', [
              m('label', [
                'Race Distance ',
                m('input', {type: 'number'})
              ])
            ])
          ])
        ]),
        m('.row', [
          m('.col-xs-12 col-sm-6', [
            m('.input-group.inline',
              m('label.control-label', [
                'Circumference ',
                m('span', ctrl.circumference())
              ])
            )
          ]),
          //m('.col-xs-12 col-sm-6', [
          //  m('.input-group.inline',
          //    m('label.control-label', [
          //      'Time Display ',
          //      m('span', '????')
          //    ])
          //  )
          //])
        ]),
        m('.row', [
          m('.col-xs-12', [
            m('.input-group',
              m('label.control-label', [
                'Winner\'s Message (max 25 characters) ',
                m('input', {type: 'text'})
              ])
            )
          ])
        ])
      ])
    ]);
  }
};

module.exports = defaultSettings;<commit_msg>Changing layout of default settings<commit_after>var m = require('mithril');
var header = require('./header');
var DefaultSettings = require('./models/default-settings');

var defaultSettings = {
  controller: function() {
    this.settings = DefaultSettings.get();

    this.onChange = function(cb) {
      return function(event) {
        cb(event);
        this.settings.save();
      }.bind(this);
    };

    this.circumference = function() {
      return '42,000,000 KM';
    };

    this.bikeOptions = [2, 4];
    this.unitsOfMeasureOptions = [
      {label: 'US', value: 'us'},
      {label: 'Metric', value: 'metric'}
    ];
  },
  view: function(ctrl) {
    return m('.container-fluid', [
      m.component(header),
      m('.container', [
        m('h4', 'Default Settings'),

        m('.row', [
          // # of Bikes Select
          m('.col-xs-12.col-sm-6', [

            m('.row', [
              m('.input-group.inline', [
                m('label', [
                  'Number of Bikes ',
                  m('select', {
                    onchange: ctrl.onChange(function(event) {
                      ctrl.settings.bikes = parseInt(event.target.value);
                    })
                  },
                  ctrl.bikeOptions.map(function(option){
                    return m('option', {
                      selected: option === ctrl.settings.bikes,
                      value: option
                    }, option);
                  }))
                ])
              ])
            ]),

            m('.row', [
              m('.input-group.inline', [
                m('label', [
                  'Roller Diameter ',
                  m('input', {type: 'text'})
                ]),
                m('select', [
                  m('option', 'in'),
                  m('option', 'cm')
                ])
              ])
            ])

          ]),

          m('.col-xs-12.col-sm-6', [

            m('.row', [
              m('.input-group.inline', [
                m('label', [
                  'Distance/Speed Units ',
                  m('select', {
                    onchange: ctrl.onChange(function(event) {
                      ctrl.settings.unitsOfMeasure = event.target.value;
                    })
                  },
                  ctrl.unitsOfMeasureOptions.map(function(option) {
                    return m('option', {
                      selected: option.value === ctrl.settings.unitsOfMeasure,
                      value: option.value
                    }, option.label);
                  }))
                ])
              ])
            ]),

            m('.row', [
              m('.input-group.inline', [
                m('label', [
                  'Race Distance ',
                  m('input', {type: 'number'})
                ])
              ])
            ])
          ])
        ])
      ])
    ]);
  }
};

module.exports = defaultSettings;<|endoftext|>


<commit_before>'use strict';

import * as _ from 'lodash'
import * as React from 'react'
import * as humanize from 'humanize-plus'

import {DragDropMixin} from 'react-dnd'
import itemTypes from '../models/itemTypes'
import semesterName from '../helpers/semesterName'

let thisYear = new Date().getYear()

var Course = React.createClass({
	displayName: 'Course',
	mixins: [DragDropMixin],

	configureDragDrop(registerType) {
		registerType(itemTypes.COURSE, {
			dragSource: {
				beginDrag() {
					return {
						item: {clbid: this.props.info.clbid}
					}
				},
				endDrag(didDrop) {
					if (didDrop) {
						if (this.props.schedule) {
							console.log(
								'removing course', this.props.info.clbid,
								'from', this.props.schedule.id)
							this.props.schedule.removeCourse(this.props.info.clbid)
						}
					}
				}
			}
		})
	},

	getInitialState() {
		return {
			showTools: false
		}
	},

	showTools() {
		console.log('show tools')
		this.setState({
			showTools: true
		})
		// FIXME: Fix this. It won't stay open long enough for someone to select something from the dropdown.
		// TODO: Replace this with a real solution for hiding the tools *after an action*
		setTimeout(this.hideTools, 1500)
	},

	hideTools() {
		console.log('show tools')
		this.setState({
			showTools: false
		})
	},

	removeFromSemester() {
		this.props.schedule.removeCourse(this.props.info.clbid)
	},

	render() {
		let course = this.props.info;
		let title = course.type === 'Topic' ? course.name : course.title;

		let titleEl = React.createElement('h1', {className: 'title'}, title)

		let identifier = React.createElement('span', {className: 'identifier'}, course.dept, ' ', course.num, course.sect)
		let professors = React.createElement('span', {className: 'professors'}, humanize.oxford(course.profs))

		let details;
		if (this.state.showTools) {
			let tools = []
			if (this.props.schedule) {
				let semesterList = React.createElement('select', {className: 'semester-select'}, _.map(this.props.semesters, s => {
					return React.createElement('option', {value: s.id, key: s.id}, s.year + '-' + s.semester)
				}))
				tools.push(semesterList)
			}
			let deleteButton = React.createElement('button', {className: 'remove-course', onClick: this.removeFromSemester}, 'Remove Course')
			tools.push(deleteButton)
			details = React.createElement('span', {className: 'details'}, React.createElement('span', null, tools))
		} else {
			details = React.createElement('span', {className: 'details'}, identifier, professors)
		}

		let warnings = []
		if (this.props.schedule && course.year !== this.props.schedule.year && this.props.schedule.year <= thisYear) {
			warnings.push({msg: 'This course (from ' + course.year + ') is not offered in this year.'})
		}
		if (this.props.schedule && course.sem !== this.props.schedule.semester) {
			warnings.push({msg: 'This course (from ' + semesterName(course.sem) + ') is not offered in this semester.', icon: 'ios7-calendar-outline'})
		}
		if (this.props.conflicts && !_.isUndefined(this.props.index)) {
			let i = this.props.index;
			if (_.any(this.props.conflicts[i])) {
				let conflictIndex = _.findIndex(this.props.conflicts[i], item => item === true)
				conflictIndex = conflictIndex + 1; // because humans don't 0-index lists
				warnings.push({msg: 'This course has a time conflict with the ' + humanize.ordinal(conflictIndex) + ' course.', icon: 'ios7-clock-outline'})
			}
		}
		let warningEls;
		if (warnings.length) {
			// console.log(warnings, course.title, course.year, this.props.schedule.year,course.semester, this.props.schedule.semester)
			warningEls = React.createElement('span', {
				title: _.map(warnings, w => '- ' + w.msg + '\n')},
				_.map(warnings, w => {
					let icon = w.icon ? w.icon : 'alert-circled';
					return React.createElement('i', {className: 'ion-' + icon, key: icon})
				}))
		}

		return React.createElement('article',
			_.extend({
				className: 'course',
				onClick: this.showTools,
			}, this.dragSourceFor(itemTypes.COURSE)),

			React.createElement('div', {className: 'info-rows'}, titleEl, details),
			React.createElement('div', {className: 'warnings'}, warningEls)
		);
	}
})

var EmptyCourseSlot = React.createClass({
	displayName: 'EmptyCourseSlot',
	render() {
		let title = 'Empty Slot ' + this.props.index

		let titleEl = React.createElement('h1', {className: 'title'}, title)
		let details = React.createElement('span', {className: 'details'}, 'no details')

		return React.createElement('article', {className: 'course empty'},
			React.createElement('div', {className: 'info-rows'}, titleEl, details));
	}
})

export default Course
export {EmptyCourseSlot}
<commit_msg>Pull warning generation into its own function - Fix the year warning (getYear returns a 3-digit value, not a 4-digit) - Put getFullYear into the findWarnings method<commit_after>'use strict';

import * as _ from 'lodash'
import * as React from 'react'
import * as humanize from 'humanize-plus'

import {DragDropMixin} from 'react-dnd'
import itemTypes from '../models/itemTypes'
import semesterName from '../helpers/semesterName'

var Course = React.createClass({
	displayName: 'Course',
	mixins: [DragDropMixin],

	configureDragDrop(registerType) {
		registerType(itemTypes.COURSE, {
			dragSource: {
				beginDrag() {
					return {
						item: {clbid: this.props.info.clbid}
					}
				},
				endDrag(didDrop) {
					if (didDrop) {
						if (this.props.schedule) {
							console.log(
								'removing course', this.props.info.clbid,
								'from', this.props.schedule.id)
							this.props.schedule.removeCourse(this.props.info.clbid)
						}
					}
				}
			}
		})
	},

	getInitialState() {
		return {
			showTools: false
		}
	},

	showTools() {
		console.log('show tools')
		this.setState({
			showTools: true
		})
		// FIXME: Fix this. It won't stay open long enough for someone to select something from the dropdown.
		// TODO: Replace this with a real solution for hiding the tools *after an action*
		setTimeout(this.hideTools, 1500)
	},

	hideTools() {
		console.log('show tools')
		this.setState({
			showTools: false
		})
	},

	removeFromSemester() {
		this.props.schedule.removeCourse(this.props.info.clbid)
	},

	findWarnings() {
		let thisYear = new Date().getFullYear();
		let course = this.props.info;

		console.log(course.deptnum, 'courseYear', course.year, 'schedYear', this.props.schedule.year, 'thisYear', thisYear);

		let warnings = [];
		if (this.props.schedule && (course.year !== this.props.schedule.year) && this.props.schedule.year <= thisYear) {
			warnings.push({msg: 'This course (from ' + course.year + ') is not offered in this year.'})
		}
		if (this.props.schedule && course.sem !== this.props.schedule.semester) {
			warnings.push({msg: 'This course (from ' + semesterName(course.sem) + ') is not offered in this semester.', icon: 'ios7-calendar-outline'})
		}

		if (this.props.conflicts && !_.isUndefined(this.props.index)) {
			let i = this.props.index;
			if (_.any(this.props.conflicts[i])) {
				let conflictIndex = _.findIndex(this.props.conflicts[i], item => item === true)
				conflictIndex = conflictIndex + 1; // because humans don't 0-index lists
				warnings.push({msg: 'This course has a time conflict with the ' + humanize.ordinal(conflictIndex) + ' course.', icon: 'ios7-clock-outline'})
			}
		}

		// console.log(warnings, course.title, course.year, this.props.schedule.year,course.semester, this.props.schedule.semester)
		let warningEls = React.createElement('span',
			{title: _.map(warnings, w => '- ' + w.msg + '\n')},
			_.map(warnings, w => {
				let icon = w.icon ? w.icon : 'alert-circled';
				return React.createElement('i', {className: 'ion-' + icon, key: icon})
			}))

		return warnings.length ? warningEls : null;
	},

	render() {
		let course = this.props.info;
		let title = course.type === 'Topic' ? course.name : course.title;

		let titleEl = React.createElement('h1', {className: 'title'}, title)

		let identifier = React.createElement('span', {className: 'identifier'}, course.dept, ' ', course.num, course.sect)
		let professors = React.createElement('span', {className: 'professors'}, humanize.oxford(course.profs))

		let details;
		if (this.state.showTools) {
			let tools = []
			if (this.props.schedule) {
				let semesterList = React.createElement('select', {className: 'semester-select'}, _.map(this.props.semesters, s => {
					return React.createElement('option', {value: s.id, key: s.id}, s.year + '-' + s.semester)
				}))
				tools.push(semesterList)
			}
			let deleteButton = React.createElement('button', {className: 'remove-course', onClick: this.removeFromSemester}, 'Remove Course')
			tools.push(deleteButton)
			details = React.createElement('span', {className: 'details'}, React.createElement('span', null, tools))
		} else {
			details = React.createElement('span', {className: 'details'}, identifier, professors)
		}

		let warnings = this.findWarnings();

		return React.createElement('article',
			_.extend({
				className: 'course',
				onClick: this.showTools,
			}, this.dragSourceFor(itemTypes.COURSE)),

			React.createElement('div', {className: 'info-rows'}, titleEl, details),
			React.createElement('div', {className: 'warnings'}, warnings)
		);
	}
})

var EmptyCourseSlot = React.createClass({
	displayName: 'EmptyCourseSlot',
	render() {
		let title = 'Empty Slot ' + this.props.index

		let titleEl = React.createElement('h1', {className: 'title'}, title)
		let details = React.createElement('span', {className: 'details'}, 'no details')

		return React.createElement('article', {className: 'course empty'},
			React.createElement('div', {className: 'info-rows'}, titleEl, details));
	}
})

export default Course
export {EmptyCourseSlot}
<|endoftext|>


<commit_before>import Vue  from 'vue';
import moment from 'moment';
import $ from 'jquery';
import _ from 'lodash';

import 'jquery.scrollto';
import 'bootstrap-loader/extractStyles';

import '../stylesheets/application.css';

$(function() {
  if (window.DATA === undefined || window.DATA.type != 'schedule') {
    return;
  }

  let tabs = [
    {
      hash: 'timetable',
      tabElement: $('#timetable-tab'),
      contentElement: $('#timetable')
    },
    {
      hash: 'character',
      tabElement: $('#character-tab'),
      contentElement: $('#character')
    }
  ];
  let twitterTab = {
    hash: 'twitter',
    tabElement: $('#twitter-tab'),
    contentElement: $('#twitter')
  };
  if (twitterTab.tabElement.length !== 0) {
    tabs.push(twitterTab);
  }

  let updateTab = function(hash) {
    let tab = (function() {
      let i, n = tabs.length;
      for (i = 0; i < n; ++i) {
        if (hash.indexOf('#' + tabs[i].hash + '/') === 0) {
          return tabs[i];
        }
      }
    })();
    if (tab === undefined) {
      tab = tabs[0];
    }

    tabs.filter(t => t.hash != tab.hash).forEach(t => {
      t.tabElement.removeClass('active');
      t.contentElement.hide();
    });
    tab.tabElement.addClass('active');
    tab.contentElement.show();
  };

  let hashchange = function() {
    updateTab(location.hash);
  };

  $(window).on('hashchange', hashchange).triggerHandler('hashchange');

  $(document).on('click', 'a[href^="#"]', function() {
    let hash = $(this).attr('href');

    updateTab(hash);

    $(window).off('hashchange', hashchange);
    location.hash = hash;
    $(window).on('hashchange', hashchange);

    let target = $('*[name="' + decodeURI(hash.substring(1)) + '"]');
    if (target.length > 0) {
      $.scrollTo(target);
    }
    return false;
  });

  Vue.filter('to_time', function(value) {
    return moment(value).format('HH:mm');
  });

  let groupGreetings = function(greetings) {
    let table = {};
    _.each(greetings, greeting => {
      if (!(greeting.end_at in table)) {
        table[greeting.end_at] = {};
      }
      if (!(greeting.start_at in table[greeting.end_at])) {
        table[greeting.end_at][greeting.start_at] = [];
      }
      table[greeting.end_at][greeting.start_at].push(greeting);
    });

    let result = [];
    _.chain(table).keys().each(end_at => {
      _.chain(table[end_at]).keys().each(start_at => {
        result.push({
          start_at: start_at,
          end_at: end_at,
          greetings: table[end_at][start_at]
        });
      });
    });
    return result;
  };

  let vm = new Vue({
    el: '#contents',
    data: {
      rawGreetings: window.DATA.greetings,
      epoch: +new Date()
    },
    created: function() {
      setInterval(() => {
        if (moment().format('YYYY-MM-DD') == window.DATA.date) {
          $.ajax({
            url: '/api/schedule/' + moment(window.DATA.date).format('YYYY/MM/DD') + '/',
            dataType: 'json'
          }).done(data => {
            vm.$set('rawGreetings', data);
          });
        }
      }, 5 * 60 * 1000);

      setInterval(() => {
        let date;
        if (moment(date).format('YYYY-MM-DD') == window.DATA.date) {
          date = new Date();
          date.setMinutes(Math.floor(date.getMinutes() / 5) * 5);
          date.setSeconds(0);
          date.setMilliseconds(0);
        }
        else {
          date = moment(window.DATA.date).add(1, 'days').toDate();
        }
        vm.$data.epoch = +date;
      }, 1000);
    },
    computed: {
      groupedGreetingsDeleted: function() {
        return groupGreetings(_.filter(this.rawGreetings, greeting => greeting.deleted));
      },
      groupedGreetingsBeforeTheStart: function() {
        let epoch = this.epoch;

        return groupGreetings(_.filter(this.rawGreetings, greeting => {
          return !greeting.deleted && epoch < (+new Date(greeting.start_at));
        }));
      },
      groupedGreetingsInSession: function() {
        let epoch = this.epoch;

        return groupGreetings(_.filter(this.rawGreetings, greeting => {
          return !greeting.deleted && epoch >= (+new Date(greeting.start_at)) && epoch < (+new Date(greeting.end_at));
        }));
      },
      groupedGreetingsAfterTheEnd: function() {
        let epoch = this.epoch;

        return groupGreetings(_.filter(this.rawGreetings, greeting => {
          return !greeting.deleted && epoch >= (+new Date(greeting.end_at));
        }));
      },
      groupedGreetingsByCharacter: function() {
        let grouped = {};
        _.chain(this.rawGreetings).filter(greeting => !greeting.deleted).each(greeting => {
          _.each(greeting.characters, character => {
            if (!(character.name in grouped)) {
              grouped[character.name] = [];
            }
            grouped[character.name].push(greeting);
          });
        });

        return _.chain(grouped).toPairs().map(pair => {
          return {
            character: _.find(pair[1][0].characters, character => character.name == pair[0]),
            greetings: pair[1]
          };
        }).value();
      }
    }
  });
});

$(function() {
  $('#report-form').submit(function() {
    let place = $('select[name="place_id"] option:selected', this).text();
    let character = $('select[name="character_id"] option:selected', this).text();
    let status = place + ' で ' + character + ' に会ったよ！';
    let width = 575;
    let height = 400;
    let left = ($(window).width() - width) / 2;
    let top = ($(window).height() - height) / 2;
    window.open(
      'https://twitter.com/share?via=puro_greeting&' + [
        'text=' + encodeURIComponent(status),
        'url=',
        'hashtags=' + encodeURIComponent('ピューログリ')
      ].join('&'),
      'twitter',
      [
        'status=1',
        'width=' + width,
        'height=' + height,
        'left=' + left,
        'top=' + top
      ].join(',')
    );
    return false;
  });
});
<commit_msg>Refactor<commit_after>import Vue  from 'vue';
import moment from 'moment';
import $ from 'jquery';
import _ from 'lodash';

import 'jquery.scrollto';
import 'bootstrap-loader/extractStyles';

import '../stylesheets/application.css';

$(function() {
  if (window.DATA === undefined || window.DATA.type != 'schedule') {
    return;
  }

  let tabs = [
    {
      hash: 'timetable',
      tabElement: $('#timetable-tab'),
      contentElement: $('#timetable')
    },
    {
      hash: 'character',
      tabElement: $('#character-tab'),
      contentElement: $('#character')
    }
  ];
  let twitterTab = {
    hash: 'twitter',
    tabElement: $('#twitter-tab'),
    contentElement: $('#twitter')
  };
  if (twitterTab.tabElement.length !== 0) {
    tabs.push(twitterTab);
  }

  let updateTab = function(hash) {
    let tab = (function() {
      let i, n = tabs.length;
      for (i = 0; i < n; ++i) {
        if (hash.indexOf('#' + tabs[i].hash + '/') === 0) {
          return tabs[i];
        }
      }
    })();
    if (tab === undefined) {
      tab = tabs[0];
    }

    tabs.filter(t => t.hash != tab.hash).forEach(t => {
      t.tabElement.removeClass('active');
      t.contentElement.hide();
    });
    tab.tabElement.addClass('active');
    tab.contentElement.show();
  };

  let hashchange = function() {
    updateTab(location.hash);
  };

  $(window).on('hashchange', hashchange).triggerHandler('hashchange');

  $(document).on('click', 'a[href^="#"]', function() {
    let hash = $(this).attr('href');

    updateTab(hash);

    $(window).off('hashchange', hashchange);
    location.hash = hash;
    $(window).on('hashchange', hashchange);

    let target = $('*[name="' + decodeURI(hash.substring(1)) + '"]');
    if (target.length > 0) {
      $.scrollTo(target);
    }
    return false;
  });

  Vue.filter('to_time', function(value) {
    return moment(value).format('HH:mm');
  });

  let groupGreetings = function(greetings) {
    let table = {};
    _.each(greetings, greeting => {
      if (!(greeting.end_at in table)) {
        table[greeting.end_at] = {};
      }
      if (!(greeting.start_at in table[greeting.end_at])) {
        table[greeting.end_at][greeting.start_at] = [];
      }
      table[greeting.end_at][greeting.start_at].push(greeting);
    });

    return _.flatMap(table, (t, end_at) => {
      return _.flatMap(t, (g, start_at) => {
        return {
          start_at: start_at,
          end_at: end_at,
          greetings: g
        };
      });
    });
  };

  let vm = new Vue({
    el: '#contents',
    data: {
      rawGreetings: window.DATA.greetings,
      epoch: +new Date()
    },
    created: function() {
      setInterval(() => {
        if (moment().format('YYYY-MM-DD') == window.DATA.date) {
          $.ajax({
            url: '/api/schedule/' + moment(window.DATA.date).format('YYYY/MM/DD') + '/',
            dataType: 'json'
          }).done(data => {
            vm.$set('rawGreetings', data);
          });
        }
      }, 5 * 60 * 1000);

      setInterval(() => {
        let date;
        if (moment(date).format('YYYY-MM-DD') == window.DATA.date) {
          date = new Date();
          date.setMinutes(Math.floor(date.getMinutes() / 5) * 5);
          date.setSeconds(0);
          date.setMilliseconds(0);
        }
        else {
          date = moment(window.DATA.date).add(1, 'days').toDate();
        }
        vm.$data.epoch = +date;
      }, 1000);
    },
    computed: {
      groupedGreetingsDeleted: function() {
        return groupGreetings(_.filter(this.rawGreetings, greeting => greeting.deleted));
      },
      groupedGreetingsBeforeTheStart: function() {
        let epoch = this.epoch;

        return groupGreetings(_.filter(this.rawGreetings, greeting => {
          return !greeting.deleted && epoch < (+new Date(greeting.start_at));
        }));
      },
      groupedGreetingsInSession: function() {
        let epoch = this.epoch;

        return groupGreetings(_.filter(this.rawGreetings, greeting => {
          return !greeting.deleted && epoch >= (+new Date(greeting.start_at)) && epoch < (+new Date(greeting.end_at));
        }));
      },
      groupedGreetingsAfterTheEnd: function() {
        let epoch = this.epoch;

        return groupGreetings(_.filter(this.rawGreetings, greeting => {
          return !greeting.deleted && epoch >= (+new Date(greeting.end_at));
        }));
      },
      groupedGreetingsByCharacter: function() {
        let characters = _.reduce(this.rawGreetings, (result, greeting) => {
          return _.reduce(greeting.characters, (result, character) => {
            result[character.id] = character;
            return result;
          }, result);
        }, {});

        let characterIdGreetingPairs = _.flatMap(this.rawGreetings, greeting => {
          return _.map(greeting.characters, character => {
            return [ character.id, greeting ];
          });
        });

        let grouped = _.reduce(characterIdGreetingPairs, (result, pair) => {
          (result[pair[0]] || (result[pair[0]] = [])).push(pair[1]);
          return result;
        }, {});

        return _.map(grouped, (greetings, id) => {
          return { character: characters[id], greetings: greetings };
        });
      }
    }
  });
});

$(function() {
  $('#report-form').submit(function() {
    let place = $('select[name="place_id"] option:selected', this).text();
    let character = $('select[name="character_id"] option:selected', this).text();
    let status = place + ' で ' + character + ' に会ったよ！';
    let width = 575;
    let height = 400;
    let left = ($(window).width() - width) / 2;
    let top = ($(window).height() - height) / 2;
    window.open(
      'https://twitter.com/share?via=puro_greeting&' + [
        'text=' + encodeURIComponent(status),
        'url=',
        'hashtags=' + encodeURIComponent('ピューログリ')
      ].join('&'),
      'twitter',
      [
        'status=1',
        'width=' + width,
        'height=' + height,
        'left=' + left,
        'top=' + top
      ].join(',')
    );
    return false;
  });
});
<|endoftext|>