<commit_before>const {flowRight} = require('lodash');
const {mapKeyValues, mapQuery} = require('@nexes/mongo-utils');
const DomainEvents = require('@tryghost/domain-events');
const OfferCodeChangeEvent = require('../domain/events/OfferCodeChange');
const OfferCreatedEvent = require('../domain/events/OfferCreated');
const Offer = require('../domain/models/Offer');
const OfferStatus = require('../domain/models/OfferStatus');

const statusTransformer = mapKeyValues({
    key: {
        from: 'status',
        to: 'active'
    },
    values: [{
        from: 'active',
        to: true
    }, {
        from: 'archived',
        to: false
    }]
});

const rejectNonStatusTransformer = input => mapQuery(input, function (value, key) {
    if (key !== 'status') {
        return;
    }

    return {
        [key]: value
    };
});

const mongoTransformer = flowRight(statusTransformer, rejectNonStatusTransformer);

/**
 * @typedef {object} BaseOptions
 * @prop {import('knex').Transaction} transacting
 */

/**
 * @typedef {object} ListOptions
 * @prop {import('knex').Transaction} transacting
 * @prop {string} filter
 */

class OfferRepository {
    /**
     * @param {{forge: (data: object) => import('bookshelf').Model<Offer.OfferProps>}} OfferModel
     * @param {{forge: (data: object) => import('bookshelf').Model<any>}} OfferRedemptionModel
     */
    constructor(OfferModel, OfferRedemptionModel) {
        /** @private */
        this.OfferModel = OfferModel;
        /** @private */
        this.OfferRedemptionModel = OfferRedemptionModel;
    }

    /**
     * @template T
     * @param {(t: import('knex').Transaction) => Promise<T>} cb
     * @returns {Promise<T>}
     */
    async createTransaction(cb) {
        return this.OfferModel.transaction(cb);
    }

    /**
     * @param {string} name
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByName(name, options) {
        const model = await this.OfferModel.findOne({name}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @param {string} code
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByCode(code, options) {
        const model = await this.OfferModel.findOne({code}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @private
     * @param {import('bookshelf').Model<any>} model
     * @param {BaseOptions} options
     * @returns {Promise<Offer>}
     */
    async mapToOffer(model, options) {
        const json = model.toJSON();

        const count = await this.OfferRedemptionModel.where({offer_id: json.id}).count('id', {
            transacting: options.transacting
        });
        return Offer.create({
            id: json.id,
            name: json.name,
            code: json.code,
            display_title: json.portal_title,
            display_description: json.portal_description,
            type: json.discount_type === 'amount' ? 'fixed' : 'percent',
            amount: json.discount_amount,
            cadence: json.interval,
            currency: json.currency,
            duration: json.duration,
            duration_in_months: json.duration_in_months,
            redemptionCount: count,
            status: json.active ? 'active' : 'archived',
            tier: {
                id: json.product.id,
                name: json.product.name
            }
        }, null);
    }

    /**
     * @param {string} id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getById(id, options) {
        const model = await this.OfferModel.findOne({id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {string} id stripe_coupon_id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getByStripeCouponId(id, options) {
        const model = await this.OfferModel.findOne({stripe_coupon_id: id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {ListOptions} options
     * @returns {Promise<Offer[]>}
     */
    async getAll(options) {
        const models = await this.OfferModel.findAll({
            ...options,
            mongoTransformer,
            withRelated: ['product']
        });

        const mapOptions = {
            transacting: options && options.transacting
        };

        const offers = models.map(model => this.mapToOffer(model, mapOptions));

        return Promise.all(offers);
    }

    /**
     * @param {Offer} offer
     * @param {BaseOptions} [options]
     * @returns {Promise<void>}
     */
    async save(offer, options) {
        /** @type any */
        const data = {
            id: offer.id,
            name: offer.name.value,
            code: offer.code.value,
            portal_title: offer.displayTitle.value || null,
            portal_description: offer.displayDescription.value || null,
            discount_type: offer.type.value === 'fixed' ? 'amount' : 'percent',
            discount_amount: offer.amount.value,
            interval: offer.cadence.value,
            product_id: offer.tier.id,
            duration: offer.duration.value.type,
            duration_in_months: offer.duration.value.type === 'repeating' ? offer.duration.value.months : null,
            currency: offer.currency ? offer.currency.value : null,
            active: offer.status.equals(OfferStatus.create('active'))
        };

        if (offer.codeChanged) {
            const event = OfferCodeChangeEvent.create({
                offerId: offer.id,
                previousCode: offer.oldCode,
                currentCode: offer.code
            });
            DomainEvents.dispatch(event);
        }

        if (offer.isNew) {
            const event = OfferCreatedEvent.create({offer});
            await this.OfferModel.add(data, options);
            DomainEvents.dispatch(event);
        } else {
            await this.OfferModel.edit(data, {...options, id: data.id});
        }
    }
}

module.exports = OfferRepository;
<commit_msg>Fixed OfferCreatedEvent being dispatched before the transaction has been committed (#391)<commit_after>const {flowRight} = require('lodash');
const {mapKeyValues, mapQuery} = require('@nexes/mongo-utils');
const DomainEvents = require('@tryghost/domain-events');
const OfferCodeChangeEvent = require('../domain/events/OfferCodeChange');
const OfferCreatedEvent = require('../domain/events/OfferCreated');
const Offer = require('../domain/models/Offer');
const OfferStatus = require('../domain/models/OfferStatus');

const statusTransformer = mapKeyValues({
    key: {
        from: 'status',
        to: 'active'
    },
    values: [{
        from: 'active',
        to: true
    }, {
        from: 'archived',
        to: false
    }]
});

const rejectNonStatusTransformer = input => mapQuery(input, function (value, key) {
    if (key !== 'status') {
        return;
    }

    return {
        [key]: value
    };
});

const mongoTransformer = flowRight(statusTransformer, rejectNonStatusTransformer);

/**
 * @typedef {object} BaseOptions
 * @prop {import('knex').Transaction} transacting
 */

/**
 * @typedef {object} ListOptions
 * @prop {import('knex').Transaction} transacting
 * @prop {string} filter
 */

class OfferRepository {
    /**
     * @param {{forge: (data: object) => import('bookshelf').Model<Offer.OfferProps>}} OfferModel
     * @param {{forge: (data: object) => import('bookshelf').Model<any>}} OfferRedemptionModel
     */
    constructor(OfferModel, OfferRedemptionModel) {
        /** @private */
        this.OfferModel = OfferModel;
        /** @private */
        this.OfferRedemptionModel = OfferRedemptionModel;
    }

    /**
     * @template T
     * @param {(t: import('knex').Transaction) => Promise<T>} cb
     * @returns {Promise<T>}
     */
    async createTransaction(cb) {
        return this.OfferModel.transaction(cb);
    }

    /**
     * @param {string} name
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByName(name, options) {
        const model = await this.OfferModel.findOne({name}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @param {string} code
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByCode(code, options) {
        const model = await this.OfferModel.findOne({code}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @private
     * @param {import('bookshelf').Model<any>} model
     * @param {BaseOptions} options
     * @returns {Promise<Offer>}
     */
    async mapToOffer(model, options) {
        const json = model.toJSON();

        const count = await this.OfferRedemptionModel.where({offer_id: json.id}).count('id', {
            transacting: options.transacting
        });
        return Offer.create({
            id: json.id,
            name: json.name,
            code: json.code,
            display_title: json.portal_title,
            display_description: json.portal_description,
            type: json.discount_type === 'amount' ? 'fixed' : 'percent',
            amount: json.discount_amount,
            cadence: json.interval,
            currency: json.currency,
            duration: json.duration,
            duration_in_months: json.duration_in_months,
            redemptionCount: count,
            status: json.active ? 'active' : 'archived',
            tier: {
                id: json.product.id,
                name: json.product.name
            }
        }, null);
    }

    /**
     * @param {string} id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getById(id, options) {
        const model = await this.OfferModel.findOne({id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {string} id stripe_coupon_id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getByStripeCouponId(id, options) {
        const model = await this.OfferModel.findOne({stripe_coupon_id: id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {ListOptions} options
     * @returns {Promise<Offer[]>}
     */
    async getAll(options) {
        const models = await this.OfferModel.findAll({
            ...options,
            mongoTransformer,
            withRelated: ['product']
        });

        const mapOptions = {
            transacting: options && options.transacting
        };

        const offers = models.map(model => this.mapToOffer(model, mapOptions));

        return Promise.all(offers);
    }

    /**
     * @param {Offer} offer
     * @param {BaseOptions} [options]
     * @returns {Promise<void>}
     */
    async save(offer, options) {
        /** @type any */
        const data = {
            id: offer.id,
            name: offer.name.value,
            code: offer.code.value,
            portal_title: offer.displayTitle.value || null,
            portal_description: offer.displayDescription.value || null,
            discount_type: offer.type.value === 'fixed' ? 'amount' : 'percent',
            discount_amount: offer.amount.value,
            interval: offer.cadence.value,
            product_id: offer.tier.id,
            duration: offer.duration.value.type,
            duration_in_months: offer.duration.value.type === 'repeating' ? offer.duration.value.months : null,
            currency: offer.currency ? offer.currency.value : null,
            active: offer.status.equals(OfferStatus.create('active'))
        };

        if (offer.codeChanged) {
            const event = OfferCodeChangeEvent.create({
                offerId: offer.id,
                previousCode: offer.oldCode,
                currentCode: offer.code
            });
            DomainEvents.dispatch(event);
        }

        if (offer.isNew) {
            await this.OfferModel.add(data, options);
            const event = OfferCreatedEvent.create({offer});

            if (options.transacting) {
                // Only dispatch the event after the transaction has finished
                // Because else the offer won't be committed to the database yet
                options.transacting.executionPromise.then(() => {
                    DomainEvents.dispatch(event);
                });
            } else {
                DomainEvents.dispatch(event);
            }
        } else {
            await this.OfferModel.edit(data, {...options, id: data.id});
        }
    }
}

module.exports = OfferRepository;
<|endoftext|>


<commit_before>class SkinnedMesh {
  constructor(geometry, materials) {
    super(geometry, materials);

    this.idMatrix = SkinnedMesh.defaultMatrix();
    this.bones = [];
    this.boneMatrices = [];
    //...
  }
  update(camera) {
    //...
    super.update();
  }
  static defaultMatrix() {
    return new THREE.Matrix4();
  }
}<commit_msg>babel<commit_after>var React = require('react');

var res = require('./content.js');

require("./style.css");

var rr = require('./re');

class SkinnedMesh {
  constructor(geometry, materials) {
    super(geometry, materials);

    this.idMatrix = SkinnedMesh.defaultMatrix();
    this.bones = [];
    this.boneMatrices = [];
    //...
  }
  update(camera) {
    //...
    super.update();
  }
  static defaultMatrix() {
    return new THREE.Matrix4();
  }
}<|endoftext|>


<commit_before>//Could've used the same controller for add and edit, but figured it would be cleaner to keep them separate even though there is redundancy.

'use strict';

angular.module('brewApp.controllers')
    .controller('EditRecipeCtrl', ['$modalInstance', 'BrewMaster', 'logger', 'notifications', 'UserStore', '$modalParams', editRecipeController]);

function editRecipeController($modalInstance, BrewMaster, logger, notifications, UserStore, $modalParams) {
    /* jshint validthis: true */
    var self = this, original = {};

    self.INGREDIENT_TYPE = { HOPS: 'hops', MALT: 'malt', YEAST: 'yeast' };

    UserStore.getCurrentUserRecipeById($modalParams.id).then(function(recipe) {
        self.recipe = angular.copy(recipe);

        UserStore.getRecipeIngredientsByRecipeId($modalParams.id).then(function(ingredients) {
            //Break out ingredients by type for UI.
            if (ingredients && ingredients.length > 0) {
                self.ingredients = [];

                for (var i = 0; i < ingredients.length; i++)
                    (self.ingredients[ingredients[i].type] = self.ingredients[ingredients[i].type] || []).push(ingredients[i]);
            }
        });
    });

    BrewMaster.getDefinitions().then(function(definitions) {
        self.units = definitions.units.volume.map(function(def) { return def.name; });

        if (BrewMaster.hasIngredient(definitions, 'yeast'))
            self.yeasts = definitions.ingredient.yeast.map(function(def) { return def.name; });
    });

    self.addIngredient = function(type, ingredient) {
        (self.ingredients[type] = self.ingredients[type] || []).push(ingredient);

        //This is pretty brittle.
        self.current[type] = null;
    };

    self.deleteIngredient = function(type, ingredient) {
        var index = self.ingredients[type]
            .map(function(i) { return i.name; })
            .indexOf(ingredient.name);

        self.ingredients[type].splice(index, 1);
    };

    self.update = function(isValid) {
        if (isValid) {
            self.recipe.ingredients = self.recipe.ingredients || [];

            for (var key in self.INGREDIENT_TYPE) {
                if (!self.INGREDIENT_TYPE.hasOwnProperty(key)) continue;

                var type = self.INGREDIENT_TYPE[key];

                if (self.ingredients[type] && self.ingredients[type].length > 0)
                    for (var i = 0; i < self.ingredients[type].length; i++) {
                        var ingredient = self.ingredients[type][i];
                        ingredient.type = type;

                        self.recipe.ingredients.push(ingredient);
                    }
            }

            //Need a spinner on this?
            UserStore.updateRecipe(self.recipe).then(function() {
                notifications.success('Recipe ' + self.recipe.name + ' updated.');
                logger.info('Recipe ' + self.recipe.recipeId + ' updated.');

                clearForm();

                $modalInstance.close();
            });
        }
    };

    self.cancel = function() {
        clearForm();

        $modalInstance.dismiss();
    };

    function clearForm() {
        self.recipeForm.$setPristine();
        self.recipe = {};
        self.ingredients = [];
    }
}
<commit_msg>Cleaned up edit recipe controller.<commit_after>//Can refactor to eliminate redundancy between this and the add recipe controller.
(function() {
    'use strict';

    angular.module('brewApp.controllers')
        .controller('EditRecipeCtrl', ['$modalInstance', 'BrewMaster', 'logger', 'notifications', 'UserStore', '$modalParams', editRecipeController]);

    function editRecipeController($modalInstance, BrewMaster, logger, notifications, UserStore, $modalParams) {
        /* jshint validthis: true */
        var self = this;

        self.INGREDIENT_TYPE = { HOPS: 'hops', MALT: 'malt', YEAST: 'yeast' };

        UserStore.getCurrentUserRecipeById($modalParams.id).then(function(recipe) {
            self.recipe = angular.copy(recipe);

            UserStore.getRecipeIngredientsByRecipeId($modalParams.id).then(function(ingredients) {
                //Break out ingredients by type for UI.
                if (ingredients && ingredients.length > 0) {
                    self.ingredients = [];

                    for (var i = 0; i < ingredients.length; i++)
                        (self.ingredients[ingredients[i].type] = self.ingredients[ingredients[i].type] || []).push(ingredients[i]);
                }
            });
        });

        BrewMaster.getDefinitions().then(function(definitions) {
            self.units = definitions.units.volume.map(function(def) { return def.name; });

            if (BrewMaster.hasIngredient(definitions, 'yeast'))
                self.yeasts = definitions.ingredient.yeast.map(function(def) { return def.name; });
        });

        self.addIngredient = function(type, ingredient) {
            (self.ingredients[type] = self.ingredients[type] || []).push(ingredient);

            //This is pretty brittle.
            self.current[type] = null;
        };

        self.deleteIngredient = function(type, ingredient) {
            var index = self.ingredients[type]
                .map(function(i) { return i.name; })
                .indexOf(ingredient.name);

            self.ingredients[type].splice(index, 1);
        };

        self.update = function(isValid) {
            if (isValid) {
                self.recipe.ingredients = self.recipe.ingredients || [];

                for (var key in self.INGREDIENT_TYPE) {
                    if (!self.INGREDIENT_TYPE.hasOwnProperty(key)) continue;

                    var type = self.INGREDIENT_TYPE[key];

                    if (self.ingredients[type] && self.ingredients[type].length > 0)
                        for (var i = 0; i < self.ingredients[type].length; i++) {
                            var ingredient = self.ingredients[type][i];
                            ingredient.type = type;

                            self.recipe.ingredients.push(ingredient);
                        }
                }

                //Need a spinner on this?
                UserStore.updateRecipe(self.recipe).then(function() {
                    notifications.success('Recipe ' + self.recipe.name + ' updated.');
                    logger.info('Recipe ' + self.recipe.recipeId + ' updated.');

                    $modalInstance.close();
                });
            }
        };

        self.cancel = function() { $modalInstance.dismiss(); };
    }
})();<|endoftext|>


<commit_before>$('.navbar-header .nav a h4').html('Resources');
// url = "/admin/apiserver/fetch/resource_instances";
url = "/api/proxy/"+slug+"/resources";
api = url;
$.ajax({
	url: url,
	success: function(data){
		if(typeof data !== 'object'){ data = []; }
		tableConfig.schema = [
			{label: 'Name', name:'name', required: true},
			{label: 'Type', name:'resource_type', required: true, type:'select',
			options:[
				{label: 'mySQL Resource',value: 'mysql'},
				{label: 'Oracle Resource', value:'oracle'},
				{label: 'Constant', value:'constant'},
			]},
			{label: 'Environment Type', name:'type', options:['dev','test','prod'], required: true},

			// {label: 'Resource', name:'resource_id',type:'select', required: true,choices:'/api/proxy/'+slug+'/resources',label_key:'name',value_key:'id'},
			{name:'config',label:'Config',show:false, template:'{{attributes.config.value}}{{attributes.config.name}}',fields:[
				{label: 'Name',name: 'name',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'Pass', name:'pass',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'User', name:'user',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'Server', name:'server',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'Value', name:'value',type:'hidden',show:{matches:{name:'type',value:'constant'}}},
			]},
			{name: 'id', type:'hidden'}
		];
		tableConfig.data = data;

		tableConfig.events=[
			{'name': 'config', 'label': ' Config', callback: function(model){

				var fields = [
					{name: 'name',type: 'hidden'},
					{name: 'id',type: 'hidden'},
					{name: 'resource_id',type: 'hidden'},
				];
				switch(model.attributes.type){
					case 'mysql':
					fields.push({name:'config',label:false,fields:[
						{label: 'Name',name: 'name'},
						{label: 'Pass', name:'pass'},
						{label: 'User', name:'user'},
						{label: 'Server', name:'server'}
					]})
					break;
					case 'constant':
					fields.push({name:'config',label:false,fields:[
						{label: 'Value',name: 'value'}
					]})
					break;
				}
				$().berry({
					legend:'Config',
					name:'config',
					model:model,
					"flatten": false,
					fields:fields
					}).on('saved',function(){
						// this.set(Berries.config.toJSON())
						this.owner.options.edit(this);
						this.owner.draw();
					}.bind(model))
			}, multiEdit: false},

		]

		tableConfig.name = "resources";
		bt = new berryTable(tableConfig)
	}
});

// {label: 'Service', name:'service_id',type:'select', required: true,choices:'/api/proxy/resources',label_key:'name',value_key:'id'},
<commit_msg>Fix resource type<commit_after>$('.navbar-header .nav a h4').html('Resources');
// url = "/admin/apiserver/fetch/resource_instances";
url = "/api/proxy/"+slug+"/resources";
api = url;
$.ajax({
	url: url,
	success: function(data){
		if(typeof data !== 'object'){ data = []; }
		tableConfig.schema = [
			{label: 'Name', name:'name', required: true},
			{label: 'Type', name:'resource_type', required: true, type:'select',
			options:[
				{label: 'mySQL Resource',value: 'mysql'},
				{label: 'Oracle Resource', value:'oracle'},
				{label: 'Constant', value:'constant'},
			]},
			{label: 'Environment Type', name:'type', options:['dev','test','prod'], required: true},

			// {label: 'Resource', name:'resource_id',type:'select', required: true,choices:'/api/proxy/'+slug+'/resources',label_key:'name',value_key:'id'},
			{name:'config',label:'Config',show:false, template:'{{attributes.config.value}}{{attributes.config.name}}',fields:[
				{label: 'Name',name: 'name',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'Pass', name:'pass',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'User', name:'user',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'Server', name:'server',type:'hidden',show:{matches:{name:'type',value:'mysql'}}},
				{label: 'Value', name:'value',type:'hidden',show:{matches:{name:'type',value:'constant'}}},
			]},
			{name: 'id', type:'hidden'}
		];
		tableConfig.data = data;

		tableConfig.events=[
			{'name': 'config', 'label': ' Config', callback: function(model){

				var fields = [
					{name: 'name',type: 'hidden'},
					{name: 'id',type: 'hidden'},
					{name: 'resource_id',type: 'hidden'},
				];
				switch(model.attributes.resource_type){
					case 'mysql':
					fields.push({name:'config',label:false,fields:[
						{label: 'Name',name: 'name'},
						{label: 'Pass', name:'pass'},
						{label: 'User', name:'user'},
						{label: 'Server', name:'server'}
					]})
					break;
					case 'constant':
					fields.push({name:'config',label:false,fields:[
						{label: 'Value',name: 'value'}
					]})
					break;
				}
				$().berry({
					legend:'Config',
					name:'config',
					model:model,
					"flatten": false,
					fields:fields
					}).on('saved',function(){
						// this.set(Berries.config.toJSON())
						this.owner.options.edit(this);
						this.owner.draw();
					}.bind(model))
			}, multiEdit: false},

		]

		tableConfig.name = "resources";
		bt = new berryTable(tableConfig)
	}
});

// {label: 'Service', name:'service_id',type:'select', required: true,choices:'/api/proxy/resources',label_key:'name',value_key:'id'},
<|endoftext|>


<commit_before>/**
 * GPII User Update Handler
 *
 * Copyright 2013 OCAD University
 *
 * Licensed under the New BSD license. You may not use this file except in
 * compliance with this License.
 *
 * You may obtain a copy of the License at
 * https://github.com/gpii/universal/LICENSE.txt
 */

(function () {

    "use strict";

    var fluid = require("infusion"),
        $ = fluid.registerNamespace("jQuery"),
        request = fluid.registerNamespace("gpii.request.flowManager");

    fluid.defaults("kettle.requests.request.handler.userUpdate", {
        gradeNames: ["fluid.littleComponent", "gpii.request.flowManager.token", "autoInit"],
        invokers: {
            handle: {
                funcName: "gpii.request.flowManager.userUpdateHandle",
                args: [
                    "{flowManager}.matchMakerDataSource",
                    "{that}.events.onMatch",
                    "{request}"
                ],
                dynamic: true
            },
            onMatchHandler: {
                funcName: "gpii.request.flowManager.onMatchUpdateHandler",
                args: [
                    "{flowManager}.lifecycleManagerServerDataSource",
                    "{requestProxy}.events.onSuccess",
                    "{request}.session.session.token",
                    "{arguments}.0",
                    "{request}.updatedPreferences"
                ]
            }
        },
        listeners: {
            onMatch: "{that}.onMatchHandler"
        }
    });

    request.deepEq = function (obj1, obj2) {
        var equal = true;
        if (!obj2) {
            return !equal;
        }
        fluid.each(obj1, function (val, key) {
            if (fluid.isPrimitive(val)) {
                equal = val === obj2[key];
            } else {
                equal = request.deepEq(val, obj2[key]);
            }
            return equal;
        });
        return equal;
    };

    request.getUpdatedPreferences = function (newPreferences, oldPreferences) {
        var togo = fluid.copy(newPreferences);
        fluid.remove_if(togo, function (val, key) {
            if (fluid.isPrimitive(val)) {
                return val === oldPreferences[key];
            } else {
                return request.deepEq(val, oldPreferences[key]);
            }
        });
        return togo;
    };

    request.userUpdateHandle = function (matchMakerDataSource, event, fluidRequest) {
        var session = fluidRequest.session.session;
        fluidRequest.updatedPreferences = request.getUpdatedPreferences(
            fluidRequest.data, session.preferences);
        request.getMatch(matchMakerDataSource, event,
            fluidRequest.updatedPreferences, session.device);
    };

    request.onMatchUpdateHandler = function (lifecycleManagerServerDataSource, event, token, match, preferences) {
        lifecycleManagerServerDataSource.set({
            operation: "update",
            token: token
        }, match, request.logAndNotify("Lifecycle manager returned: ", event));
    };

})();
<commit_msg>GPII-75: added comments for the deepEq.<commit_after>/**
 * GPII User Update Handler
 *
 * Copyright 2013 OCAD University
 *
 * Licensed under the New BSD license. You may not use this file except in
 * compliance with this License.
 *
 * You may obtain a copy of the License at
 * https://github.com/gpii/universal/LICENSE.txt
 */

(function () {

    "use strict";

    var fluid = require("infusion"),
        $ = fluid.registerNamespace("jQuery"),
        request = fluid.registerNamespace("gpii.request.flowManager");

    fluid.defaults("kettle.requests.request.handler.userUpdate", {
        gradeNames: ["fluid.littleComponent", "gpii.request.flowManager.token", "autoInit"],
        invokers: {
            handle: {
                funcName: "gpii.request.flowManager.userUpdateHandle",
                args: [
                    "{flowManager}.matchMakerDataSource",
                    "{that}.events.onMatch",
                    "{request}"
                ],
                dynamic: true
            },
            onMatchHandler: {
                funcName: "gpii.request.flowManager.onMatchUpdateHandler",
                args: [
                    "{flowManager}.lifecycleManagerServerDataSource",
                    "{requestProxy}.events.onSuccess",
                    "{request}.session.session.token",
                    "{arguments}.0",
                    "{request}.updatedPreferences"
                ]
            }
        },
        listeners: {
            onMatch: "{that}.onMatchHandler"
        }
    });

    // TODO: this needs to be replaced with the implementation based on
    // FLUID-3674 once it reaches once it's part of Infusion.
    request.deepEq = function (obj1, obj2) {
        var equal = true;
        if (!obj2) {
            return !equal;
        }
        fluid.each(obj1, function (val, key) {
            if (fluid.isPrimitive(val)) {
                equal = val === obj2[key];
            } else {
                equal = request.deepEq(val, obj2[key]);
            }
            return equal;
        });
        return equal;
    };

    request.getUpdatedPreferences = function (newPreferences, oldPreferences) {
        var togo = fluid.copy(newPreferences);
        fluid.remove_if(togo, function (val, key) {
            if (fluid.isPrimitive(val)) {
                return val === oldPreferences[key];
            } else {
                return request.deepEq(val, oldPreferences[key]);
            }
        });
        return togo;
    };

    request.userUpdateHandle = function (matchMakerDataSource, event, fluidRequest) {
        var session = fluidRequest.session.session;
        fluidRequest.updatedPreferences = request.getUpdatedPreferences(
            fluidRequest.data, session.preferences);
        request.getMatch(matchMakerDataSource, event,
            fluidRequest.updatedPreferences, session.device);
    };

    request.onMatchUpdateHandler = function (lifecycleManagerServerDataSource, event, token, match, preferences) {
        lifecycleManagerServerDataSource.set({
            operation: "update",
            token: token
        }, match, request.logAndNotify("Lifecycle manager returned: ", event));
    };

})();
<|endoftext|>


<commit_before>/*
 * Attach event listeners
 */
$(function() {

  var hovered = null;

  $(".lousList_extension").scroll(function() {
    if(hovered) {
      positionPopup(hovered);
    }
  });

  $(".lousList_extension_savedClassList_clear").on("click", function(e) {
    e.preventDefault();
    $("#lousList_extension_savedClassList ul").html("");
    sectionList = new SectionList([]);
    sectionList.save();
  });

  $(".lousList_extension_savedClassList_clear_selected").on("click", function(e) {
    e.preventDefault();
    selectedList = {};
    conflicts = {};
    $("#lousList_extension_savedClassList ul li").each(function() {
      if($(this).hasClass("conflict")) {
        $(this).removeClass("conflict");
      } else if($(this).hasClass("no-conflict")) {
        $(this).removeClass("no-conflict");
      }
    });
  });

  $(".lousList_extension_saveSection").on("click", function(e) {
    e.stopPropagation();
    e.preventDefault();
    var selectedRow = $(e.target).parents(".S"),
        sectionRowData = parseSectionRow(selectedRow),
        courseRowData = parseCourseRow(selectedRow.prevAll(".CourseInfo:first"));
        course = new Course(courseRowData.courseNbr, courseRowData.courseName),
        section = new Section(course, sectionRowData.sectionNbr, sectionRowData.sectionType,
          sectionRowData.sectionInstructor, sectionRowData.sectionTime, sectionRowData.sectionPlace,
          semester);
    if(sectionList.add(section)) {
      appendToClassList(section);
    }
  });

  $("body").on("click", ".lousList_extension_class_remove", function(e) {
    e.stopPropagation();
    e.preventDefault();
    var sectionIdentifier = $(this).attr("id").split("-"),
        el = $(this).parent().parent();
    sectionList.remove(sectionIdentifier[2], sectionIdentifier[1]);
    if(el.hasClass("conflict") || el.hasClass("no-conflict")) {
      delete selectedList[sectionIdentifier[1] + "-" + sectionIdentifier[2]];
    }
    // Resolve conflicts
    el.remove();
  });

  $("body").on("click", ".lousList_extension_class", function(e) {
    var el = $(this),
        index = $(".lousList_extension_class").index($(this)),
        section = sectionList.list[index],
        id = el.attr("id");
    if(el.hasClass("no-conflict")) {
      el.removeClass("no-conflict");
      delete conflicts[section.id];
      delete selectedList[id];
    } else if(el.hasClass("conflict")) {
      el.removeClass("conflict");
      for(c in conflicts[section.id]) {
        if(c !== "size") {
          console.log(c);
          if(section.id in conflicts[c]) {
            delete conflicts[c][section.id];
            conflicts[c].size--;
            if(conflicts[c].size === 0) {
              $("#" + c).removeClass("conflict").addClass("no-conflict");
            }
          }
        }
      }
      delete conflicts[section.id];
      delete selectedList[id];
    } else {
      var conflict = false;
      if(!(section.id in conflicts)) {
        conflicts[section.id] = {
          "size": 0
        }
      }
      for(var s in selectedList) {
        if(selectedList[s].isOverlap(section)) {
          $("#" + selectedList[s].id)
            .removeClass("no-conflict").removeClass("conflict")
            .addClass("conflict");
          conflict = true;
          conflicts[selectedList[s].id].size++;
          conflicts[selectedList[s].id][section.id] = true;
          conflicts[section.id].size++;
          conflicts[section.id][selectedList[s].id] = true;
        }
      }
      selectedList[id] = section;
      if(conflict) {
        $(this).addClass("conflict");
      } else {
        $(this).addClass("no-conflict");
      }
    }
  });

  var interval;

  $("body").on({
    "mouseenter": function() {
      var el = $(this),
          index = $(".lousList_extension_class").index(el),
          section = sectionList.list[index];
      interval = setInterval(function() {
        $.ajax({
          url: urls.sectiontip,
          data: { "Semester": section.semester, "ClassNumber": section.nbr },
          dataType: "html",
          success: function(html) {
            var tableBody = $(html).find("table:last").html();
            $(".louList_extension_class_popup").remove();
            $("body").prepend("" +
              "
" +
                "

" +
                "
" +
                  "
" +
                    tableBody +
                  "
" +
                "
" +
              "
");
            positionPopup(el);
            clearInterval(interval);
          }
        });
      }, 750);
      hovered = el;
    },
    "mouseleave": function() {
      clearInterval(interval);
      $(".lousList_extension_class_popup").remove();
      hovered = null;
    }
  }, ".lousList_extension_class");

  function parseSectionRow(row) {
    var tableCells = row.find("td"),
        data = {
          "sectionNbr":         $.trim(tableCells[0].innerText),
          "sectionType":        $.trim(tableCells[2].innerText),
          "sectionInstructor":  $.trim(tableCells[5].innerText),
          "sectionPlace":       $.trim(tableCells[7].innerText),
          "sectionTime":        $.trim(tableCells[6].innerText)
        }
    return data;
  }

  function parseCourseRow(row) {
    var tableCells = row.find("td"),
        data = {
          "courseNbr":          $.trim(tableCells[0].innerText),
          "courseName":         $.trim(tableCells[1].innerText)
        }
    return data;
  }

  /*
   * Position a popup relative to el
   */
  function positionPopup(el) {
    var offsetTop = el.offset().top - $(window).scrollTop(),
        popup = $(".lousList_extension_class_popup"),
        popupTop = 8,
        arrowTop = 0;
    // Popup positioning
    if(offsetTop + (popup.outerHeight() / 2) + (el.outerHeight() / 2) > $(window).height()) {
      // Treat the case if the popup overflows the window from the bottom
      popupTop = offsetTop - popup.outerHeight() + el.outerHeight() - 1;
      arrowTop = popup.outerHeight() - (el.outerHeight() / 2) - 12
    } else if(offsetTop - (popup.outerHeight() / 2) + (el.outerHeight() / 2) < 0) {
      // Treat the case if the popup overflows past the top
      arrowTop = offsetTop + (el.outerHeight() / 2) - 18
    } else {
      popupTop = offsetTop - (popup.outerHeight() / 2) + (el.outerHeight() / 2);
      arrowTop = (popup.outerHeight() / 2) - 12;
    }
    popup.css({
      "top": popupTop
    });
    $(".lousList_extension_class_popup_arrow").css({
      "top": arrowTop
    });
  }

});
<commit_msg>added section source url<commit_after>/*
 * Attach event listeners
 */
$(function() {

  var hovered = null;

  $(".lousList_extension").scroll(function() {
    if(hovered) {
      positionPopup(hovered);
    }
  });

  $(".lousList_extension_savedClassList_clear").on("click", function(e) {
    e.preventDefault();
    $("#lousList_extension_savedClassList ul").html("");
    sectionList = new SectionList([]);
    sectionList.save();
  });

  $(".lousList_extension_savedClassList_clear_selected").on("click", function(e) {
    e.preventDefault();
    selectedList = {};
    conflicts = {};
    $("#lousList_extension_savedClassList ul li").each(function() {
      if($(this).hasClass("conflict")) {
        $(this).removeClass("conflict");
      } else if($(this).hasClass("no-conflict")) {
        $(this).removeClass("no-conflict");
      }
    });
  });

  $(".lousList_extension_saveSection").on("click", function(e) {
    e.stopPropagation();
    e.preventDefault();
    var selectedRow = $(e.target).parents(".S");
    var sectionRowData = parseSectionRow(selectedRow),
        courseRowData = parseCourseRow(selectedRow.prevAll(".CourseInfo:first"));
        course = new Course(courseRowData.courseNbr, courseRowData.courseName),
        section = new Section(course, sectionRowData.sectionNbr, sectionRowData.sectionType,
          sectionRowData.sectionInstructor, sectionRowData.sectionTime, sectionRowData.sectionPlace,
          semester, document.URL);
    if(sectionList.add(section)) {
      appendToClassList(section);
    }
  });

  $("body").on("click", ".lousList_extension_class_remove", function(e) {
    e.stopPropagation();
    e.preventDefault();
    var sectionIdentifier = $(this).attr("id").split("-"),
        el = $(this).parent().parent();
    sectionList.remove(sectionIdentifier[2], sectionIdentifier[1]);
    if(el.hasClass("conflict") || el.hasClass("no-conflict")) {
      delete selectedList[sectionIdentifier[1] + "-" + sectionIdentifier[2]];
    }
    // Resolve conflicts
    el.remove();
  });

  $("body").on("click", ".lousList_extension_class", function(e) {
    var el = $(this),
        index = $(".lousList_extension_class").index($(this)),
        section = sectionList.list[index],
        id = el.attr("id");
    if(el.hasClass("no-conflict")) {
      el.removeClass("no-conflict");
      delete conflicts[section.id];
      delete selectedList[id];
    } else if(el.hasClass("conflict")) {
      el.removeClass("conflict");
      for(c in conflicts[section.id]) {
        if(c !== "size") {
          console.log(c);
          if(section.id in conflicts[c]) {
            delete conflicts[c][section.id];
            conflicts[c].size--;
            if(conflicts[c].size === 0) {
              $("#" + c).removeClass("conflict").addClass("no-conflict");
            }
          }
        }
      }
      delete conflicts[section.id];
      delete selectedList[id];
    } else {
      var conflict = false;
      if(!(section.id in conflicts)) {
        conflicts[section.id] = {
          "size": 0
        }
      }
      for(var s in selectedList) {
        if(selectedList[s].isOverlap(section)) {
          $("#" + selectedList[s].id)
            .removeClass("no-conflict").removeClass("conflict")
            .addClass("conflict");
          conflict = true;
          conflicts[selectedList[s].id].size++;
          conflicts[selectedList[s].id][section.id] = true;
          conflicts[section.id].size++;
          conflicts[section.id][selectedList[s].id] = true;
        }
      }
      selectedList[id] = section;
      if(conflict) {
        $(this).addClass("conflict");
      } else {
        $(this).addClass("no-conflict");
      }
    }
  });

  var interval;

  $("body").on({
    "mouseenter": function() {
      var el = $(this),
          index = $(".lousList_extension_class").index(el),
          section = sectionList.list[index];
      interval = setInterval(function() {
        $.ajax({
          url: urls.sectiontip,
          data: { "Semester": section.semester, "ClassNumber": section.nbr },
          dataType: "html",
          success: function(html) {
            var tableBody = $(html).find("table:last").html();
            $(".louList_extension_class_popup").remove();
            $("body").prepend("" +
              "
" +
                "

" +
                "
" +
                  "
" +
                    tableBody +
                  "
" +
                "
" +
              "
");
            positionPopup(el);
            clearInterval(interval);
          }
        });
      }, 1050);
      hovered = el;
    },
    "mouseleave": function() {
      clearInterval(interval);
      $(".lousList_extension_class_popup").remove();
      hovered = null;
    }
  }, ".lousList_extension_class");

  function parseSectionRow(row) {
    var tableCells = row.find("td"),
        data = {
          "sectionNbr":         $.trim(tableCells[0].innerText),
          "sectionType":        $.trim(tableCells[2].innerText),
          "sectionInstructor":  $.trim(tableCells[5].innerText),
          "sectionPlace":       $.trim(tableCells[7].innerText),
          "sectionTime":        $.trim(tableCells[6].innerText)
        }
    return data;
  }

  function parseCourseRow(row) {
    var tableCells = row.find("td"),
        data = {
          "courseNbr":          $.trim(tableCells[0].innerText),
          "courseName":         $.trim(tableCells[1].innerText)
        }
    return data;
  }

  /*
   * Position a popup relative to el
   */
  function positionPopup(el) {
    var offsetTop = el.offset().top - $(window).scrollTop(),
        popup = $(".lousList_extension_class_popup"),
        popupTop = 8,
        arrowTop = 0;
    // Popup positioning
    if(offsetTop + (popup.outerHeight() / 2) + (el.outerHeight() / 2) > $(window).height()) {
      // Treat the case if the popup overflows the window from the bottom
      popupTop = offsetTop - popup.outerHeight() + el.outerHeight() - 1;
      arrowTop = popup.outerHeight() - (el.outerHeight() / 2) - 12
    } else if(offsetTop - (popup.outerHeight() / 2) + (el.outerHeight() / 2) < 0) {
      // Treat the case if the popup overflows past the top
      arrowTop = offsetTop + (el.outerHeight() / 2) - 18
    } else {
      popupTop = offsetTop - (popup.outerHeight() / 2) + (el.outerHeight() / 2);
      arrowTop = (popup.outerHeight() / 2) - 12;
    }
    popup.css({
      "top": popupTop
    });
    $(".lousList_extension_class_popup_arrow").css({
      "top": arrowTop
    });
  }

});
<|endoftext|>


<commit_before>/**
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * @author manou.maret@gmail.com
 * @author timothee.maret@gmail.com
 */<commit_msg>Create Phaser game<commit_after>/**
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * @author manou.maret@gmail.com
 * @author timothee.maret@gmail.com
 */
 window.onload = function() {

 	var screenWidth = 800, screenHeight = 600, worldWidth = 1.25 * screenWidth;
 	var game = new Phaser.Game(/*width*/screenWidth, /*height*/screenHeight, /*render*/Phaser.AUTO, /*parent*/'',
 		/*state*/{preload: preload, create: create, render: render, update: update},
 		/*transparent*/ false, /*antialias*/false, /*physicsConfig*/null);

 	function preload (game){
 	}

 	function create (game){
 	}

 	function render (game){
 	}

 	function update (game){
 	}

 }<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012, Dienst Landelijk Gebied - Ministerie van Economische Zaken
 *
 * Gepubliceerd onder de BSD 2-clause licentie,
 * zie https://github.com/MinELenI/CBSviewer/blob/master/LICENSE.md voor de volledige licentie.
 */
/**
 * Werkt de legenda bij als de kaart wordt ge-update met een WMS layer.
 *
 * @author mprins
 * @class
 * @extends OpenLayers.Control
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Layer/WMS/js
 * @constructor
 */
UpdateLegendControl = OpenLayers.Class(OpenLayers.Control, {
	/**
	 * Activate the control when it is added to a map. Default is true.
	 *
	 * @type{Boolean}
	 */
	autoActivate : true,

	/**
	 * Dom element waar de legenda in wordt gevoegd. Moet een container element
	 * zijn zoals P, DIV, SPAN, MAP, LI, ...
	 *
	 * @type {DOMElement}
	 */
	element : null,

	/**
	 * destroy this control.
	 */
	destroy : function() {
		this.deactivate();
		OpenLayers.Control.prototype.destroy.apply(this, arguments);
	},

	/**
	 * activate this control.
	 */
	activate : function() {
		if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {
			this.map.events.register('addlayer', this, this.redraw);
			this.redraw();
			return true;
		} else {
			return false;
		}
	},

	/**
	 * deactivate this control.
	 */
	deactivate : function() {
		if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
			this.map.events.unregister('addlayer', this, this.redraw);
			this.element.innerHTML = "";
			return true;
		} else {
			return false;
		}
	},

	/**
	 * draw this control.
	 *
	 * @returns {DOMElement}
	 */
	draw : function() {
		OpenLayers.Control.prototype.draw.apply(this, arguments);
		if (!this.element) {
			this.div.left = "";
			this.div.top = "";
			this.element = this.div;
		}
		return this.div;
	},

	/**
	 * redraw this control.
	 *
	 * @param {OpenLayers.Event}
	 *            evt De addlayer event
	 */
	redraw : function(evt) {
		// addlayer event - triggered after a layer has been added. The event
		// object will include a *layer* property that references the added
		// layer.
		if (evt == null) {
			this.reset();
			return;
		} else {
			// test if layer is WMS
			if (evt.layer instanceof OpenLayers.Layer.WMS) {
				var lyr = evt.layer;
				var legendUrl = lyr.url + '?SERVICE=WMS&REQUEST=GetLegendGraphic' + '&FORMAT=image%2Fpng'
						+ '&WIDTH=25&HEIGHT=25' + '&LAYER=' + lyr.params.LAYERS + '&STYLE=' + lyr.params.STYLES
						+ '&VERSION=' + lyr.params.VERSION + '&EXCEPTIONS=' + lyr.params.EXCEPTIONS;
				var newHtml = '';

				if (newHtml != this.element.innerHTML) {
					this.element.innerHTML = newHtml;
				}
			}
		}
	},

	/**
	 * reset this control.
	 *
	 * @param {OpenLayers.Event}
	 *            evt De addlayer event
	 */
	reset : function(evt) {
		if (this.emptyString !== null) {
			this.element.innerHTML = this.emptyString;
		}
	}
});
<commit_msg>fix voor legenda bolletjes<commit_after>/*
 * Copyright (c) 2012, Dienst Landelijk Gebied - Ministerie van Economische Zaken
 *
 * Gepubliceerd onder de BSD 2-clause licentie,
 * zie https://github.com/MinELenI/CBSviewer/blob/master/LICENSE.md voor de volledige licentie.
 */
/**
 * Werkt de legenda bij als de kaart wordt ge-update met een WMS layer.
 *
 * @author mprins
 * @class
 * @extends OpenLayers.Control
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Layer/WMS/js
 * @constructor
 */
UpdateLegendControl = OpenLayers.Class(OpenLayers.Control, {
	/**
	 * Activate the control when it is added to a map. Default is true.
	 *
	 * @type{Boolean}
	 */
	autoActivate : true,

	/**
	 * Dom element waar de legenda in wordt gevoegd. Moet een container element
	 * zijn zoals P, DIV, SPAN, MAP, LI, ...
	 *
	 * @type {DOMElement}
	 */
	element : null,

	/**
	 * destroy this control.
	 */
	destroy : function() {
		this.deactivate();
		OpenLayers.Control.prototype.destroy.apply(this, arguments);
	},

	/**
	 * activate this control.
	 */
	activate : function() {
		if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {
			this.map.events.register('addlayer', this, this.redraw);
			this.redraw();
			return true;
		} else {
			return false;
		}
	},

	/**
	 * deactivate this control.
	 */
	deactivate : function() {
		if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
			this.map.events.unregister('addlayer', this, this.redraw);
			this.element.innerHTML = "";
			return true;
		} else {
			return false;
		}
	},

	/**
	 * draw this control.
	 *
	 * @returns {DOMElement}
	 */
	draw : function() {
		OpenLayers.Control.prototype.draw.apply(this, arguments);
		if (!this.element) {
			this.div.left = "";
			this.div.top = "";
			this.element = this.div;
		}
		return this.div;
	},

	/**
	 * redraw this control.
	 *
	 * @param {OpenLayers.Event}
	 *            evt De addlayer event
	 */
	redraw : function(evt) {
		// addlayer event - triggered after a layer has been added. The event
		// object will include a *layer* property that references the added
		// layer.
		if (evt == null) {
			this.reset();
			return;
		} else {
			// test if layer is WMS
			if (evt.layer instanceof OpenLayers.Layer.WMS) {
				var lyr = evt.layer;
				var legendUrl = lyr.url + '?SERVICE=WMS&REQUEST=GetLegendGraphic' + '&FORMAT=image%2Fpng'
						+ '&WIDTH=36&HEIGHT=36' + '&LAYER=' + lyr.params.LAYERS + '&STYLE=' + lyr.params.STYLES
						+ '&VERSION=' + lyr.params.VERSION + '&EXCEPTIONS=' + lyr.params.EXCEPTIONS;
				var newHtml = '';

				if (newHtml != this.element.innerHTML) {
					this.element.innerHTML = newHtml;
				}
			}
		}
	},

	/**
	 * reset this control.
	 *
	 * @param {OpenLayers.Event}
	 *            evt De addlayer event
	 */
	reset : function(evt) {
		if (this.emptyString !== null) {
			this.element.innerHTML = this.emptyString;
		}
	}
});
<|endoftext|>


<commit_before>'use strict';

var http    = require('http')
  , fs      = require('fs')
  , PORT    = 6060
  , express = require('express')
  , app     = express()
  , util    = require('util');

/*
 * use ejs to serve static files
 */
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.static(__dirname + '/views'));

/*
 * get git log file
 * TODO seperate this into a module
 */
var gitText = {};
fs.readFile('./views/gitlog.txt', 'utf8', function (error, data) {
    if (! error) gitText = { 'content': data };
});

/*
 * read body files for later serving
 */
var bodies = {};
var subjects = {
    projects:   'Personal Projects'
    , about:    'About Me'
    , contact:  'Get in Touch'
    , home:     'Hello'
};
var files = [ 'about', 'projects', 'contact', 'home'];
for (var i = 0; i < files.length; i++) {
    bodies[files[i]] = fs.readFileSync('./views/bodies/body-' + files[i] + '.ejs', 'utf8');
}

/*
 * read some submodules' files for later serving
 */
var reader  = require('./face-read.js');
var notes   = reader.read('./views/notes', 'txt');
var scripts = reader.read('./views/scripts', 'sh');

/*
 * HTTP request routers
 */
app.all('/*', function (req, res, next) {
    logConnection(req);
    next();
});

app.get('/', function (req, res, next) {
	res.render('index.ejs', {
        debug: true,
        subject: 'Hello',
        content: bodies['home']
    });
});
app.get('/body/:which', function (req, res, next) {
    var which = req.params.which;

    res.status(200).json({
        data: {
            subject: subjects[which],
            content: bodies[which]
        }
    });
});
app.get('/robots.txt', function (req, res) {
    res.type('text/plain');
    res.send('#011000100110010101100101011100000010'
    + '00000110001001101111011011110111000000100001'
    + '\nUser-agent: *\nDisallow: /');
});
app.get('/getGitLog', function (req, res) {
    res.send(gitText);
});
app.get('/notes', function (req, res) {
    res.render('notes.ejs', {
        subject: 'Some Notes',
        titles: Object.keys(notes),
        notes: notes
    });
});
app.get('/notes/:which', function (req, res) {
    console.log(which);
    var which = req.params.which;
    res.render(notes[which] || null);
});

app.get('/scripts', function (req, res) {
    res.render('scripts.ejs', {
        subject: 'Some Scripts',
        titles: Object.keys(scripts),
        scripts: scripts
    });
});
app.get('/scripts/:which', function (req, res) {
    console.log(which);
    var which = req.params.which;
    res.render(scripts[which] || null);
});

/*
 * listen on port 6060 (rerouted from 80)
 */
app.listen(PORT, function () {
	console.log('facer listening on port', PORT);
});

function logConnection(req) {
    // if not my public IP
    console.log(req.path);
    var info = util.format('[%s]: %s,\t%s,\t%s',
      new Date().toUTCString(), req.method, req.ip, req.path);
    info += '\n';
    fs.appendFile('logs/connect.log', info, function (error) {
        if (error) throw new Error(("Error writing to file: " + error));
    });
}
<commit_msg>Send simple '404' on invalid URLs<commit_after>'use strict';

var http    = require('http')
  , fs      = require('fs')
  , PORT    = 6060
  , express = require('express')
  , app     = express()
  , util    = require('util');

/*
 * use ejs to serve static files
 */
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.static(__dirname + '/views'));

/*
 * get git log file
 * TODO seperate this into a module
 */
var gitText = {};
fs.readFile('./views/gitlog.txt', 'utf8', function (error, data) {
    if (! error) gitText = { 'content': data };
});

/*
 * read body files for later serving
 */
var bodies = {};
var subjects = {
    projects:   'Personal Projects'
    , about:    'About Me'
    , contact:  'Get in Touch'
    , home:     'Hello'
};
var files = [ 'about', 'projects', 'contact', 'home'];
for (var i = 0; i < files.length; i++) {
    bodies[files[i]] = fs.readFileSync('./views/bodies/body-' + files[i] + '.ejs', 'utf8');
}

/*
 * valid urls
 */
var valid = [ /^\/$/
    , /^\/favicon\.ico$/
    , /^\/body\/[a-z]+$/
    , /^\/robots\.txt$/
    , /^\/getGitLog$/
    , /^\/notes\/[a-zA-Z]*$/
    , /^\/scripts\/[a-zA-Z]*$/
];

/*
 * read some submodules' files for later serving
 */
var reader  = require('./face-read.js');
var notes   = reader.read('./views/notes', 'txt');
var scripts = reader.read('./views/scripts', 'sh');

/*
 * HTTP request routers
 */
app.all('/*', function (req, res, next) {
    res.setHeader('X-Powered-By', 'Maisy');
    if (validConnection(req.path)) {
        next();
    } else {
        console.error('Invalid path "%s"', req.path);
        // TODO add proper 404 page
        res.end('404');
    }
    logConnection(req); // TODO log fact of bad conn attempt

});

app.get('/', function (req, res, next) {
	res.render('index.ejs', {
        debug: false,
        subject: 'Hello',
        content: bodies['home']
    });
});
app.get('/body/:which', function (req, res, next) {
    var which = req.params.which;

    res.status(200).json({
        data: {
            subject: subjects[which],
            content: bodies[which]
        }
    });
});
app.get('/robots.txt', function (req, res) {
    res.type('text/plain');
    res.send('#011000100110010101100101011100000010'
    + '00000110001001101111011011110111000000100001'
    + '\nUser-agent: *\nDisallow: /');
});
app.get('/getGitLog', function (req, res) {
    res.send(gitText);
});
app.get('/notes', function (req, res) {
    res.render('notes.ejs', {
        subject: 'Some Notes',
        titles: Object.keys(notes),
        notes: notes
    });
});
app.get('/notes/:which', function (req, res) {
    console.log(which);
    var which = req.params.which;
    res.render(notes[which] || null);
});

app.get('/scripts', function (req, res) {
    res.render('scripts.ejs', {
        subject: 'Some Scripts',
        titles: Object.keys(scripts),
        scripts: scripts
    });
});
app.get('/scripts/:which', function (req, res) {
    console.log(which);
    var which = req.params.which;
    res.render(scripts[which] || null);
});

/*
 * listen on port 6060 (rerouted from 80)
 */
app.listen(PORT, function () {
	console.log('facer listening on port', PORT);
});

function validConnection(path) {
    var result = false;
    valid.forEach(function (r) {
        if (path.match(r) !== null) {
            result = true;
        }
    });
    return result;
}

function logConnection(req) {

    console.log(req.path);

    var now = new Date();
    var info = util.format('[%s (%s)]:\t%s,\t%s,\t%s',
      now.toDateString(), now.toLocaleTimeString(),  req.method, req.ip, req.path);
    info += '\n';
    fs.appendFile('logs/connect.log', info, function (error) {
        if (error) throw new Error(("Error writing to file: " + error));
    });
}
<|endoftext|>


<commit_before>'use strict';

/*
 Use arguments provided by start.sh
 */
var startup     = {};
startup.PORT    = Number(process.argv[2]);
startup.DEBUG   = String(process.argv[3]) == 'true';
startup.TOKEN   = process.argv[4] || 0;

var http    = require('http')
  , fs      = require('fs')
  , express = require('express')
  , app     = express()
  , util    = require('util');

var httpCodes = JSON.parse(fs.readFileSync('./views/json/http-codes.json', 'utf8'));

/*
 * Use nullportal to handle connections on
 * same such domain.
 */
var np = require('./nullportal-web/nullportal.js');
np.setup();

/*
 * use ejs to serve static files
 */
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

// Aliases for paths to main and sub website resources
app.use('/', express.static(__dirname + '/views'));
app.use('/nullportal-views', express.static(__dirname + '/nullportal-web/views'));

/*
 * get git log file
 * TODO seperate this into a module
 */
var gitText = {};
fs.readFile('./views/gitlog.txt', 'utf8', function (error, data) {
    if (! error) gitText = { 'content': data };
});

/*
 * read body files for later serving
 */
var bodies = {};
var subjects = {
    projects:   'Personal Projects'
    , about:    'About Me'
    , contact:  'Get in Touch'
    , home:     'Hello'
};
var files = [ 'about', 'projects', 'contact', 'home'];
for (var i = 0; i < files.length; i++) {
    bodies[files[i]] = fs.readFileSync('./views/bodies/body-' + files[i] + '.ejs', 'utf8');
}

/*
 * valid urls
 */
var valid = [ /^\/$/
    , /^\/body\/[a-z]+$/
    , /^\/favicon\.ico$/
    , /^\/getGitLog$/
    , /^\/notes\/[a-zA-Z]*$/
    , /^\/robots\.txt$/
    , /^\/scripts\/[a-zA-Z-]*$/
];

/*
 * read some submodules' files for later serving
 */
var reader  = require('./face-read.js');
var notes = {};
reader.read('./views/notes', function (result) {
    notes = result;
});
var scripts = {};
reader.read('./views/scripts', function (result) {
    scripts = result;
}, { extension: 'sh' });

/*
 * HTTP request routers
 */
app.all('/*', function (req, res, next) {
    var valid = true;
    res.setHeader('X-Powered-By', 'Maisy');

    if (validConnection(req.path)) {
        // TODO put this in validConnection
        if (req.method !== 'GET') {
            valid = false;
            res.render('error.ejs', {
                httpStatus: httpCodes.ClientError[405]
            });
        } else if (req.headers.host === 'www.nullportal.com') {
            np.getPage(req, function (result) {
                res.end(result);
            });
        } else {
            next();
        }
    } else {
        valid = false;
        console.error('Invalid path "%s"', req.path);
        res.render('error.ejs', {
            httpStatus: httpCodes.ClientError[404]
        });
    }
    logConnection(req, valid);

});

app.get('/', function (req, res, next) {
	res.render('index.ejs', {
        debug_mode: startup.DEBUG,
        subject: 'Hello',
        content: bodies['home']
    });
});
app.get('/body/:which', function (req, res, next) {
    var which = req.params.which;

    res.status(200).json({
        data: {
            subject: subjects[which],
            content: bodies[which]
        }
    });
});
app.get('/robots.txt', function (req, res) {
    res.type('text/plain');
    res.send('#011000100110010101100101011100000010'
    + '00000110001001101111011011110111000000100001'
    + '\nUser-agent: *\nDisallow: /');
});
app.get('/getGitLog', function (req, res) {
    res.send(gitText);
});

app.get('/notes', function (req, res) {
    res.render('notes.ejs', {
        subject: 'Some Notes',
        titles: Object.keys(notes),
        notes: notes
    });
});
app.get('/notes/:which', function (req, res) {
    var which = req.params.which;
    res.setHeader('Content-Type', 'text/plain');
    res.send((notes[which]) || '404');
});

app.get('/scripts', function (req, res) {
    res.render('scripts.ejs', {
        subject: 'Some Scripts',
        titles: Object.keys(scripts),
        scripts: scripts
    });
});
app.get('/scripts/:which', function (req, res) {
    var which = req.params.which;
    res.setHeader('Content-Type', 'text/plain');
    res.send((scripts[which]) || '404');
});

/*
 * listen on port 6060 (rerouted from 80)
 */
app.listen(startup.PORT, function () {
	console.log('[facer.js]:\tListening on port(%d), with debug(%s)'
        , startup.PORT
        , startup.DEBUG);
});

function validConnection(path) {
    var result = false;
    valid.forEach(function (r) {
        if (path.match(r) !== null) {
            result = true;
        }
    });
    return result;
}

function logConnection(req, valid) {

    console.log(req.headers.host, req.path);

    var now = new Date();
    var info = util.format('[%s (%s)]:\t\t%s,\t%s,\t%s%s',
      now.toDateString(), now.toLocaleTimeString(),  req.method, req.ip, req.headers.host, req.path);
    if (! valid) info += '\t\t[DENIED]';
    info += '\n';

    fs.appendFile('logs/connect.log', info, function (error) {
        if (error) throw new Error(("Error writing to file: " + error));
    });
    if (typeof req.path === 'undefined') {
        console.error('undefined ip', req.route);
    }
}
<commit_msg>Add proper file extension opt<commit_after>'use strict';

/*
 Use arguments provided by start.sh
 */
var startup     = {};
startup.PORT    = Number(process.argv[2]);
startup.DEBUG   = String(process.argv[3]) == 'true';
startup.TOKEN   = process.argv[4] || 0;

var http    = require('http')
  , fs      = require('fs')
  , express = require('express')
  , app     = express()
  , util    = require('util');

var httpCodes = JSON.parse(fs.readFileSync('./views/json/http-codes.json', 'utf8'));

/*
 * Use nullportal to handle connections on
 * same such domain.
 */
var np = require('./nullportal-web/nullportal.js');
np.setup();

/*
 * use ejs to serve static files
 */
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

// Aliases for paths to main and sub website resources
app.use('/', express.static(__dirname + '/views'));
app.use('/nullportal-views', express.static(__dirname + '/nullportal-web/views'));

/*
 * get git log file
 * TODO seperate this into a module
 */
var gitText = {};
fs.readFile('./views/gitlog.txt', 'utf8', function (error, data) {
    if (! error) gitText = { 'content': data };
});

/*
 * read body files for later serving
 */
var bodies = {};
var subjects = {
    projects:   'Personal Projects'
    , about:    'About Me'
    , contact:  'Get in Touch'
    , home:     'Hello'
};
var files = [ 'about', 'projects', 'contact', 'home'];
for (var i = 0; i < files.length; i++) {
    bodies[files[i]] = fs.readFileSync('./views/bodies/body-' + files[i] + '.ejs', 'utf8');
}

/*
 * valid urls
 */
var valid = [ /^\/$/
    , /^\/body\/[a-z]+$/
    , /^\/favicon\.ico$/
    , /^\/getGitLog$/
    , /^\/notes\/[a-zA-Z]*$/
    , /^\/robots\.txt$/
    , /^\/scripts\/[a-zA-Z-]*$/
];

/*
 * read some submodules' files for later serving
 */
var reader  = require('./face-read.js');
var notes = {};
reader.read('./views/notes', function (result) {
    notes = result;
}, {extension: 'mkd' });
var scripts = {};
reader.read('./views/scripts', function (result) {
    scripts = result;
}, { extension: 'sh' });

/*
 * HTTP request routers
 */
app.all('/*', function (req, res, next) {
    var valid = true;
    res.setHeader('X-Powered-By', 'Maisy');

    if (validConnection(req.path)) {
        // TODO put this in validConnection
        if (req.method !== 'GET') {
            valid = false;
            res.render('error.ejs', {
                httpStatus: httpCodes.ClientError[405]
            });
        } else if (req.headers.host === 'www.nullportal.com') {
            np.getPage(req, function (result) {
                res.end(result);
            });
        } else {
            next();
        }
    } else {
        valid = false;
        console.error('Invalid path "%s"', req.path);
        res.render('error.ejs', {
            httpStatus: httpCodes.ClientError[404]
        });
    }
    logConnection(req, valid);

});

app.get('/', function (req, res, next) {
	res.render('index.ejs', {
        debug_mode: startup.DEBUG,
        subject: 'Hello',
        content: bodies['home']
    });
});
app.get('/body/:which', function (req, res, next) {
    var which = req.params.which;

    res.status(200).json({
        data: {
            subject: subjects[which],
            content: bodies[which]
        }
    });
});
app.get('/robots.txt', function (req, res) {
    res.type('text/plain');
    res.send('#011000100110010101100101011100000010'
    + '00000110001001101111011011110111000000100001'
    + '\nUser-agent: *\nDisallow: /');
});
app.get('/getGitLog', function (req, res) {
    res.send(gitText);
});

app.get('/notes', function (req, res) {
    res.render('notes.ejs', {
        subject: 'Some Notes',
        titles: Object.keys(notes),
        notes: notes
    });
});
app.get('/notes/:which', function (req, res) {
    var which = req.params.which;
    res.setHeader('Content-Type', 'text/plain');
    res.send((notes[which]) || '404');
});

app.get('/scripts', function (req, res) {
    res.render('scripts.ejs', {
        subject: 'Some Scripts',
        titles: Object.keys(scripts),
        scripts: scripts
    });
});
app.get('/scripts/:which', function (req, res) {
    var which = req.params.which;
    res.setHeader('Content-Type', 'text/plain');
    res.send((scripts[which]) || '404');
});

/*
 * listen on port 6060 (rerouted from 80)
 */
app.listen(startup.PORT, function () {
	console.log('[facer.js]:\tListening on port(%d), with debug(%s)'
        , startup.PORT
        , startup.DEBUG);
});

function validConnection(path) {
    var result = false;
    valid.forEach(function (r) {
        if (path.match(r) !== null) {
            result = true;
        }
    });
    return result;
}

function logConnection(req, valid) {

    console.log(req.headers.host, req.path);

    var now = new Date();
    var info = util.format('[%s (%s)]:\t\t%s,\t%s,\t%s%s',
      now.toDateString(), now.toLocaleTimeString(),  req.method, req.ip, req.headers.host, req.path);
    if (! valid) info += '\t\t[DENIED]';
    info += '\n';

    fs.appendFile('logs/connect.log', info, function (error) {
        if (error) throw new Error(("Error writing to file: " + error));
    });
    if (typeof req.path === 'undefined') {
        console.error('undefined ip', req.route);
    }
}
<|endoftext|>


<commit_before>'use strict';

var directive = {};
var service = { value: {} };

var DEPENDENCIES = {
  'angular.js': 'http://code.angularjs.org/angular-' + angular.version.full + '.min.js',
  'angular-resource.js': 'http://code.angularjs.org/angular-resource-' + angular.version.full + '.min.js',
  'angular-sanitize.js': 'http://code.angularjs.org/angular-sanitize-' + angular.version.full + '.min.js',
  'angular-cookies.js': 'http://code.angularjs.org/angular-cookies-' + angular.version.full + '.min.js'
};

function escape(text) {
  return text.
    replace(/\&/g, '&').
    replace(/\</g, '<').
    replace(/\>/g, '>').
    replace(/"/g, '"');
}

/**
 * http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
 * http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
 */
function setHtmlIe8SafeWay(element, html) {
  var newElement = angular.element('
' + html + '
');

  element.html('');
  element.append(newElement.contents());
  return element;
}

directive.jsFiddle = function(getEmbeddedTemplate, escape, script) {
  return {
    terminal: true,
    link: function(scope, element, attr) {
      var name = '',
        stylesheet = '<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">\n',
        fields = {
          html: '',
          css: '',
          js: ''
        };

      angular.forEach(attr.jsFiddle.split(' '), function(file, index) {
        var fileType = file.split('.')[1];

        if (fileType == 'html') {
          if (index == 0) {
            fields[fileType] +=
              '
\n' +
                getEmbeddedTemplate(file, 2);
          } else {
            fields[fileType] += '\n\n\n  \n' +
              '  \n';
          }
        } else {
          fields[fileType] += getEmbeddedTemplate(file) + '\n';
        }
      });

      fields.html += '
\n';

      setHtmlIe8SafeWay(element,
        '<form class="jsfiddle" method="post" action="http://jsfiddle.net/api/post/library/pure/" target="_blank">' +
          hiddenField('title', 'AngularJS Example: ' + name) +
          hiddenField('css', '</style>  \n' +
            stylesheet +
            script.angular +
            (attr.resource ? script.resource : '') +
            '  \n' +
            stylesheet +
            script.angular +
            (attr.resource ? script.resource : '') +
            '


<commit_before>async function remindmeArgless (msg) {
  const prefix = this.db.getPrefix(msg.channel.guild ? msg.channel.guild.id : null);

  const delarray = [];
  const cleanup = async () => {
    if (msg.channel.type === 0 && msg.channel.permissionsOf(this.client.user.id).has('manageMessages')) {
      msg.channel.deleteMessages(delarray);
    }
  };

  delarray.push(msg.id);

  const collector = new this.utils.MessageCollector(
    this.client,
    msg.channel,
    (message) => message.author.id === msg.author.id,
    { time: 60000 }
  );
  let step = 1;
  const reminder = { ownerID: msg.author.id };

  this.sendMessage(msg.channel.id, 'What would you like the reminder to be? (You can send `cancel` at any time to cancel creation.)')
    .then(m => delarray.push(m.id));

  collector.on('message', async m => {
    if (m.content.length === 0 && !m.attachments[0]) {
      return;
    }
    if (m.content.startsWith(`${prefix}remind`) || m.content.includes(`${this.client.user.id}> remind`)) {
      cleanup();
      return collector.stop();
    }
    if (m.content.toLowerCase().includes('cancel') || m.content.toLowerCase() === 'c') {
      this.sendMessage(msg.channel.id, 'Cancelled.');
      return collector.stop();
    }

    delarray.push(m.id);

    if (step === 1) {
      reminder.reminder = m.content || m.attachments[0].proxy_url;

      this.sendMessage(msg.channel.id, 'When would you like to be reminded? (e.g. 24 hours)')
        .then(m => delarray.push(m.id));
    }

    if (step === 2) {
      const parsedTime = this.utils.parseTime(m.content);

      if (parsedTime === 'INVALID') {
        return this.sendMessage(msg.channel.id, 'Invalid time argument. When would you like to be reminded? (e.g. `12 hours` or `next week`).')
          .then(m => delarray.push(m.id));
      }
      if (parsedTime === 'SET_FOR_PAST') {
        return this.sendMessage(msg.channel.id, 'Your reminder wasn\'t added because it was set for the past. Note that if you\'re trying to set a reminder for the same day at a specific time (e.g. `6 PM`), UTC time will be assumed. You can fix this by including your timezone (e.g. `6 PM PST`).\n\nWhen would you like to be reminded? (e.g. `12 hours` or `next week`).')
          .then(m => delarray.push(m.id));
      }

      reminder.dueDate = parsedTime.absolute;

      this.sendMessage(msg.channel.id, 'Would you like to receive the reminder in a specific channel, or in your DMs?\nMention the channel you\'d like to receive the reminder in, or send `DM` if you\'d like to receive it in your DMs.')
        .then(m => delarray.push(m.id));
    }

    if (step === 3) {
      if (!m.content.toLowerCase().startsWith('dm')) {
        if (!m.channelMentions[0] && !m.content.includes('here')) {
          return this.sendMessage(msg.channel.id, 'You need to either ping the channel you\'d like to receive your reminder in, send `here` or send `DM`.\nWhere would you like to receive your reminder?')
            .then(m => delarray.push(m.id));
        }
        reminder.channelID = m.channelMentions[0] || m.channel.id;
      }

      this.sendMessage(msg.channel.id, 'Would you like this reminder to be recurring? Send how frequently (e.g. `every hour` or `every 3 weeks`) or send `n` for no.')
        .then(m => delarray.push(m.id));
    }

    if (step === 4) {
      if (!['n', 'no'].includes(m.content.toLowerCase())) {
        reminder.recurringArg = m.content;
        const parsed = this.utils.parseTime(m.content);

        if (parsed === 'INVALID' || parsed === 'SET_FOR_PAST' || parsed.mode !== 'relative') {
          return this.sendMessage(msg.channel.id, `I was unable to recognize \`${m.content}\` as a valid recurring time argument. Please enter a proper recurring time argument, e.g. \`every 12 hours\` or \`every month\`.`);
        }

        reminder.recurring = parsed.relative;
      }

      collector.stop();
      await this.db.addReminder(reminder);

      const fields = [
        {
          name: 'Target channel',
          value: reminder.channelID ? `<#${reminder.channelID}>` : `<@${msg.author.id}>'s DMs`,
          inline: true
        }
      ];

      if (reminder.recurring) {
        fields.push({
          name: 'Recurring',
          value: `${reminder.recurringArg.trim()} (every ${this.utils.parseDuration(reminder.recurring / 1000)})`,
          inline: true
        });
      }

      this.sendMessage(msg.channel.id, {
        title: 'Reminder successfully added',
        description: reminder.reminder,
        fields: fields,
        footer: { text: 'Reminder set for ' },
        timestamp: new Date(reminder.dueDate)
      });
      cleanup();
    }
    step++;
  });

  collector.on('end', async (_, reason) => {
    if (reason === 'time') {
      this.sendMessage(msg.channel.id, 'Prompt timed out.');
    }
  });
}

module.exports = remindmeArgless;<commit_msg>fix bug showing encrypted string<commit_after>async function remindmeArgless (msg) {
  const prefix = this.db.getPrefix(msg.channel.guild ? msg.channel.guild.id : null);

  const delarray = [];
  const cleanup = async () => {
    if (msg.channel.type === 0 && msg.channel.permissionsOf(this.client.user.id).has('manageMessages')) {
      msg.channel.deleteMessages(delarray);
    }
  };

  delarray.push(msg.id);

  const collector = new this.utils.MessageCollector(
    this.client,
    msg.channel,
    (message) => message.author.id === msg.author.id,
    { time: 60000 }
  );
  let step = 1;
  const reminder = { ownerID: msg.author.id };
  let reminderText;

  this.sendMessage(msg.channel.id, 'What would you like the reminder to be? (You can send `cancel` at any time to cancel creation.)')
    .then(m => delarray.push(m.id));

  collector.on('message', async m => {
    if (m.content.length === 0 && !m.attachments[0]) {
      return;
    }
    if (m.content.startsWith(`${prefix}remind`) || m.content.includes(`${this.client.user.id}> remind`)) {
      cleanup();
      return collector.stop();
    }
    if (m.content.toLowerCase().includes('cancel') || m.content.toLowerCase() === 'c') {
      this.sendMessage(msg.channel.id, 'Cancelled.');
      return collector.stop();
    }

    delarray.push(m.id);

    if (step === 1) {
      reminder.reminder = reminderText = m.content || m.attachments[0].proxy_url;

      this.sendMessage(msg.channel.id, 'When would you like to be reminded? (e.g. 24 hours)')
        .then(m => delarray.push(m.id));
    }

    if (step === 2) {
      const parsedTime = this.utils.parseTime(m.content);

      if (parsedTime === 'INVALID') {
        return this.sendMessage(msg.channel.id, 'Invalid time argument. When would you like to be reminded? (e.g. `12 hours` or `next week`).')
          .then(m => delarray.push(m.id));
      }
      if (parsedTime === 'SET_FOR_PAST') {
        return this.sendMessage(msg.channel.id, 'Your reminder wasn\'t added because it was set for the past. Note that if you\'re trying to set a reminder for the same day at a specific time (e.g. `6 PM`), UTC time will be assumed. You can fix this by including your timezone (e.g. `6 PM PST`).\n\nWhen would you like to be reminded? (e.g. `12 hours` or `next week`).')
          .then(m => delarray.push(m.id));
      }

      reminder.dueDate = parsedTime.absolute;

      this.sendMessage(msg.channel.id, 'Would you like to receive the reminder in a specific channel, or in your DMs?\nMention the channel you\'d like to receive the reminder in, or send `DM` if you\'d like to receive it in your DMs.')
        .then(m => delarray.push(m.id));
    }

    if (step === 3) {
      if (!m.content.toLowerCase().startsWith('dm')) {
        if (!m.channelMentions[0] && !m.content.includes('here')) {
          return this.sendMessage(msg.channel.id, 'You need to either ping the channel you\'d like to receive your reminder in, send `here` or send `DM`.\nWhere would you like to receive your reminder?')
            .then(m => delarray.push(m.id));
        }
        reminder.channelID = m.channelMentions[0] || m.channel.id;
      }

      this.sendMessage(msg.channel.id, 'Would you like this reminder to be recurring? Send how frequently (e.g. `every hour` or `every 3 weeks`) or send `no`.')
        .then(m => delarray.push(m.id));
    }

    if (step === 4) {
      if (!['n', 'no'].includes(m.content.toLowerCase())) {
        reminder.recurringArg = m.content;
        const parsed = this.utils.parseTime(m.content);

        if (parsed === 'INVALID' || parsed === 'SET_FOR_PAST' || parsed.mode !== 'relative') {
          return this.sendMessage(msg.channel.id, `I was unable to recognize \`${m.content}\` as a valid recurring time argument. Please enter a proper recurring time argument, e.g. \`every 12 hours\` or \`every month\`.`);
        }

        reminder.recurring = parsed.relative;
      }

      collector.stop();

      await this.db.addReminder(reminder);

      const fields = [
        {
          name: 'Target channel',
          value: reminder.channelID ? `<#${reminder.channelID}>` : `<@${msg.author.id}>'s DMs`,
          inline: true
        }
      ];

      if (reminder.recurring) {
        fields.push({
          name: 'Recurring',
          value: `${reminder.recurringArg.trim()} (every ${this.utils.parseDuration(reminder.recurring / 1000)})`,
          inline: true
        });
      }

      this.sendMessage(msg.channel.id, {
        title: 'Reminder successfully added',
        description: reminderText,
        fields: fields,
        footer: { text: 'Reminder set for ' },
        timestamp: new Date(reminder.dueDate)
      });
      cleanup();
    }
    step++;
  });

  collector.on('end', async (_, reason) => {
    if (reason === 'time') {
      this.sendMessage(msg.channel.id, 'Prompt timed out.');
    }
  });
}

module.exports = remindmeArgless;<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015,  nwillc@gmail.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

var myPresentation = {

    init: function (config) {
        console.log("init");
        myPresentation.config = {
            categories: $('#browseCategories'),
            snippetCategories: $('#snippetCategories'),
            category: $('#category'),
            titles: $('#titles'),
            title: $('#title'),
            body: $('#body'),
            bodyInput: $('#bodyInput'),
            searchDialog: $('#searchCategoryDialog'),
            query: $('#query')
        };
        $.extend(myPresentation.config, config);
        myPresentation.bind();
        myPresentation.loadCategories();
    },

    bind: function () {
        console.log("bind");
        $('#tabs').tabs();
        $(myPresentation.config.searchDialog).dialog();
        $(myPresentation.config.searchDialog).dialog('close');
        $(myPresentation.config.categories).change(myPresentation.loadAllTitles);
        $(myPresentation.config.titles).change(myPresentation.loadBody);
        $('#saveSnippetButton').click(myPresentation.saveSnippet);
        $('#logoutButton').click(myPresentation.logout);
        $('#deleteButton').click(myPresentation.deleteSnippet);
        $('#saveCategoryButton').click(myPresentation.saveCategory);
        $('#deleteCategoryButton').click(myPresentation.deleteCategory);
        $('#searchButton').click(myPresentation.openSearch);
        $('#performSearch').click(myPresentation.performSearch);
    },

    loadCategories: function () {
        console.log("loadCategories");
        $.get("v1/categories", function (data) {
            var list = JSON.parse(data);
            $(myPresentation.config.categories).empty();
            $(list).sort(function (a, b) {
                return a.name.toLowerCase() > b.name.toLowerCase();
            }).each(function () {
                myPresentation.config.categories.append($("<option></option>").attr("value", this.key).text(this.name));
            });
            window.setTimeout(function () {
                $(myPresentation.config.categories).change();
            }, 1);
            $(myPresentation.config.snippetCategories).empty();
            $(list).sort(function (a, b) {
                return a.name.toLowerCase() > b.name.toLowerCase();
            }).each(function () {
                myPresentation.config.snippetCategories.append($("<option></option>").attr("value", this.key).text(this.name));
            });
        });
    },

    loadAllTitles: function () {
        console.log("loadAllTitles");
        var category = $(myPresentation.config.categories).val();
        console.log("Selected Category: " + category);
        $.get("v1/snippets/category/" + category, function (data) {
            myPresentation.loadTitles(JSON.parse(data));
        })
    },

    loadTitles: function (list) {
        console.log("loadTitles");
        $('option', myPresentation.config.titles).remove();
        $(myPresentation.config.body).val('');
        $(list).sort(function (a, b) {
            return a.title.toLowerCase() > b.title.toLowerCase();
        }).each(function () {
            myPresentation.config.titles.append($("<option></option>").attr("value", this.key).text(this.title));
        })
    },

    loadBody: function () {
        console.log("loadBody");
        var category = $(myPresentation.config.categories).val();
        var title = $(myPresentation.config.titles).val();
        console.log("Selected Category: " + category + " Title: " + title);
        $.get("v1/snippets/" + title, function (data, status) {
            console.log("Status: " + status + " Data: " + data);
            var found = JSON.parse(data);
            $(myPresentation.config.body).val(found.body);
        })
    },

    saveCategory: function () {
        console.log("saveCategory");
        $.post("v1/categories", JSON.stringify({
            name: $(myPresentation.config.category).val()
        }), function () {
            myPresentation.loadCategories();
            $('#category').val('');
        }).fail(function () {
            alert("Failed saving category");
        });
    },

    saveSnippet: function () {
        console.log("Save Snippet");
        $.post('v1/snippets', JSON.stringify({
            category: $(myPresentation.config.snippetCategories).val(),
            title: $(myPresentation.config.title).val(),
            body: $(myPresentation.config.bodyInput).val()
        }), function () {
            myPresentation.loadCategories();
        }).fail(function () {
            alert("Failed saving snippet.")
        });
        $(myPresentation.config.title).val('');
        $(myPresentation.config.bodyInput).val('');
    },

    deleteSnippet: function () {
        var selected = $(titles).find("option:selected");
        console.log("Delete Snippet: " + $(myPresentation.config.categories).val() + ':'
            + $(selected).val());
        $.ajax({
            url: 'v1/snippets/' + $(selected).val(),
            type: 'DELETE',
            success: function () {
                console.log('success');
                myPresentation.loadCategories();
            }
        });
    },

    deleteCategory: function () {
        console.log("Delete Category: " + $(myPresentation.config.categories).val());
        $.ajax({
            url: 'v1/categories/' + $(myPresentation.config.categories).val(),
            type: 'DELETE',
            success: function () {
                console.log('success');
                myPresentation.loadCategories();
            }
        });
    },

    openSearch: function () {
        $(myPresentation.config.searchDialog).dialog('open');
    },

    performSearch: function () {
        console.log("loadAllTitles");
        var category = $(myPresentation.config.categories).val();
        console.log("Selected Category: " + category);
        $.post("v1/snippets/category/" + category, JSON.stringify({
            query: $(query).val()
        }), function (data) {
            myPresentation.loadTitles(JSON.parse(data));
            $(myPresentation.config.searchDialog).dialog('close');
        }).fail(function () {
            alert("Failed searching snippets.")
        });
    },

    logout: function () {
        console.log("logout");
        myPersona.logout();
        $.ajax({
            url: 'v1/auth',
            type: 'DELETE',
            success: function () {
                window.location.replace("/login.html");
            }
        });
    }

};

$(document).ready(function () {
    myPresentation.init();
});
<commit_msg>Set initial search dialog size.<commit_after>/*
 * Copyright (c) 2015,  nwillc@gmail.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

var myPresentation = {

    init: function (config) {
        console.log("init");
        myPresentation.config = {
            categories: $('#browseCategories'),
            snippetCategories: $('#snippetCategories'),
            category: $('#category'),
            titles: $('#titles'),
            title: $('#title'),
            body: $('#body'),
            bodyInput: $('#bodyInput'),
            searchDialog: $('#searchCategoryDialog'),
            query: $('#query')
        };
        $.extend(myPresentation.config, config);
        myPresentation.bind();
        myPresentation.loadCategories();
    },

    bind: function () {
        console.log("bind");
        $('#tabs').tabs();
        $(myPresentation.config.searchDialog).dialog({ width: 500 });
        $(myPresentation.config.searchDialog).dialog('close');
        $(myPresentation.config.categories).change(myPresentation.loadAllTitles);
        $(myPresentation.config.titles).change(myPresentation.loadBody);
        $('#saveSnippetButton').click(myPresentation.saveSnippet);
        $('#logoutButton').click(myPresentation.logout);
        $('#deleteButton').click(myPresentation.deleteSnippet);
        $('#saveCategoryButton').click(myPresentation.saveCategory);
        $('#deleteCategoryButton').click(myPresentation.deleteCategory);
        $('#searchButton').click(myPresentation.openSearch);
        $('#performSearch').click(myPresentation.performSearch);
    },

    loadCategories: function () {
        console.log("loadCategories");
        $.get("v1/categories", function (data) {
            var list = JSON.parse(data);
            $(myPresentation.config.categories).empty();
            $(list).sort(function (a, b) {
                return a.name.toLowerCase() > b.name.toLowerCase();
            }).each(function () {
                myPresentation.config.categories.append($("<option></option>").attr("value", this.key).text(this.name));
            });
            window.setTimeout(function () {
                $(myPresentation.config.categories).change();
            }, 1);
            $(myPresentation.config.snippetCategories).empty();
            $(list).sort(function (a, b) {
                return a.name.toLowerCase() > b.name.toLowerCase();
            }).each(function () {
                myPresentation.config.snippetCategories.append($("<option></option>").attr("value", this.key).text(this.name));
            });
        });
    },

    loadAllTitles: function () {
        console.log("loadAllTitles");
        var category = $(myPresentation.config.categories).val();
        console.log("Selected Category: " + category);
        $.get("v1/snippets/category/" + category, function (data) {
            myPresentation.loadTitles(JSON.parse(data));
        })
    },

    loadTitles: function (list) {
        console.log("loadTitles");
        $('option', myPresentation.config.titles).remove();
        $(myPresentation.config.body).val('');
        $(list).sort(function (a, b) {
            return a.title.toLowerCase() > b.title.toLowerCase();
        }).each(function () {
            myPresentation.config.titles.append($("<option></option>").attr("value", this.key).text(this.title));
        })
    },

    loadBody: function () {
        console.log("loadBody");
        var category = $(myPresentation.config.categories).val();
        var title = $(myPresentation.config.titles).val();
        console.log("Selected Category: " + category + " Title: " + title);
        $.get("v1/snippets/" + title, function (data, status) {
            console.log("Status: " + status + " Data: " + data);
            var found = JSON.parse(data);
            $(myPresentation.config.body).val(found.body);
        })
    },

    saveCategory: function () {
        console.log("saveCategory");
        $.post("v1/categories", JSON.stringify({
            name: $(myPresentation.config.category).val()
        }), function () {
            myPresentation.loadCategories();
            $('#category').val('');
        }).fail(function () {
            alert("Failed saving category");
        });
    },

    saveSnippet: function () {
        console.log("Save Snippet");
        $.post('v1/snippets', JSON.stringify({
            category: $(myPresentation.config.snippetCategories).val(),
            title: $(myPresentation.config.title).val(),
            body: $(myPresentation.config.bodyInput).val()
        }), function () {
            myPresentation.loadCategories();
        }).fail(function () {
            alert("Failed saving snippet.")
        });
        $(myPresentation.config.title).val('');
        $(myPresentation.config.bodyInput).val('');
    },

    deleteSnippet: function () {
        var selected = $(titles).find("option:selected");
        console.log("Delete Snippet: " + $(myPresentation.config.categories).val() + ':'
            + $(selected).val());
        $.ajax({
            url: 'v1/snippets/' + $(selected).val(),
            type: 'DELETE',
            success: function () {
                console.log('success');
                myPresentation.loadCategories();
            }
        });
    },

    deleteCategory: function () {
        console.log("Delete Category: " + $(myPresentation.config.categories).val());
        $.ajax({
            url: 'v1/categories/' + $(myPresentation.config.categories).val(),
            type: 'DELETE',
            success: function () {
                console.log('success');
                myPresentation.loadCategories();
            }
        });
    },

    openSearch: function () {
        $(myPresentation.config.searchDialog).dialog('open');
    },

    performSearch: function () {
        console.log("loadAllTitles");
        var category = $(myPresentation.config.categories).val();
        console.log("Selected Category: " + category);
        $.post("v1/snippets/category/" + category, JSON.stringify({
            query: $(query).val()
        }), function (data) {
            myPresentation.loadTitles(JSON.parse(data));
            $(myPresentation.config.searchDialog).dialog('close');
        }).fail(function () {
            alert("Failed searching snippets.")
        });
    },

    logout: function () {
        console.log("logout");
        myPersona.logout();
        $.ajax({
            url: 'v1/auth',
            type: 'DELETE',
            success: function () {
                window.location.replace("/login.html");
            }
        });
    }

};

$(document).ready(function () {
    myPresentation.init();
});
<|endoftext|>