<commit_before>/**
 Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at

 http://aws.amazon.com/apache2.0/

 or in the "license" file accompanying this file. This file 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.
 */

/**
 * This simple sample has no external dependencies or session management, and shows the most basic
 * example of how to create a Lambda function for handling Alexa Skill requests.
 *
 * Examples:
 * One-shot model:
 *  User: "Alexa, tell Greeter to say hello"
 *  Alexa: "Hello World!"
 */

/**
 * App ID for the skill
 */
var APP_ID = undefined; //replace with "amzn1.echo-sdk-ams.app.[your-unique-value-here]";
var WORD = 'banana';

/**
 * The AlexaSkill prototype and helper functions
 */
var AlexaSkill = require('./AlexaSkill');
var Speech = require('./lib/speech');
var syl = require('./lib/syllables');

/**
 * DrSpeech is a child of AlexaSkill.
 * To read more about inheritance in JavaScript, see the link below.
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Inheritance
 */
var DrSpeech = function () {
    AlexaSkill.call(this, APP_ID);
};

// Extend AlexaSkill
DrSpeech.prototype = Object.create(AlexaSkill.prototype);
DrSpeech.prototype.constructor = DrSpeech;

DrSpeech.prototype.eventHandlers.onSessionStarted = function (sessionStartedRequest, session) {
    console.log("DrSpeech onSessionStarted requestId: " + sessionStartedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any initialization logic goes here
};

DrSpeech.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
    var speech = new Speech();
    speech.say("Welcome to Doctor Speech. Let's Begin Your Lesson.");
    speech.say("When you give an answer, start with saying its.");
    speech.pause("1s");
    speech.say("How do you say ");
    speech.say(WORD);

    response.ask(speech.toObject(), "How do you say " + WORD);
};

DrSpeech.prototype.eventHandlers.onSessionEnded = function (sessionEndedRequest, session) {
    console.log("DrSpeech onSessionEnded requestId: " + sessionEndedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any cleanup logic goes here
};

DrSpeech.prototype.intentHandlers = {
    // register custom intent handlers
    "SayWordIntent": function (intent, session, response) {
        var speech = new Speech();
        var word = intent.slots.Word.value;

        if (word == WORD) {
            speech.say("You said it correctly.");
            speech.say(word);
            speech.pause("1s");
            speech.say("which is spelled as");
            speeech.pause("1s");
            speech.spell(word);
        } else {
            speech.say("That was not correct. I heard ");
            speech.say(word);
            speech.pause('1s');
            speech.say("which is spelled as");
            speeech.pause("1s");
            speech.spell(word);
            speech.pause("1s");
            speech.say("The correct way to pronounce it is");
            speech.pause("800ms");
            var syllables = syl(WORD);
            syllables.syllables.forEach(function (part, index) {
                speech.pause("500ms");
                speech.say(part);
            });
        }

        response.tell(speech.toObject());
    },
    "AMAZON.HelpIntent": function (intent, session, response) {
        response.ask("Try again and listen carefully", "You can do this!");
    }
};

// Create the handler that responds to the Alexa Request.
exports.handler = function (event, context) {
    // Create an instance of the DrSpeech skill.
    var helloWorld = new DrSpeech();
    helloWorld.execute(event, context);
};
<commit_msg>fixed speech typo<commit_after>/**
 Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at

 http://aws.amazon.com/apache2.0/

 or in the "license" file accompanying this file. This file 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.
 */

/**
 * This simple sample has no external dependencies or session management, and shows the most basic
 * example of how to create a Lambda function for handling Alexa Skill requests.
 *
 * Examples:
 * One-shot model:
 *  User: "Alexa, tell Greeter to say hello"
 *  Alexa: "Hello World!"
 */

/**
 * App ID for the skill
 */
var APP_ID = undefined; //replace with "amzn1.echo-sdk-ams.app.[your-unique-value-here]";
var WORD = 'banana';

/**
 * The AlexaSkill prototype and helper functions
 */
var AlexaSkill = require('./AlexaSkill');
var Speech = require('./lib/speech');
var syl = require('./lib/syllables');

/**
 * DrSpeech is a child of AlexaSkill.
 * To read more about inheritance in JavaScript, see the link below.
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Inheritance
 */
var DrSpeech = function () {
    AlexaSkill.call(this, APP_ID);
};

// Extend AlexaSkill
DrSpeech.prototype = Object.create(AlexaSkill.prototype);
DrSpeech.prototype.constructor = DrSpeech;

DrSpeech.prototype.eventHandlers.onSessionStarted = function (sessionStartedRequest, session) {
    console.log("DrSpeech onSessionStarted requestId: " + sessionStartedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any initialization logic goes here
};

DrSpeech.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
    var speech = new Speech();
    speech.say("Welcome to Doctor Speech. Let's Begin Your Lesson.");
    speech.say("When you give an answer, start with saying its.");
    speech.pause("1s");
    speech.say("How do you say ");
    speech.say(WORD);

    response.ask(speech.toObject(), "How do you say " + WORD);
};

DrSpeech.prototype.eventHandlers.onSessionEnded = function (sessionEndedRequest, session) {
    console.log("DrSpeech onSessionEnded requestId: " + sessionEndedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any cleanup logic goes here
};

DrSpeech.prototype.intentHandlers = {
    // register custom intent handlers
    "SayWordIntent": function (intent, session, response) {
        var speech = new Speech();
        var word = intent.slots.Word.value;

        if (word === WORD) {
            speech.say("You said it correctly.");
            speech.say(word);
            speech.pause("1s");
            speech.say("which is spelled as");
            speech.pause("1s");
            speech.spell(word);
        } else {
            speech.say("That was not correct. I heard ");
            speech.say(word);
            speech.pause('1s');
            speech.say("which is spelled as");
            speech.pause("1s");
            speech.spell(word);
            speech.pause("1s");
            speech.say("The correct way to pronounce it is");
            speech.pause("800ms");
            var syllables = syl(WORD);
            syllables.syllables.forEach(function (part, index) {
                speech.pause("500ms");
                speech.say(part);
            });
        }

        response.tell(speech.toObject());
    },
    "AMAZON.HelpIntent": function (intent, session, response) {
        response.ask("Try again and listen carefully", "You can do this!");
    }
};

// Create the handler that responds to the Alexa Request.
exports.handler = function (event, context) {
    // Create an instance of the DrSpeech skill.
    var helloWorld = new DrSpeech();
    helloWorld.execute(event, context);
};
<|endoftext|>


<commit_before>'use strict';

/**
 * Serverless CORS Plugin
 */
module.exports = function(SPlugin, serverlessPath) {
  const _ = require('lodash'),
    path = require('path'),
    Joi = require('joi'),
    Promise = require('bluebird'),
    SError = require(path.join(serverlessPath, 'ServerlessError')),
    SUtils = require(path.join(serverlessPath, 'utils'));

  class ServerlessCors extends SPlugin {
    static getName() {
      return 'com.joostfarla.' + ServerlessCors.name;
    }

    registerHooks() {
      this.S.addHook(this.addCorsHeaders.bind(this), {
        action: 'endpointBuildApiGateway',
        event: 'pre'
      });

      this.S.addHook(this.addPreflightRequests.bind(this), {
        action: 'endpointDeploy',
        event: 'post'
      });
    }

    addCorsHeaders(evt) {
      let policy,
        responseParameters = {};

      // Capture region object for preflight endpoints
      this.context = evt.region;

      // Skip when CORS is not enabled
      if (!this._isCorsEnabled(evt.endpoint)) {
        return Promise.resolve(evt);
      }

      try {
        policy = this._getEndpointPolicy(evt.endpoint);
      } catch (err) {
        return Promise.reject(err);
      }

      // Set allow-origin header on all responses
      _.each(evt.endpoint.responses, function(response) {
        if (!response.responseParameters) {
          response.responseParameters = {};
        }

        response.responseParameters['method.response.header.Access-Control-Allow-Origin'] = '\'' + policy.allowOrigin + '\'';

        // Set allow-credentials header on all GET responses as these will not be preflighted
        if (evt.endpoint.method === 'GET' && !_.isUndefined(policy.allowCredentials)) {
          response.responseParameters['method.response.header.Access-Control-Allow-Credentials'] = '\'' + policy.allowCredentials + '\'';
        }
      });

      return Promise.resolve(evt);
    }

    addPreflightRequests(evt) {
      let config = {
        region: this.context.region,
        accessKeyId: this.S._awsAdminKeyId,
        secretAccessKey: this.S._awsAdminSecretKey,
      };

      this.ApiGateway = require(path.join(serverlessPath, 'utils', 'aws', 'ApiGateway'))(config);

      evt = {
        deployed: evt.endpoints,
        stage: evt.stage
      };

      return this._getApiResources(evt)
        .bind(this)
        .then(this._getEndpoints)
        .then(this._createPreflightEndpoints)
        .then(this._deployPreflightEndpoints)
        .then(this._deployApi);
    }

    _isCorsEnabled(endpoint) {
      return !_.isUndefined(endpoint.module.custom.cors) || !_.isUndefined(endpoint.function.custom.cors);
    }

    _getEndpointPolicy(endpoint) {
      let policy = _.merge({},
        endpoint.module.custom.cors,
        endpoint.function.custom.cors
      );

      let schema = Joi.object().keys({
        allowOrigin: Joi.string().required(),
        allowHeaders: Joi.array().min(1).items(Joi.string().regex(/^[a-zA-Z-]+$/)),
        allowCredentials: Joi.boolean(),
        exposeHeaders: Joi.array().min(1).items(Joi.string().regex(/^[a-zA-Z-]+$/)),
        maxAge: Joi.number()
      });

      Joi.validate(policy, schema, function(err) {
        if (err) {
          throw new SError(
            err.message,
            SError.errorCodes.INVALID_PROJECT_SERVERLESS
          );
        }
      });

      return policy;
    }

    _getApiResources(evt) {
      let params = {
        restApiId: this.context.restApiId,
        limit: 500
      };

      return this.ApiGateway.getResourcesPromised(params)
        .then(function(response) {
          evt.resources = response.items;
          return evt;
        });
    }

    _getEndpoints(evt) {
      return SUtils.getEndpoints(this.S._projectRootPath)
        .then(function(endpoints) {
          evt.endpoints = endpoints;
          return evt;
        });
    }

    _createPreflightEndpoints(evt) {
      let _this = this;
      let paths = _.uniq(_.pluck(evt.deployed, 'path'));

      // Remove leading slashes
      paths = _.map(paths, path => _.trimLeft(path, '/'));

      // Generate method objects
      // @todo how do we handle hard-specified OPTIONS requests?
      try {
        evt.preflightEndpoints = paths.reduce(function(result, path) {
          let endpoints = _.filter(evt.endpoints, { path: path });

          _.forEach(endpoints, function(endpoint) {
            let policy,
              resource = _.findWhere(evt.resources, { path: '/' + path });

            // Skip when resource is not found or CORS is not enabled
            if (!resource || !_this._isCorsEnabled(endpoint)) {
              return;
            }

            policy = _this._getEndpointPolicy(endpoint);

            if (!result[path]) {
              // @todo handle conflicts with endpoints within same path
              result[path] = _.merge(policy, {
                path: path,
                resource: resource
              });
            }

            if (!result[path].allowMethods) {
              result[path].allowMethods = [];
            }

            result[path].allowMethods.push(endpoint.method);
          });

          return result;
        }, {});
      } catch (err) {
        return Promise.reject(err);
      }

      return Promise.resolve(evt);
    }

    _deployPreflightEndpoints(evt) {
      return Promise.resolve(_.values(evt.preflightEndpoints))
        .mapSeries(this._createEndpoint.bind(this))
        .then(() => { return evt; });
    }

    _createEndpoint(endpoint) {
      return this._removeEndpointMethod(endpoint)
        .bind(this)
        .then(this._createEndpointMethod)
        .then(this._createEndpointIntegration)
        .then(this._createEndpointMethodResponse)
        .then(this._createEndpointIntegrationResponse);
    }

    _removeEndpointMethod(endpoint) {
      let params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId
      };

      return this.ApiGateway.deleteMethodPromised(params)
        .catch(function(err) {
          // Do nothing, it probably doesn't exist
        })
        .then(() => { return endpoint; });
    }

    _createEndpointMethod(endpoint) {
      let params = {
        authorizationType: 'none',
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId
      };

      return this.ApiGateway.putMethodPromised(params)
        .then(method => { return endpoint; });
    }

    _createEndpointIntegration(endpoint) {
      var params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId,
        type: 'MOCK',
        requestTemplates: {
          'application/json': '{"statusCode": 200}'
        }
      };

      return this.ApiGateway.putIntegrationPromised(params)
        .then(integration => { return endpoint; });
    }

    _createEndpointMethodResponse(endpoint) {
      var params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId,
        statusCode: '200',
        responseParameters: {
          'method.response.header.Access-Control-Allow-Methods': true,
          'method.response.header.Access-Control-Allow-Origin': true,
          'method.response.header.Access-Control-Allow-Headers': false,
          'method.response.header.Access-Control-Allow-Credentials': false,
          'method.response.header.Access-Control-Expose-Headers': false,
          'method.response.header.Access-Control-Max-Age': false
        }
      };

      return this.ApiGateway.putMethodResponsePromised(params)
        .then(methodResponse => { return endpoint; });
    }

    _createEndpointIntegrationResponse(endpoint) {
      var params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId,
        statusCode: '200',
        responseParameters: {
          'method.response.header.Access-Control-Allow-Methods': '\'' + endpoint.allowMethods + '\''
        }
      };

      params.responseParameters['method.response.header.Access-Control-Allow-Origin'] = '\'' + endpoint.allowOrigin + '\'';

      if (!_.isUndefined(endpoint.allowHeaders)) {
        params.responseParameters['method.response.header.Access-Control-Allow-Headers'] = '\'' + endpoint.allowHeaders + '\'';
      }

      if (!_.isUndefined(endpoint.allowCredentials)) {
        params.responseParameters['method.response.header.Access-Control-Allow-Credentials'] = '\'' + endpoint.allowCredentials + '\'';
      }

      if (!_.isUndefined(endpoint.exposeHeaders)) {
        params.responseParameters['method.response.header.Access-Control-Expose-Headers'] = '\'' + endpoint.exposeHeaders + '\'';
      }

      if (!_.isUndefined(endpoint.maxAge)) {
        params.responseParameters['method.response.header.Access-Control-Max-Age'] = '\'' + endpoint.maxAge + '\'';
      }

      return this.ApiGateway.putIntegrationResponsePromised(params)
        .then(integrationResponse => { return endpoint; });
    }

    _deployApi(evt) {
      let params = {
        restApiId: this.context.restApiId,
        stageName: evt.stage,
        description: evt.description || 'Serverless deployment',
        stageDescription: evt.stage,
        variables: {
          functionAlias: evt.stage
        }
      };

      return this.ApiGateway.createDeploymentPromised(params)
        .then(deployment => { return evt; });
    }
  }

  return ServerlessCors;
}
<commit_msg>Allow numbers in header names (#4)<commit_after>'use strict';

/**
 * Serverless CORS Plugin
 */
module.exports = function(SPlugin, serverlessPath) {
  const _ = require('lodash'),
    path = require('path'),
    Joi = require('joi'),
    Promise = require('bluebird'),
    SError = require(path.join(serverlessPath, 'ServerlessError')),
    SUtils = require(path.join(serverlessPath, 'utils'));

  class ServerlessCors extends SPlugin {
    static getName() {
      return 'com.joostfarla.' + ServerlessCors.name;
    }

    registerHooks() {
      this.S.addHook(this.addCorsHeaders.bind(this), {
        action: 'endpointBuildApiGateway',
        event: 'pre'
      });

      this.S.addHook(this.addPreflightRequests.bind(this), {
        action: 'endpointDeploy',
        event: 'post'
      });
    }

    addCorsHeaders(evt) {
      let policy,
        responseParameters = {};

      // Capture region object for preflight endpoints
      this.context = evt.region;

      // Skip when CORS is not enabled
      if (!this._isCorsEnabled(evt.endpoint)) {
        return Promise.resolve(evt);
      }

      try {
        policy = this._getEndpointPolicy(evt.endpoint);
      } catch (err) {
        return Promise.reject(err);
      }

      // Set allow-origin header on all responses
      _.each(evt.endpoint.responses, function(response) {
        if (!response.responseParameters) {
          response.responseParameters = {};
        }

        response.responseParameters['method.response.header.Access-Control-Allow-Origin'] = '\'' + policy.allowOrigin + '\'';

        // Set allow-credentials header on all GET responses as these will not be preflighted
        if (evt.endpoint.method === 'GET' && !_.isUndefined(policy.allowCredentials)) {
          response.responseParameters['method.response.header.Access-Control-Allow-Credentials'] = '\'' + policy.allowCredentials + '\'';
        }
      });

      return Promise.resolve(evt);
    }

    addPreflightRequests(evt) {
      let config = {
        region: this.context.region,
        accessKeyId: this.S._awsAdminKeyId,
        secretAccessKey: this.S._awsAdminSecretKey,
      };

      this.ApiGateway = require(path.join(serverlessPath, 'utils', 'aws', 'ApiGateway'))(config);

      evt = {
        deployed: evt.endpoints,
        stage: evt.stage
      };

      return this._getApiResources(evt)
        .bind(this)
        .then(this._getEndpoints)
        .then(this._createPreflightEndpoints)
        .then(this._deployPreflightEndpoints)
        .then(this._deployApi);
    }

    _isCorsEnabled(endpoint) {
      return !_.isUndefined(endpoint.module.custom.cors) || !_.isUndefined(endpoint.function.custom.cors);
    }

    _getEndpointPolicy(endpoint) {
      let policy = _.merge({},
        endpoint.module.custom.cors,
        endpoint.function.custom.cors
      );

      let schema = Joi.object().keys({
        allowOrigin: Joi.string().required(),
        allowHeaders: Joi.array().min(1).items(Joi.string().regex(/^[\w-]+$/)),
        allowCredentials: Joi.boolean(),
        exposeHeaders: Joi.array().min(1).items(Joi.string().regex(/^[\w-]+$/)),
        maxAge: Joi.number()
      });

      Joi.validate(policy, schema, function(err) {
        if (err) {
          throw new SError(
            err.message,
            SError.errorCodes.INVALID_PROJECT_SERVERLESS
          );
        }
      });

      return policy;
    }

    _getApiResources(evt) {
      let params = {
        restApiId: this.context.restApiId,
        limit: 500
      };

      return this.ApiGateway.getResourcesPromised(params)
        .then(function(response) {
          evt.resources = response.items;
          return evt;
        });
    }

    _getEndpoints(evt) {
      return SUtils.getEndpoints(this.S._projectRootPath)
        .then(function(endpoints) {
          evt.endpoints = endpoints;
          return evt;
        });
    }

    _createPreflightEndpoints(evt) {
      let _this = this;
      let paths = _.uniq(_.pluck(evt.deployed, 'path'));

      // Remove leading slashes
      paths = _.map(paths, path => _.trimLeft(path, '/'));

      // Generate method objects
      // @todo how do we handle hard-specified OPTIONS requests?
      try {
        evt.preflightEndpoints = paths.reduce(function(result, path) {
          let endpoints = _.filter(evt.endpoints, { path: path });

          _.forEach(endpoints, function(endpoint) {
            let policy,
              resource = _.findWhere(evt.resources, { path: '/' + path });

            // Skip when resource is not found or CORS is not enabled
            if (!resource || !_this._isCorsEnabled(endpoint)) {
              return;
            }

            policy = _this._getEndpointPolicy(endpoint);

            if (!result[path]) {
              // @todo handle conflicts with endpoints within same path
              result[path] = _.merge(policy, {
                path: path,
                resource: resource
              });
            }

            if (!result[path].allowMethods) {
              result[path].allowMethods = [];
            }

            result[path].allowMethods.push(endpoint.method);
          });

          return result;
        }, {});
      } catch (err) {
        return Promise.reject(err);
      }

      return Promise.resolve(evt);
    }

    _deployPreflightEndpoints(evt) {
      return Promise.resolve(_.values(evt.preflightEndpoints))
        .mapSeries(this._createEndpoint.bind(this))
        .then(() => { return evt; });
    }

    _createEndpoint(endpoint) {
      return this._removeEndpointMethod(endpoint)
        .bind(this)
        .then(this._createEndpointMethod)
        .then(this._createEndpointIntegration)
        .then(this._createEndpointMethodResponse)
        .then(this._createEndpointIntegrationResponse);
    }

    _removeEndpointMethod(endpoint) {
      let params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId
      };

      return this.ApiGateway.deleteMethodPromised(params)
        .catch(function(err) {
          // Do nothing, it probably doesn't exist
        })
        .then(() => { return endpoint; });
    }

    _createEndpointMethod(endpoint) {
      let params = {
        authorizationType: 'none',
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId
      };

      return this.ApiGateway.putMethodPromised(params)
        .then(method => { return endpoint; });
    }

    _createEndpointIntegration(endpoint) {
      var params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId,
        type: 'MOCK',
        requestTemplates: {
          'application/json': '{"statusCode": 200}'
        }
      };

      return this.ApiGateway.putIntegrationPromised(params)
        .then(integration => { return endpoint; });
    }

    _createEndpointMethodResponse(endpoint) {
      var params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId,
        statusCode: '200',
        responseParameters: {
          'method.response.header.Access-Control-Allow-Methods': true,
          'method.response.header.Access-Control-Allow-Origin': true,
          'method.response.header.Access-Control-Allow-Headers': false,
          'method.response.header.Access-Control-Allow-Credentials': false,
          'method.response.header.Access-Control-Expose-Headers': false,
          'method.response.header.Access-Control-Max-Age': false
        }
      };

      return this.ApiGateway.putMethodResponsePromised(params)
        .then(methodResponse => { return endpoint; });
    }

    _createEndpointIntegrationResponse(endpoint) {
      var params = {
        httpMethod: 'OPTIONS',
        resourceId: endpoint.resource.id,
        restApiId: this.context.restApiId,
        statusCode: '200',
        responseParameters: {
          'method.response.header.Access-Control-Allow-Methods': '\'' + endpoint.allowMethods + '\''
        }
      };

      params.responseParameters['method.response.header.Access-Control-Allow-Origin'] = '\'' + endpoint.allowOrigin + '\'';

      if (!_.isUndefined(endpoint.allowHeaders)) {
        params.responseParameters['method.response.header.Access-Control-Allow-Headers'] = '\'' + endpoint.allowHeaders + '\'';
      }

      if (!_.isUndefined(endpoint.allowCredentials)) {
        params.responseParameters['method.response.header.Access-Control-Allow-Credentials'] = '\'' + endpoint.allowCredentials + '\'';
      }

      if (!_.isUndefined(endpoint.exposeHeaders)) {
        params.responseParameters['method.response.header.Access-Control-Expose-Headers'] = '\'' + endpoint.exposeHeaders + '\'';
      }

      if (!_.isUndefined(endpoint.maxAge)) {
        params.responseParameters['method.response.header.Access-Control-Max-Age'] = '\'' + endpoint.maxAge + '\'';
      }

      return this.ApiGateway.putIntegrationResponsePromised(params)
        .then(integrationResponse => { return endpoint; });
    }

    _deployApi(evt) {
      let params = {
        restApiId: this.context.restApiId,
        stageName: evt.stage,
        description: evt.description || 'Serverless deployment',
        stageDescription: evt.stage,
        variables: {
          functionAlias: evt.stage
        }
      };

      return this.ApiGateway.createDeploymentPromised(params)
        .then(deployment => { return evt; });
    }
  }

  return ServerlessCors;
}
<|endoftext|>


<commit_before>import path from 'path'

import _ from 'lodash'
import postcss from 'postcss'
import stylefmt from 'stylefmt'

import registerConfigAsDependency from './lib/registerConfigAsDependency'
import substituteTailwindPreflightAtRule from './lib/substituteTailwindPreflightAtRule'
import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions'
import substituteTailwindUtilitiesAtRules from './lib/substituteTailwindUtilitiesAtRules'
import substituteVariantsAtRules from './lib/substituteVariantsAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteScreenAtRules from './lib/substituteScreenAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

import mergeConfigWithDefaults from './util/mergeConfigWithDefaults'

const plugin = postcss.plugin('tailwind', config => {
  const plugins = []

  if (!_.isUndefined(config)) {
    plugins.push(registerConfigAsDependency(path.resolve(config)))
  }

  const lazyConfig = () => {
    if (_.isUndefined(config)) {
      return require('../defaultConfig')()
    }

    delete require.cache[require.resolve(path.resolve(config))]
    return mergeConfigWithDefaults(require(path.resolve(config)), require('../defaultConfig')())
  }

  return postcss(
    ...plugins,
    ...[
      substituteTailwindPreflightAtRule(lazyConfig),
      evaluateTailwindFunctions(lazyConfig),
      substituteTailwindUtilitiesAtRules(lazyConfig),
      substituteVariantsAtRules(lazyConfig),
      substituteResponsiveAtRules(lazyConfig),
      substituteScreenAtRules(lazyConfig),
      substituteClassApplyAtRules(lazyConfig),
      stylefmt,
    ]
  )
})

plugin.defaultConfig = function() {
  // prettier-ignore
  throw new Error("`require('tailwindcss').defaultConfig()` is no longer a function, access it instead as `require('tailwindcss/defaultConfig')()`.")
}

module.exports = plugin
<commit_msg>Run perfectionist at end of PostCSS chain in place of stylefmt<commit_after>import path from 'path'

import _ from 'lodash'
import postcss from 'postcss'
import perfectionist from 'perfectionist'

import registerConfigAsDependency from './lib/registerConfigAsDependency'
import substituteTailwindPreflightAtRule from './lib/substituteTailwindPreflightAtRule'
import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions'
import substituteTailwindUtilitiesAtRules from './lib/substituteTailwindUtilitiesAtRules'
import substituteVariantsAtRules from './lib/substituteVariantsAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteScreenAtRules from './lib/substituteScreenAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

import mergeConfigWithDefaults from './util/mergeConfigWithDefaults'

const plugin = postcss.plugin('tailwind', config => {
  const plugins = []

  if (!_.isUndefined(config)) {
    plugins.push(registerConfigAsDependency(path.resolve(config)))
  }

  const lazyConfig = () => {
    if (_.isUndefined(config)) {
      return require('../defaultConfig')()
    }

    delete require.cache[require.resolve(path.resolve(config))]
    return mergeConfigWithDefaults(require(path.resolve(config)), require('../defaultConfig')())
  }

  return postcss(
    ...plugins,
    ...[
      substituteTailwindPreflightAtRule(lazyConfig),
      evaluateTailwindFunctions(lazyConfig),
      substituteTailwindUtilitiesAtRules(lazyConfig),
      substituteVariantsAtRules(lazyConfig),
      substituteResponsiveAtRules(lazyConfig),
      substituteScreenAtRules(lazyConfig),
      substituteClassApplyAtRules(lazyConfig),
      perfectionist({
        cascade: false,
        colorShorthand: false,
        indentSize: 2,
        maxSelectorLength: 1,
        maxValueLength: false,
        trimLeadingZero: false,
        trimTrailingZeros: false,
      }),
    ]
  )
})

plugin.defaultConfig = function() {
  // prettier-ignore
  throw new Error("`require('tailwindcss').defaultConfig()` is no longer a function, access it instead as `require('tailwindcss/defaultConfig')()`.")
}

module.exports = plugin
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';
import {
  deepOrange400,
  blueGrey700,
  teal200,
  grey100, grey300, grey400, grey500, grey900,
  cyan500,
  white, darkBlack, fullBlack,
} from 'material-ui/styles/colors';
// https://www.materialui.co/colors
import {fade} from 'material-ui/utils/colorManipulator';
import spacing from 'material-ui/styles/spacing';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Chip from 'material-ui/Chip';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
import IconButton from 'material-ui/IconButton';
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
import Media from 'react-media';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import {Card, CardActions, CardHeader, CardText} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';
import ArticleCard from './components/ArticleCard.js'

const muiTheme = getMuiTheme({
  palette: {
    primary1Color: deepOrange400,
    primary2Color: blueGrey700,
    primary3Color: teal200,
    accent1Color: grey900,
    accent2Color: grey100,
    accent3Color: grey500,
    textColor: darkBlack,
    alternateTextColor: white,
    canvasColor: white,
    borderColor: grey300,
    disabledColor: fade(darkBlack, 0.3),
    pickerHeaderColor: cyan500,
    clockCircleColor: fade(darkBlack, 0.07),
    shadowColor: fullBlack,
  },
});

injectTapEventPlugin();

const ARTICLEURL = 'http://www.theonion.com/article/trump-spends-entire-classified-national-security-b-53550';
const ARTICLETITLE = 'Fans of Hard Hitting News';
const ARTICLEPUBLISHER = 'The Onion (satire)';
const NAVBARHEIGHT = '75px';
const DEFAULTWIDTH = '380px';
const MINSIDEBARWIDTH = '380px';

const ANNOTATIONS = {
  Mark: {
    text: 'Lorem Ipsum',
  },
};
  //  Maybe this should be an array of arrays of strings?

//  CSS for components
const styles = {
  title: {
    zIndex: 100,
    fontSize: 22,
    color: white,
    paddingLeft: '20px',
    top: '15px',
  },

  navBar: {
    width: '100%',
    height: NAVBARHEIGHT,
    position: 'fixed',
    backgroundColor: deepOrange400,
    top: '0px',
    left: '0px',
  },

  iframeContainer: {
    height: '55%',
    paddingLeft: '25px',
    paddingRight: '25px',
  },

  iframe: {
    border: 'rgba(255, 255, 255, 1)',  // Transparent
    height: '100%',
    minWidth: '330px',
    backgroundColor: 'rgba(255, 255, 255, 1)',  // Transparent
  },

  iconContainer: {
    height: NAVBARHEIGHT,
  },

  rightSidebarText: {
    fontSize: 16,
    paddingLeft: '25px',
    paddingRight: '25px',
  },

  rightSidebar: {
    position: 'fixed',
    backgroundColor: grey100,
    width: '23%',
    minWidth: '23%',
    height: '100%',
    top: NAVBARHEIGHT,
    right: '0px',
  },

  leftSidebarText: {
    fontSize: 16,
    paddingLeft: '25px',
    paddingRight: '25px',
    color: white,
  },

  leftSidebar: {
    position: 'fixed',
    backgroundColor: blueGrey700,
    width: '18%',
    minWidth: '18%',
    height: '100%',
    top: NAVBARHEIGHT,
    left: '0px',
  },

  // card: {
  //   position: 'fixed',
  //   height: '200px',
  //   top: '100px',
  //   left: '330px',
  //   right: '410px',
  // },

  break: {
    color: white,
  },

  cardHeader: {
    color: grey500,
  },
};

// not currently being rendered -- needs to for group / feed view
class SimpleDrawer extends Component {

  constructor(props) {
    super(props);
    this.state = { open: false };
  }

  handleToggle = () => this.setState({ open: !this.state.open });

  render() {
    return (

        <RaisedButton
          label="Toggle Drawer"
          onTouchTap={this.handleToggle}
        />
        <Drawer open={this.state.open}>
          <MenuItem>Menu Item</MenuItem>
          <MenuItem>Menu Item 2</MenuItem>
        </Drawer>

    );
  }
}

const otherStyles = {
  smallIcon: {
    width: 36,
    height: 36,
  },
  small: {
    width: 72,
    height: 72,
    padding: 0,
  },
};

class MyCard extends React.Component {
  constructor(props) {
    super(props);
    this.title = props.title;
    this.subtitle = props.subtitle;
    this.annotationContent = props.annotationContent;
  }

  render() {
    return (

      <MuiThemeProvider muiTheme={muiTheme}>
        <Card>
          <CardHeader style= {styles.cardHeader}
            title={this.title}
            subtitle={this.subtitle}
            actAsExpander={true}
            showExpandableButton={true}
          />
          <CardText expandable={false}>
            {this.annotationContent}
          </CardText>
          <CardActions>
            <FlatButton label="See more" />
          </CardActions>
        </Card>
      </MuiThemeProvider>
    );
  }
}

class ChipExampleArray extends React.Component {

  constructor(props) {
    super(props);
    this.state = { chipData: [
      { key: 0, label: 'politics' },
      { key: 1, label: '@cblanc' },
      { key: 2, label: 'X' },
      { key: 3, label: 'Y' },
    ] };
    this.styles = {
      chip: {
        margin: 4,
      },
      wrapper: {
        display: 'flex',
        flexWrap: 'wrap',
      },
    };
  }

  handleRequestDelete = (key) => {
    if (key === 3) {
      alert('Are you sure you want to delete _?');
      return;
    }

    this.chipData = this.state.chipData;
    const chipToDelete = this.chipData.map((chip) => chip.key).indexOf(key);
    this.chipData.splice(chipToDelete, 1);
    this.setState({ chipData: this.chipData });
  };

  renderChip(data) {
    return (
      <Chip
        key={data.key}
        onRequestDelete={() => this.handleRequestDelete(data.key)}
        style={this.styles.chip}
      >
        {data.label}
      </Chip>
    );
  }

  render() {
    return (

        {this.state.chipData.map(this.renderChip, this)}

    );
  }
}

class NavBar extends Component {
  render() {
    return (

{ARTICLETITLE}

    );
  }
}

class LeftSideBar extends Component {
  render() {
    return (

ethan 994

    );
  }
}

class RightSideBar extends Component {
  render() {
    return (

Will eventually be chat!

    );
  }
}

class MiddleContent extends Component {
  render() {
    return (

        <ArticleCard id="card1"
        title="Officials Struggling To Condense Trump’s Intelligence Briefing Down To One Word"
        subtitle="The president tends to grow frustrated if crucial intelligence is not delivered within the first seven letters or so. We recently gave him a briefing that consisted only of the term ‘nuclear proliferation,’ but he clearly became distracted by the end of the"
        annotationContent= "here goes the annotation content"
        username= "cblanc"
        points={16}
        timeSince = "4 hours"
        numUsers={8}
        numAnnotations={6}
        numReplies={4}
        />

    );
  }
}

class App extends Component {

  render() {
    return (

        <MuiThemeProvider>
          <RightSideBar />
        </MuiThemeProvider>
        <MuiThemeProvider>
          <LeftSideBar />
        </MuiThemeProvider>
        <MuiThemeProvider>
          <NavBar />
        </MuiThemeProvider>
        <MuiThemeProvider>
          <MiddleContent />
        </MuiThemeProvider>

    );
  }
}

ReactDOM.render(<App />, document.getElementById('main'));
<commit_msg>fixed z index so nav bar always on top of content<commit_after>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';
import {
  deepOrange400,
  blueGrey700,
  teal200,
  grey100, grey300, grey400, grey500, grey900,
  cyan500,
  white, darkBlack, fullBlack,
} from 'material-ui/styles/colors';
// https://www.materialui.co/colors
import {fade} from 'material-ui/utils/colorManipulator';
import spacing from 'material-ui/styles/spacing';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Chip from 'material-ui/Chip';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
import IconButton from 'material-ui/IconButton';
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
import Media from 'react-media';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import {Card, CardActions, CardHeader, CardText} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';
import ArticleCard from './components/ArticleCard.js'

const muiTheme = getMuiTheme({
  palette: {
    primary1Color: deepOrange400,
    primary2Color: blueGrey700,
    primary3Color: teal200,
    accent1Color: grey900,
    accent2Color: grey100,
    accent3Color: grey500,
    textColor: darkBlack,
    alternateTextColor: white,
    canvasColor: white,
    borderColor: grey300,
    disabledColor: fade(darkBlack, 0.3),
    pickerHeaderColor: cyan500,
    clockCircleColor: fade(darkBlack, 0.07),
    shadowColor: fullBlack,
  },
});

injectTapEventPlugin();

const ARTICLEURL = 'http://www.theonion.com/article/trump-spends-entire-classified-national-security-b-53550';
const ARTICLETITLE = 'Fans of Hard Hitting News';
const ARTICLEPUBLISHER = 'The Onion (satire)';
const NAVBARHEIGHT = '75px';
const DEFAULTWIDTH = '380px';
const MINSIDEBARWIDTH = '380px';

const ANNOTATIONS = {
  Mark: {
    text: 'Lorem Ipsum',
  },
};
  //  Maybe this should be an array of arrays of strings?

//  CSS for components
const styles = {
  title: {
    zIndex: 100,
    fontSize: 22,
    color: white,
    paddingLeft: '20px',
    top: '15px',
  },

  navBar: {
    width: '100%',
    height: NAVBARHEIGHT,
    position: 'fixed',
    zIndex: 200,
    backgroundColor: deepOrange400,
    top: '0px',
    left: '0px',
  },

  iframeContainer: {
    height: '55%',
    paddingLeft: '25px',
    paddingRight: '25px',
  },

  iframe: {
    border: 'rgba(255, 255, 255, 1)',  // Transparent
    height: '100%',
    minWidth: '330px',
    backgroundColor: 'rgba(255, 255, 255, 1)',  // Transparent
  },

  iconContainer: {
    height: NAVBARHEIGHT,
  },

  rightSidebarText: {
    fontSize: 16,
    paddingLeft: '25px',
    paddingRight: '25px',
  },

  rightSidebar: {
    position: 'fixed',
    backgroundColor: grey100,
    width: '23%',
    minWidth: '23%',
    height: '100%',
    top: NAVBARHEIGHT,
    right: '0px',
  },

  leftSidebarText: {
    fontSize: 16,
    paddingLeft: '25px',
    paddingRight: '25px',
    color: white,
  },

  leftSidebar: {
    position: 'fixed',
    backgroundColor: blueGrey700,
    width: '18%',
    minWidth: '18%',
    height: '100%',
    top: NAVBARHEIGHT,
    left: '0px',
  },

  // card: {
  //   position: 'fixed',
  //   height: '200px',
  //   top: '100px',
  //   left: '330px',
  //   right: '410px',
  // },

  break: {
    color: white,
  },

  cardHeader: {
    color: grey500,
  },
};

// not currently being rendered -- needs to for group / feed view
class SimpleDrawer extends Component {

  constructor(props) {
    super(props);
    this.state = { open: false };
  }

  handleToggle = () => this.setState({ open: !this.state.open });

  render() {
    return (

        <RaisedButton
          label="Toggle Drawer"
          onTouchTap={this.handleToggle}
        />
        <Drawer open={this.state.open}>
          <MenuItem>Menu Item</MenuItem>
          <MenuItem>Menu Item 2</MenuItem>
        </Drawer>

    );
  }
}

const otherStyles = {
  smallIcon: {
    width: 36,
    height: 36,
  },
  small: {
    width: 72,
    height: 72,
    padding: 0,
  },
};

class MyCard extends React.Component {
  constructor(props) {
    super(props);
    this.title = props.title;
    this.subtitle = props.subtitle;
    this.annotationContent = props.annotationContent;
  }

  render() {
    return (

      <MuiThemeProvider muiTheme={muiTheme}>
        <Card>
          <CardHeader style= {styles.cardHeader}
            title={this.title}
            subtitle={this.subtitle}
            actAsExpander={true}
            showExpandableButton={true}
          />
          <CardText expandable={false}>
            {this.annotationContent}
          </CardText>
          <CardActions>
            <FlatButton label="See more" />
          </CardActions>
        </Card>
      </MuiThemeProvider>
    );
  }
}

class ChipExampleArray extends React.Component {

  constructor(props) {
    super(props);
    this.state = { chipData: [
      { key: 0, label: 'politics' },
      { key: 1, label: '@cblanc' },
      { key: 2, label: 'X' },
      { key: 3, label: 'Y' },
    ] };
    this.styles = {
      chip: {
        margin: 4,
      },
      wrapper: {
        display: 'flex',
        flexWrap: 'wrap',
      },
    };
  }

  handleRequestDelete = (key) => {
    if (key === 3) {
      alert('Are you sure you want to delete _?');
      return;
    }

    this.chipData = this.state.chipData;
    const chipToDelete = this.chipData.map((chip) => chip.key).indexOf(key);
    this.chipData.splice(chipToDelete, 1);
    this.setState({ chipData: this.chipData });
  };

  renderChip(data) {
    return (
      <Chip
        key={data.key}
        onRequestDelete={() => this.handleRequestDelete(data.key)}
        style={this.styles.chip}
      >
        {data.label}
      </Chip>
    );
  }

  render() {
    return (

        {this.state.chipData.map(this.renderChip, this)}

    );
  }
}

class NavBar extends Component {
  render() {
    return (

{ARTICLETITLE}

    );
  }
}

class LeftSideBar extends Component {
  render() {
    return (

ethan 994

    );
  }
}

class RightSideBar extends Component {
  render() {
    return (

Will eventually be chat!

    );
  }
}

class MiddleContent extends Component {
  render() {
    return (

        <ArticleCard id="card1"
        title="Officials Struggling To Condense Trump’s Intelligence Briefing Down To One Word"
        subtitle="The president tends to grow frustrated if crucial intelligence is not delivered within the first seven letters or so. We recently gave him a briefing that consisted only of the term ‘nuclear proliferation,’ but he clearly became distracted by the end of the"
        annotationContent= "here goes the annotation content"
        username= "cblanc"
        points={16}
        timeSince = "4 hours"
        numUsers={8}
        numAnnotations={6}
        numReplies={4}
        />
        <ArticleCard id="card2"
        title="Officials Struggling To Condense Trump’s Intelligence Briefing Down To One Word"
        subtitle="The president tends to grow frustrated if crucial intelligence is not delivered within the first seven letters or so. We recently gave him a briefing that consisted only of the term ‘nuclear proliferation,’ but he clearly became distracted by the end of the"
        annotationContent= "here goes the annotation content"
        username= "cblanc"
        points={16}
        timeSince = "4 hours"
        numUsers={8}
        numAnnotations={6}
        numReplies={4}
        />
        <ArticleCard id="card3"
        title="Officials Struggling To Condense Trump’s Intelligence Briefing Down To One Word"
        subtitle="The president tends to grow frustrated if crucial intelligence is not delivered within the first seven letters or so. We recently gave him a briefing that consisted only of the term ‘nuclear proliferation,’ but he clearly became distracted by the end of the"
        annotationContent= "here goes the annotation content"
        username= "cblanc"
        points={16}
        timeSince = "4 hours"
        numUsers={8}
        numAnnotations={6}
        numReplies={4}
        />
        <ArticleCard id="card4"
        title="Officials Struggling To Condense Trump’s Intelligence Briefing Down To One Word"
        subtitle="The president tends to grow frustrated if crucial intelligence is not delivered within the first seven letters or so. We recently gave him a briefing that consisted only of the term ‘nuclear proliferation,’ but he clearly became distracted by the end of the"
        annotationContent= "here goes the annotation content"
        username= "cblanc"
        points={16}
        timeSince = "4 hours"
        numUsers={8}
        numAnnotations={6}
        numReplies={4}
        />

    );
  }
}

class App extends Component {

  render() {
    return (

        <MuiThemeProvider>
          <RightSideBar />
        </MuiThemeProvider>
        <MuiThemeProvider>
          <LeftSideBar />
        </MuiThemeProvider>
        <MuiThemeProvider>
          <NavBar />
        </MuiThemeProvider>
        <MuiThemeProvider>
          <MiddleContent />
        </MuiThemeProvider>

    );
  }
}

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


<commit_before>import NoSleep from 'nosleep.js'

const noSleep = new NoSleep()

const timersEl = document.querySelector('.timers')
const display = document.querySelector('.display')
const timeOutputEl = document.querySelector('.time-output')
const gradientBottom = document.querySelector('.gradient--bottom')
const playPauseEl = document.querySelector('.control-button--pause')

let isRunning = false

const stopTimer = () => {
  isRunning = false
  noSleep.disable()
}

let displayTime

const startTimer = ({duration = displayTime * 1000, startTime}) => {
  noSleep.enable()
  isRunning = true
  playPauseEl.disabled = false

  const renderLoop = () => {
    if (!isRunning) return
    requestAnimationFrame(renderLoop)
    const newDisplayTime = Math.round((duration + startTime - Date.now()) / 1000)
    if (newDisplayTime === displayTime) return
    if (newDisplayTime === 0) {
      stopTimer()
      playPauseEl.disabled = true
    }
    displayTime = newDisplayTime
    timeOutputEl.innerText =
    ('0' + Math.floor(displayTime / 60)).slice(-2) +
    ':' +
    ('0' + displayTime % 60).slice(-2)
  }

  requestAnimationFrame(renderLoop)
}

for (const el of document.querySelectorAll('.timer-button')) {
  el.onclick = () => {
    gradientBottom.classList.add('gradient--bottom--hidden')
    display.classList.remove('display--hidden')
    timersEl.classList.add('timers--hidden')

    startTimer({
      duration: Number(el.getAttribute('data-time')) * 1000 * 60,
      startTime: Date.now(),
    })
  }
}

playPauseEl.onclick = () => {
  if (playPauseEl.classList.contains('control-button--pause')) {
    stopTimer()
    playPauseEl.classList.remove('control-button--pause')
    playPauseEl.classList.add('control-button--play')
  } else {
    startTimer({startTime: Date.now()})
    playPauseEl.classList.remove('control-button--play')
    playPauseEl.classList.add('control-button--pause')
  }
}

document.querySelector('.control-button--stop').onclick = () => {
  stopTimer()
  playPauseEl.classList.add('control-button--pause')
  gradientBottom.classList.remove('gradient--bottom--hidden')
  display.classList.add('display--hidden')
  timersEl.classList.remove('timers--hidden')
  noSleep.disable()
}
<commit_msg>fix(play-pause): Properly reset visual state when stop is pressed<commit_after>import NoSleep from 'nosleep.js'

const noSleep = new NoSleep()

const timersEl = document.querySelector('.timers')
const display = document.querySelector('.display')
const timeOutputEl = document.querySelector('.time-output')
const gradientBottom = document.querySelector('.gradient--bottom')
const playPauseEl = document.querySelector('.control-button--pause')

let isRunning = false

const stopTimer = () => {
  isRunning = false
  noSleep.disable()
}

let displayTime

const startTimer = ({duration = displayTime * 1000, startTime}) => {
  noSleep.enable()
  isRunning = true
  playPauseEl.disabled = false

  const renderLoop = () => {
    if (!isRunning) return
    requestAnimationFrame(renderLoop)
    const newDisplayTime = Math.round((duration + startTime - Date.now()) / 1000)
    if (newDisplayTime === displayTime) return
    if (newDisplayTime === 0) {
      stopTimer()
      playPauseEl.disabled = true
    }
    displayTime = newDisplayTime
    timeOutputEl.innerText =
    ('0' + Math.floor(displayTime / 60)).slice(-2) +
    ':' +
    ('0' + displayTime % 60).slice(-2)
  }

  requestAnimationFrame(renderLoop)
}

for (const el of document.querySelectorAll('.timer-button')) {
  el.onclick = () => {
    gradientBottom.classList.add('gradient--bottom--hidden')
    display.classList.remove('display--hidden')
    timersEl.classList.add('timers--hidden')

    startTimer({
      duration: Number(el.getAttribute('data-time')) * 1000 * 60,
      startTime: Date.now(),
    })
  }
}

playPauseEl.onclick = () => {
  if (playPauseEl.classList.contains('control-button--pause')) {
    stopTimer()
    playPauseEl.classList.remove('control-button--pause')
    playPauseEl.classList.add('control-button--play')
  } else {
    startTimer({startTime: Date.now()})
    playPauseEl.classList.remove('control-button--play')
    playPauseEl.classList.add('control-button--pause')
  }
}

document.querySelector('.control-button--stop').onclick = () => {
  stopTimer()
  playPauseEl.classList.remove('control-button--play')
  playPauseEl.classList.add('control-button--pause')
  gradientBottom.classList.remove('gradient--bottom--hidden')
  display.classList.add('display--hidden')
  timersEl.classList.remove('timers--hidden')
  noSleep.disable()
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Router, Route, IndexRoute, IndexRedirect, Redirect } from 'react-router';
import { routerActions } from 'react-router-redux';
import { connectedReduxRedirect } from 'redux-auth-wrapper/history3/redirect';

import { setConfig } from './app/config/actions';
import App from './app/App';
import Layout from './app/global/Layout';
import LoginController from './app/views/login/LoginController';
import CollectionsController from './app/views/collections/CollectionsController';
import TeamsController from './app/views/teams/TeamsController';
import SelectADataset from './app/views/datasets-new/DatasetsController';
import DatasetEditionsController from './app/views/datasets-new/editions/DatasetEditionsController';
import DatasetVersionsController from './app/views/datasets-new/versions/DatasetVersionsController';
import DatasetMetadataController from './app/views/datasets-new/edit-metadata/DatasetMetadataController';
import DatasetsController from './app/views/datasets/DatasetsController';
import DatasetUploadsController from './app/views/uploads/dataset/DatasetUploadsController';
import DatasetUploadDetails from './app/views/uploads/dataset/upload-details/DatasetUploadDetails';
import DatasetUploadMetadata from './app/views/uploads/dataset/upload-details/DatasetUploadMetadata'
import DatasetMetadata from './app/views/datasets/metadata/DatasetMetadata';
import VersionMetadata from './app/views/datasets/metadata/VersionMetadata';
import Logs from './app/views/logs/Logs';

import auth from './app/utilities/auth'

import './scss/main.scss';

import { store, history } from './app/config/store';

import SelectableTest from './SelectableTest';
import DatasetPreviewController from './app/views/datasets/preview/DatasetPreviewController';
import VersionPreviewController from './app/views/datasets/preview/VersionPreviewController';
import PreviewController from './app/views/preview/PreviewController';

const config = window.getEnv();
store.dispatch(setConfig(config));

const rootPath = store.getState().state.rootPath;

const userIsAuthenticated = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAuthenticated(state.state.user);
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: 'UserIsAuthenticated',
    redirectPath: `${rootPath}/login`
});

const userisAdminOrEditor = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAdminOrEditor(state.state.user)
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: 'userisAdminOrEditor',
    redirectPath: `${rootPath}/collections`,
    allowRedirectBack: false
})

class UnknownRoute extends Component {
    render() {
        return (

Sorry, this page couldnt be found

        )
    }
}

class Index extends Component {
    render() {
        return (
            <Provider store={ store }>
                <Router history={ history }>
                    <Route component={ App }>
                        <Route component={ Layout }>
                            <Redirect from={`${rootPath}`} to={`${rootPath}/collections`} />
                            <Route path={`${rootPath}/collections`} component={ userIsAuthenticated(CollectionsController) }>
                                <Route path=':collectionID' component={ userIsAuthenticated(CollectionsController) }>
                                    <Route path='edit' component={ userIsAuthenticated(CollectionsController) }/>
                                    <Route path='restore-content' component={ userIsAuthenticated(CollectionsController) }/>
                                </Route>
                            </Route>
                            <Route path={`${rootPath}/collections/:collectionID/preview`} component={ userIsAuthenticated(PreviewController) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets`} component={ userIsAuthenticated(SelectADataset) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets/:datasetID`} component={ userIsAuthenticated(DatasetEditionsController) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets/:datasetID/editions/:editionID`} component={ userIsAuthenticated(DatasetVersionsController) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets/:datasetID/editions/:editionID/versions/:versionID`} component={ userIsAuthenticated(DatasetMetadataController) }/>
                            <Route path={`${rootPath}/teams`} component={ userIsAuthenticated(userisAdminOrEditor(TeamsController)) }>
                                <Route path=":team" component={ userIsAuthenticated(TeamsController) }>
                                    <Route path="edit" component={ userIsAuthenticated(TeamsController) }/>
                                    <Route path="delete" component={ userIsAuthenticated(TeamsController) }/>
                                </Route>
                            </Route>
                            {config.enableDatasetImport === true &&
                                <Route>
                                    <Route path={`${rootPath}/uploads`}>
                                        <IndexRedirect to="data" />
                                        <Route path="data">
                                            <IndexRoute component={userIsAuthenticated(userisAdminOrEditor(DatasetUploadsController))} />
                                            <Route path=":jobID">
                                                <IndexRoute component={ userIsAuthenticated(userisAdminOrEditor(DatasetUploadDetails)) } />
                                                <Route path="metadata" component={ userIsAuthenticated(userisAdminOrEditor(DatasetUploadMetadata)) } />
                                            </Route>
                                        </Route>
                                    </Route>
                                    <Route path={`${rootPath}/datasets`} >
                                        <IndexRoute component={ userIsAuthenticated(userisAdminOrEditor(DatasetsController)) } />
                                        <Route path=":datasetID">
                                            <IndexRedirect to={`${rootPath}/datasets`} />
                                            <Route path="preview" component={ userIsAuthenticated(userisAdminOrEditor(DatasetPreviewController)) } />
                                            <Route path="metadata" component={ userIsAuthenticated(userisAdminOrEditor(DatasetMetadata)) } />
                                            <Route path="editions/:edition/versions/:version">
                                                <IndexRedirect to="metadata"/>
                                                <Route path="metadata" component={ userIsAuthenticated(userisAdminOrEditor(VersionMetadata)) }/>
                                                <Route path="preview" component={ userIsAuthenticated(userisAdminOrEditor(VersionPreviewController)) } />
                                            </Route>
                                            <Route path="instances">
                                                <IndexRedirect to={`${rootPath}/datasets`}/>
                                                <Route path=":instanceID/metadata" component={ userIsAuthenticated(userisAdminOrEditor(VersionMetadata)) } />
                                            </Route>
                                        </Route>
                                    </Route>
                                </Route>
                            }
                            <Route path={`${rootPath}/selectable-list`} component={ SelectableTest } />
                            <Route path={`${rootPath}/logs`} component={ Logs } />
                            <Route path={`${rootPath}/login`} component={ LoginController } />
                            <Route path="*" component={ UnknownRoute } />
                        </Route>
                    </Route>
                </Router>
            </Provider>
        )
    }
}

ReactDOM.render(<Index/>, document.getElementById('app'));
<commit_msg>Set up route for edit metadata item component<commit_after>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Router, Route, IndexRoute, IndexRedirect, Redirect } from 'react-router';
import { routerActions } from 'react-router-redux';
import { connectedReduxRedirect } from 'redux-auth-wrapper/history3/redirect';

import { setConfig } from './app/config/actions';
import App from './app/App';
import Layout from './app/global/Layout';
import LoginController from './app/views/login/LoginController';
import CollectionsController from './app/views/collections/CollectionsController';
import TeamsController from './app/views/teams/TeamsController';
import SelectADataset from './app/views/datasets-new/DatasetsController';
import DatasetEditionsController from './app/views/datasets-new/editions/DatasetEditionsController';
import DatasetVersionsController from './app/views/datasets-new/versions/DatasetVersionsController';
import DatasetMetadataController from './app/views/datasets-new/edit-metadata/DatasetMetadataController';
import DatasetsController from './app/views/datasets/DatasetsController';
import DatasetUploadsController from './app/views/uploads/dataset/DatasetUploadsController';
import DatasetUploadDetails from './app/views/uploads/dataset/upload-details/DatasetUploadDetails';
import DatasetUploadMetadata from './app/views/uploads/dataset/upload-details/DatasetUploadMetadata'
import DatasetMetadata from './app/views/datasets/metadata/DatasetMetadata';
import VersionMetadata from './app/views/datasets/metadata/VersionMetadata';
import Logs from './app/views/logs/Logs';

import auth from './app/utilities/auth'

import './scss/main.scss';

import { store, history } from './app/config/store';

import SelectableTest from './SelectableTest';
import DatasetPreviewController from './app/views/datasets/preview/DatasetPreviewController';
import VersionPreviewController from './app/views/datasets/preview/VersionPreviewController';
import PreviewController from './app/views/preview/PreviewController';
import EditMetadatItem from './app/views/datasets-new/edit-metadata/EditMetadataItem';

const config = window.getEnv();
store.dispatch(setConfig(config));

const rootPath = store.getState().state.rootPath;

const userIsAuthenticated = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAuthenticated(state.state.user);
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: 'UserIsAuthenticated',
    redirectPath: `${rootPath}/login`
});

const userisAdminOrEditor = connectedReduxRedirect({
    authenticatedSelector: state => {
        return auth.isAdminOrEditor(state.state.user)
    },
    redirectAction: routerActions.replace,
    wrapperDisplayName: 'userisAdminOrEditor',
    redirectPath: `${rootPath}/collections`,
    allowRedirectBack: false
})

class UnknownRoute extends Component {
    render() {
        return (

Sorry, this page couldnt be found

        )
    }
}

class Index extends Component {
    render() {
        return (
            <Provider store={ store }>
                <Router history={ history }>
                    <Route component={ App }>
                        <Route component={ Layout }>
                            <Redirect from={`${rootPath}`} to={`${rootPath}/collections`} />
                            <Route path={`${rootPath}/collections`} component={ userIsAuthenticated(CollectionsController) }>
                                <Route path=':collectionID' component={ userIsAuthenticated(CollectionsController) }>
                                    <Route path='edit' component={ userIsAuthenticated(CollectionsController) }/>
                                    <Route path='restore-content' component={ userIsAuthenticated(CollectionsController) }/>
                                </Route>
                            </Route>
                            <Route path={`${rootPath}/collections/:collectionID/preview`} component={ userIsAuthenticated(PreviewController) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets`} component={ userIsAuthenticated(SelectADataset) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets/:datasetID`} component={ userIsAuthenticated(DatasetEditionsController) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets/:datasetID/editions/:editionID`} component={ userIsAuthenticated(DatasetVersionsController) }/>
                            <Route path={`${rootPath}/collections/:collectionID/datasets/:datasetID/editions/:editionID/versions/:versionID`} component={ userIsAuthenticated(DatasetMetadataController) }>
                                <Route path={`${rootPath}/collections/:collectionID/datasets/:datasetID/editions/:editionID/versions/:versionID/edit/:metadataField/:metadataItemID`} component={ userIsAuthenticated(EditMetadatItem) }/>
                            </Route>
                            <Route path={`${rootPath}/teams`} component={ userIsAuthenticated(userisAdminOrEditor(TeamsController)) }>
                                <Route path=":team" component={ userIsAuthenticated(TeamsController) }>
                                    <Route path="edit" component={ userIsAuthenticated(TeamsController) }/>
                                    <Route path="delete" component={ userIsAuthenticated(TeamsController) }/>
                                </Route>
                            </Route>
                            {config.enableDatasetImport === true &&
                                <Route>
                                    <Route path={`${rootPath}/uploads`}>
                                        <IndexRedirect to="data" />
                                        <Route path="data">
                                            <IndexRoute component={userIsAuthenticated(userisAdminOrEditor(DatasetUploadsController))} />
                                            <Route path=":jobID">
                                                <IndexRoute component={ userIsAuthenticated(userisAdminOrEditor(DatasetUploadDetails)) } />
                                                <Route path="metadata" component={ userIsAuthenticated(userisAdminOrEditor(DatasetUploadMetadata)) } />
                                            </Route>
                                        </Route>
                                    </Route>
                                    <Route path={`${rootPath}/datasets`} >
                                        <IndexRoute component={ userIsAuthenticated(userisAdminOrEditor(DatasetsController)) } />
                                        <Route path=":datasetID">
                                            <IndexRedirect to={`${rootPath}/datasets`} />
                                            <Route path="preview" component={ userIsAuthenticated(userisAdminOrEditor(DatasetPreviewController)) } />
                                            <Route path="metadata" component={ userIsAuthenticated(userisAdminOrEditor(DatasetMetadata)) } />
                                            <Route path="editions/:edition/versions/:version">
                                                <IndexRedirect to="metadata"/>
                                                <Route path="metadata" component={ userIsAuthenticated(userisAdminOrEditor(VersionMetadata)) }/>
                                                <Route path="preview" component={ userIsAuthenticated(userisAdminOrEditor(VersionPreviewController)) } />
                                            </Route>
                                            <Route path="instances">
                                                <IndexRedirect to={`${rootPath}/datasets`}/>
                                                <Route path=":instanceID/metadata" component={ userIsAuthenticated(userisAdminOrEditor(VersionMetadata)) } />
                                            </Route>
                                        </Route>
                                    </Route>
                                </Route>
                            }
                            <Route path={`${rootPath}/selectable-list`} component={ SelectableTest } />
                            <Route path={`${rootPath}/logs`} component={ Logs } />
                            <Route path={`${rootPath}/login`} component={ LoginController } />
                            <Route path="*" component={ UnknownRoute } />
                        </Route>
                    </Route>
                </Router>
            </Provider>
        )
    }
}

ReactDOM.render(<Index/>, document.getElementById('app'));
<|endoftext|>


<commit_before>import request from 'request-promise'
import fs from 'fs'

const BASE_SENTRY_URL = 'https://sentry.io/api/0/projects'

const DEFAULT_INCLUDE = /\.js$|\.map$/
const DEFAULT_TRANSFORM = filename => `~/${filename}`
const DEFAULT_DELETE_REGEX = /\.map$/

module.exports = class SentryPlugin {
  constructor(options) {
    this.baseSentryURL = options.baseSentryURL || BASE_SENTRY_URL
    this.organisationSlug = options.organisation
    this.projectSlug = options.project
    this.apiKey = options.apiKey

    this.releaseVersion = options.release

    this.include = options.include || DEFAULT_INCLUDE
    this.exclude = options.exclude

    this.filenameTransform = options.filenameTransform || DEFAULT_TRANSFORM
    this.suppressErrors = options.suppressErrors

    this.deleteAfterCompile = options.deleteAfterCompile
    this.deleteRegex = options.deleteRegex || DEFAULT_DELETE_REGEX
  }

  apply(compiler) {
    compiler.plugin('after-emit', (compilation, cb) => {
      const errors = this.ensureRequiredOptions()

      if (errors) {
        return this.handleErrors(errors, compilation, cb)
      }

      const files = this.getFiles(compilation)

      if (typeof this.releaseVersion === 'function') {
        this.releaseVersion = this.releaseVersion(compilation.hash)
      }

      return this.createRelease()
        .then(() => this.uploadFiles(files))
        .then(() => cb())
        .catch(err => this.handleErrors(err, compilation, cb))
    })

    compiler.plugin('done', (stats) => {
      if (this.deleteAfterCompile) {
        this.deleteFiles(stats)
      }
    })
  }

  handleErrors(err, compilation, cb) {
    const errorMsg = `Sentry Plugin: ${err}`
    if (this.suppressErrors) {
      compilation.warnings.push(errorMsg)
    }
    else {
      compilation.errors.push(errorMsg)
    }

    cb()
  }

  ensureRequiredOptions() {
    if (!this.organisationSlug) {
      return new Error('Must provide organisation')
    }
    else if (!this.projectSlug) {
      return new Error('Must provide project')
    }
    else if (!this.apiKey) {
      return new Error('Must provide api key')
    }
    else if (!this.releaseVersion) {
      return new Error('Must provide release version')
    }
    else {
      return null
    }
  }

  getFiles(compilation) {
    return Object.keys(compilation.assets)
      .map((name) => {
        if (this.isIncludeOrExclude(name)) {
          return { name, path: compilation.assets[name].existsAt }
        }
        return null
      })
      .filter(i => i)
  }

  isIncludeOrExclude(filename) {
    const isIncluded = this.include ? this.include.test(filename) : true
    const isExcluded = this.exclude ? this.exclude.test(filename) : false

    return isIncluded && !isExcluded
  }

  createRelease() {
    return request({
      url: `${this.sentryReleaseUrl()}/`,
      method: 'POST',
      auth: {
        bearer: this.apiKey,
      },
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ version: this.releaseVersion }),
    })
  }

  uploadFiles(files) {
    return Promise.all(files.map(this.uploadFile.bind(this)))
  }

  uploadFile({ path, name }) {
    return request({
      url: `${this.sentryReleaseUrl()}/${this.releaseVersion}/files/`,
      method: 'POST',
      auth: {
        bearer: this.apiKey,
      },
      formData: {
        file: fs.createReadStream(path),
        name: this.filenameTransform(name),
      },
    })
  }

  sentryReleaseUrl() {
    return `${this.baseSentryURL}/${this.organisationSlug}/${this.projectSlug}/releases` // eslint-disable-line max-len
  }

  deleteFiles(stats) {
    Object.keys(stats.compilation.assets)
      .filter(name => this.deleteRegex.test(name))
      .forEach((name) => {
        const { existsAt } = stats.compilation.assets[name]
        fs.unlinkSync(existsAt)
      })
  }
}
<commit_msg>Update index.js<commit_after>import request from 'request-promise'
import fs from 'fs'

const BASE_SENTRY_URL = 'https://sentry.io/api/0/projects'

const DEFAULT_INCLUDE = /\.js$|\.map$/
const DEFAULT_TRANSFORM = filename => `~/${filename}`
const DEFAULT_DELETE_REGEX = /\.map$/
const DEFAULT_BODY_TRANSFORM = version => ({ version })

module.exports = class SentryPlugin {
  constructor(options) {
    this.baseSentryURL = options.baseSentryURL || BASE_SENTRY_URL
    this.organisationSlug = options.organisation
    this.projectSlug = options.project
    this.apiKey = options.apiKey

    this.bodyTransform = options.bodyTransform || DEFAULT_BODY_TRANSFORM
    this.releaseVersion = options.release

    this.include = options.include || DEFAULT_INCLUDE
    this.exclude = options.exclude

    this.filenameTransform = options.filenameTransform || DEFAULT_TRANSFORM
    this.suppressErrors = options.suppressErrors

    this.deleteAfterCompile = options.deleteAfterCompile
    this.deleteRegex = options.deleteRegex || DEFAULT_DELETE_REGEX
  }

  apply(compiler) {
    compiler.plugin('after-emit', (compilation, cb) => {
      const errors = this.ensureRequiredOptions()

      if (errors) {
        return this.handleErrors(errors, compilation, cb)
      }

      const files = this.getFiles(compilation)

      if (typeof this.releaseVersion === 'function') {
        this.releaseVersion = this.releaseVersion(compilation.hash)
      }

      return this.createRelease()
        .then(() => this.uploadFiles(files))
        .then(() => cb())
        .catch(err => this.handleErrors(err, compilation, cb))
    })

    compiler.plugin('done', (stats) => {
      if (this.deleteAfterCompile) {
        this.deleteFiles(stats)
      }
    })
  }

  handleErrors(err, compilation, cb) {
    const errorMsg = `Sentry Plugin: ${err}`
    if (this.suppressErrors) {
      compilation.warnings.push(errorMsg)
    }
    else {
      compilation.errors.push(errorMsg)
    }

    cb()
  }

  ensureRequiredOptions() {
    if (!this.organisationSlug) {
      return new Error('Must provide organisation')
    }
    else if (!this.projectSlug) {
      return new Error('Must provide project')
    }
    else if (!this.apiKey) {
      return new Error('Must provide api key')
    }
    else if (!this.releaseVersion) {
      return new Error('Must provide release version')
    }
    else {
      return null
    }
  }

  getFiles(compilation) {
    return Object.keys(compilation.assets)
      .map((name) => {
        if (this.isIncludeOrExclude(name)) {
          return { name, path: compilation.assets[name].existsAt }
        }
        return null
      })
      .filter(i => i)
  }

  isIncludeOrExclude(filename) {
    const isIncluded = this.include ? this.include.test(filename) : true
    const isExcluded = this.exclude ? this.exclude.test(filename) : false

    return isIncluded && !isExcluded
  }

  createRelease() {
    return request({
      url: `${this.sentryReleaseUrl()}/`,
      method: 'POST',
      auth: {
        bearer: this.apiKey,
      },
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(this.bodyTransform(this.releaseVersion)),
    })
  }

  uploadFiles(files) {
    return Promise.all(files.map(this.uploadFile.bind(this)))
  }

  uploadFile({ path, name }) {
    return request({
      url: `${this.sentryReleaseUrl()}/${this.releaseVersion}/files/`,
      method: 'POST',
      auth: {
        bearer: this.apiKey,
      },
      formData: {
        file: fs.createReadStream(path),
        name: this.filenameTransform(name),
      },
    })
  }

  sentryReleaseUrl() {
    return `${this.baseSentryURL}/${this.organisationSlug}/${this.projectSlug}/releases` // eslint-disable-line max-len
  }

  deleteFiles(stats) {
    Object.keys(stats.compilation.assets)
      .filter(name => this.deleteRegex.test(name))
      .forEach((name) => {
        const { existsAt } = stats.compilation.assets[name]
        fs.unlinkSync(existsAt)
      })
  }
}
<|endoftext|>


<commit_before>var _ = require("lodash");
var λ = require("contra");
var DB = require("./DB");
var krl = {
  stdlib: require("krl-stdlib"),
  Closure: require("./KRLClosure")
};
var getArg = require("./getArg");
var Future = require("fibers/future");
var modules = require("./modules");
var evalRule = require("./evalRule");
var SymbolTable = require("symbol-table");
var applyInFiber = require("./applyInFiber");
var EventEmitter = require("events");
var selectRulesToEval = require("./selectRulesToEval");

var mkCTX = function(ctx){
  ctx.getArg = getArg;
  ctx.krl = krl;
  return ctx;
};

var rulesets = {};
var salience_graph = {};

var doInstallRuleset = function(rs){
  rs.scope = SymbolTable();
  if(_.isFunction(rs.global)){
    rs.global(mkCTX({
      scope: rs.scope
    }));
  }
  _.each(rs.rules, function(rule){
    rule.rid = rs.rid;

    _.each(rule.select && rule.select.graph, function(g, domain){
      _.each(g, function(exprs, type){
        _.set(salience_graph, [domain, type, rule.rid, rule.name], true);
      });
    });
  });
  rulesets[rs.rid] = rs;
};

var installRuleset = function(rs, callback){
  applyInFiber(doInstallRuleset, null, [rs], callback);
};

module.exports = function(conf){
  var db = Future.wrap(DB(conf.db));
  var compileAndLoadRuleset = conf.compileAndLoadRuleset;

  var emitter = new EventEmitter();
  krl.stdlib.emitter.on("klog", function(val, message){
    emitter.emit("klog", val, message);
  });
  krl.stdlib.emitter.on("debug", function(scope, message){
    emitter.emit("debug", "stdlib", scope, message);
  });

  var installRID = function(rid, callback){
    if(conf._dont_check_enabled_before_installing){//for testing
      compileAndLoadRuleset({rid: rid}, function(err, rs){
        if(err) return callback(err);
        installRuleset(rs, callback);
      });
      return;
    }
    db.getEnableRuleset(rid, function(err, data){
      if(err) return callback(err);
      compileAndLoadRuleset({
        rid: rid,
        src: data.src,
        hash: data.hash
      }, function(err, rs){
        if(err){
          db.disableRuleset(rid, function(){
            callback(err);
          });
          return;
        }
        installRuleset(rs, callback);
      });
    });
  };

  //TODO standard startup-phase
  db.getAllEnableRulesets(function(err, rids){
    if(err){
      throw err;//TODO handle this somehow?
    }
    _.each(rids, function(rid){
      installRID(rid, function(err){
        if(err){
          throw err;//TODO handle this somehow?
        }
      });
    });
  });

  var signalEvent = function(event, callback){
    event.timestamp = new Date();
    event.getAttr = function(attr_key){
      return event.attrs[attr_key];
    };
    event.getAttrMatches = function(pairs){
      var matches = [];
      var i, attr, m, pair;
      for(i = 0; i < pairs.length; i++){
        pair = pairs[i];
        attr = event.attrs[pair[0]];
        m = pair[1].exec(attr || "");
        if(!m){
          return undefined;
        }
        matches.push(m[1]);
      }
      return matches;
    };
    var debug_info = {
      event: {
        eci: event.eci,
        eid: event.eid,
        domain: event.domain,
        type: event.type,
        attrs: _.cloneDeep(event.attrs),
        timestamp: event.timestamp.toISOString()
      }
    };
    emitter.emit("debug", "event", debug_info, "event recieved");
    db.getPicoByECI(event.eci, function(err, pico){
      if(err) return callback(err);
      if(!pico){
        return callback(new Error("Invalid eci: " + event.eci));
      }
      debug_info.pico_id = pico.id;
      emitter.emit("debug", "event", debug_info, "pico selected");

      var ctx_orig = mkCTX({
        pico: pico,
        db: db,
        engine: engine,
        modules: modules,
        event: event
      });

      selectRulesToEval(ctx_orig, salience_graph, rulesets, function(err, to_eval){
        if(err) return callback(err);

        λ.map(_.groupBy(to_eval, "rid"), function(rules_by_rid, callback){
          λ.map.series(rules_by_rid, function(rule, callback){

            var rule_debug_info = _.assign({}, debug_info, {
              rid: rule.rid,
              rule_name: rule.name
            });

            var ctx = _.assign({}, ctx_orig, {
              rid: rule.rid,
              rule: rule,
              scope: rule.scope,
              emitDebug: function(msg){
                emitter.emit("debug", "event", rule_debug_info, msg);
              }
            });

            ctx.emitDebug("rule selected");

            evalRule(rule, ctx, callback);
          }, callback);
        }, function(err, responses){
          if(err) return callback(err);

          var res_by_type = _.groupBy(_.flattenDeep(_.values(responses)), "type");

          //TODO other types
          callback(undefined, {
            directives:  _.map(res_by_type.directive, function(d){
              return _.omit(d, "type");
            })
          });
        });
      });
    });
  };

  var engine = Future.wrap({
    installRID: installRID,
    signalEvent: signalEvent
  });

  return {
    db: db,
    emitter: emitter,
    isInstalled: function(rid){
      return _.has(rulesets, rid);
    },
    installRID: installRID,
    signalEvent: signalEvent,
    runQuery: function(query, callback){
      db.getPicoByECI(query.eci, function(err, pico){
        if(err) return callback(err);
        if(!pico){
          return callback(new Error("Bad eci"));
        }
        if(!_.has(pico.ruleset, query.rid)){
          return callback(new Error("Pico does not have that rid"));
        }
        if(!_.has(rulesets, query.rid)){
          return callback(new Error("Not found: rid"));
        }
        var rs = rulesets[query.rid];
        var shares = _.get(rs, ["meta", "shares"]);
        if(!_.isArray(shares) || !_.includes(shares, query.name)){
          return callback(new Error("Not shared"));
        }
        if(!rs.scope.has(query.name)){
          //TODO throw -or- nil????
          return callback(new Error("Shared, but not defined: " + query.name));
        }

        ////////////////////////////////////////////////////////////////////////
        var ctx = mkCTX({
          db: db,
          rid: rs.rid,
          pico: pico,
          engine: engine,
          modules: modules,
          scope: rs.scope
        });

        var val = ctx.scope.get(query.name);
        if(_.isFunction(val)){
          applyInFiber(val, null, [ctx, query.args], function(err, resp){
            if(err) return callback(err);
            callback(undefined, resp);
          });
        }else{
          callback(undefined, val);
        }
      });
    }
  };
};
<commit_msg>starting to keep track of separte scope for dependant modules<commit_after>var _ = require("lodash");
var λ = require("contra");
var DB = require("./DB");
var krl = {
  stdlib: require("krl-stdlib"),
  Closure: require("./KRLClosure")
};
var getArg = require("./getArg");
var Future = require("fibers/future");
var modules = require("./modules");
var evalRule = require("./evalRule");
var SymbolTable = require("symbol-table");
var applyInFiber = require("./applyInFiber");
var EventEmitter = require("events");
var selectRulesToEval = require("./selectRulesToEval");

var mkCTX = function(ctx){
  ctx.getArg = getArg;
  ctx.krl = krl;
  return ctx;
};

var rulesets = {};
var salience_graph = {};

var doInstallRuleset = function(rs){
  rs.scope = SymbolTable();
  if(_.isFunction(rs.global)){
    rs.global(mkCTX({
      scope: rs.scope
    }));
  }
  rs.modules_used = {};
  _.each(rs.meta && rs.meta.use, function(use){
    if(use.kind !== "module"){
      throw new Error("Unsupported 'use' kind: " + use.kind);
    }
    if(!_.has(rulesets, use.rid)){
      throw new Error("Dependant module not loaded: " + use.rid);
    }
    var dep_rs = rulesets[use.rid];
    var ctx = mkCTX({
      scope: SymbolTable()//or dep_rs.scope.push() ??? TODO
    });
    if(_.isFunction(dep_rs.meta && dep_rs.meta.configure)){
      dep_rs.meta.configure(ctx);
    }
    if(_.isFunction(use["with"])){
      use["with"](ctx);
    }
    if(_.isFunction(dep_rs.global)){
      dep_rs.global(ctx);
    }
    rs.modules_used[use.alias] = {
      rid: use.rid,
      scope: ctx.scope
    };
  });
  _.each(rs.rules, function(rule){
    rule.rid = rs.rid;

    _.each(rule.select && rule.select.graph, function(g, domain){
      _.each(g, function(exprs, type){
        _.set(salience_graph, [domain, type, rule.rid, rule.name], true);
      });
    });
  });
  rulesets[rs.rid] = rs;
};

var installRuleset = function(rs, callback){
  applyInFiber(doInstallRuleset, null, [rs], callback);
};

module.exports = function(conf){
  var db = Future.wrap(DB(conf.db));
  var compileAndLoadRuleset = conf.compileAndLoadRuleset;

  var emitter = new EventEmitter();
  krl.stdlib.emitter.on("klog", function(val, message){
    emitter.emit("klog", val, message);
  });
  krl.stdlib.emitter.on("debug", function(scope, message){
    emitter.emit("debug", "stdlib", scope, message);
  });

  var installRID = function(rid, callback){
    if(conf._dont_check_enabled_before_installing){//for testing
      compileAndLoadRuleset({rid: rid}, function(err, rs){
        if(err) return callback(err);
        installRuleset(rs, callback);
      });
      return;
    }
    db.getEnableRuleset(rid, function(err, data){
      if(err) return callback(err);
      compileAndLoadRuleset({
        rid: rid,
        src: data.src,
        hash: data.hash
      }, function(err, rs){
        if(err){
          db.disableRuleset(rid, function(){
            callback(err);
          });
          return;
        }
        installRuleset(rs, callback);
      });
    });
  };

  //TODO standard startup-phase
  db.getAllEnableRulesets(function(err, rids){
    if(err){
      throw err;//TODO handle this somehow?
    }
    _.each(rids, function(rid){
      installRID(rid, function(err){
        if(err){
          throw err;//TODO handle this somehow?
        }
      });
    });
  });

  var signalEvent = function(event, callback){
    event.timestamp = new Date();
    event.getAttr = function(attr_key){
      return event.attrs[attr_key];
    };
    event.getAttrMatches = function(pairs){
      var matches = [];
      var i, attr, m, pair;
      for(i = 0; i < pairs.length; i++){
        pair = pairs[i];
        attr = event.attrs[pair[0]];
        m = pair[1].exec(attr || "");
        if(!m){
          return undefined;
        }
        matches.push(m[1]);
      }
      return matches;
    };
    var debug_info = {
      event: {
        eci: event.eci,
        eid: event.eid,
        domain: event.domain,
        type: event.type,
        attrs: _.cloneDeep(event.attrs),
        timestamp: event.timestamp.toISOString()
      }
    };
    emitter.emit("debug", "event", debug_info, "event recieved");
    db.getPicoByECI(event.eci, function(err, pico){
      if(err) return callback(err);
      if(!pico){
        return callback(new Error("Invalid eci: " + event.eci));
      }
      debug_info.pico_id = pico.id;
      emitter.emit("debug", "event", debug_info, "pico selected");

      var ctx_orig = mkCTX({
        pico: pico,
        db: db,
        engine: engine,
        modules: modules,
        event: event
      });

      selectRulesToEval(ctx_orig, salience_graph, rulesets, function(err, to_eval){
        if(err) return callback(err);

        λ.map(_.groupBy(to_eval, "rid"), function(rules_by_rid, callback){
          λ.map.series(rules_by_rid, function(rule, callback){

            var rule_debug_info = _.assign({}, debug_info, {
              rid: rule.rid,
              rule_name: rule.name
            });

            var ctx = _.assign({}, ctx_orig, {
              rid: rule.rid,
              rule: rule,
              scope: rule.scope,
              emitDebug: function(msg){
                emitter.emit("debug", "event", rule_debug_info, msg);
              }
            });

            ctx.emitDebug("rule selected");

            evalRule(rule, ctx, callback);
          }, callback);
        }, function(err, responses){
          if(err) return callback(err);

          var res_by_type = _.groupBy(_.flattenDeep(_.values(responses)), "type");

          //TODO other types
          callback(undefined, {
            directives:  _.map(res_by_type.directive, function(d){
              return _.omit(d, "type");
            })
          });
        });
      });
    });
  };

  var engine = Future.wrap({
    installRID: installRID,
    signalEvent: signalEvent
  });

  return {
    db: db,
    emitter: emitter,
    isInstalled: function(rid){
      return _.has(rulesets, rid);
    },
    installRID: installRID,
    signalEvent: signalEvent,
    runQuery: function(query, callback){
      db.getPicoByECI(query.eci, function(err, pico){
        if(err) return callback(err);
        if(!pico){
          return callback(new Error("Bad eci"));
        }
        if(!_.has(pico.ruleset, query.rid)){
          return callback(new Error("Pico does not have that rid"));
        }
        if(!_.has(rulesets, query.rid)){
          return callback(new Error("Not found: rid"));
        }
        var rs = rulesets[query.rid];
        var shares = _.get(rs, ["meta", "shares"]);
        if(!_.isArray(shares) || !_.includes(shares, query.name)){
          return callback(new Error("Not shared"));
        }
        if(!rs.scope.has(query.name)){
          //TODO throw -or- nil????
          return callback(new Error("Shared, but not defined: " + query.name));
        }

        ////////////////////////////////////////////////////////////////////////
        var ctx = mkCTX({
          db: db,
          rid: rs.rid,
          pico: pico,
          engine: engine,
          modules: modules,
          scope: rs.scope
        });

        var val = ctx.scope.get(query.name);
        if(_.isFunction(val)){
          applyInFiber(val, null, [ctx, query.args], function(err, resp){
            if(err) return callback(err);
            callback(undefined, resp);
          });
        }else{
          callback(undefined, val);
        }
      });
    }
  };
};
<|endoftext|>


<commit_before>console.log(require('./enums/Default.js').Author);

module.exports = {
  Argument: require('./structures/Argument.js'),
  ArgumentPrecondition: require('./structures/ArgumentPrecondition.js'),
  Command: require('./structures/Command.js'),
  CommandError: require('./enums/CommandError.js'),
  Context: require('./structures/Context.js'),
  ExceptionResult: require('./results/ExceptionResult.js'),
  Group: require('./structures/Group.js'),
  Handler: require('./structures/Handler.js'),
  Precondition: require('./structures/Precondition.js'),
  PreconditionResult: require('./results/PreconditionResult.js'),
  Registry: require('./structures/Registry.js'),
  Result: require('./results/Result.js'),
  TypeReader: require('./structures/TypeReader.js'),
  TypeReaderResult: require('./results/TypeReaderResult.js')
};
<commit_msg>default enum export<commit_after>console.log(require('./enums/Default.js').Author);

module.exports = {
  Argument: require('./structures/Argument.js'),
  ArgumentPrecondition: require('./structures/ArgumentPrecondition.js'),
  Command: require('./structures/Command.js'),
  CommandError: require('./enums/CommandError.js'),
  Context: require('./structures/Context.js'),
  Default: require('./enums/Default.js'),
  ExceptionResult: require('./results/ExceptionResult.js'),
  Group: require('./structures/Group.js'),
  Handler: require('./structures/Handler.js'),
  Precondition: require('./structures/Precondition.js'),
  PreconditionResult: require('./results/PreconditionResult.js'),
  Registry: require('./structures/Registry.js'),
  Result: require('./results/Result.js'),
  TypeReader: require('./structures/TypeReader.js'),
  TypeReaderResult: require('./results/TypeReaderResult.js')
};
<|endoftext|>


<commit_before>module.exports = function isEqual(a, b) {
    return !(a !== b && !(a !== a && b !== b));
};
<commit_msg>updates<commit_after>module.exports = isEqual;

function isEqual(a, b) {
    return !(a !== b && !(a !== a && b !== b));
}
<|endoftext|>


<commit_before>'use strict';

module.exports = function () {
    // returns true
    // comment
    return true;
};

aoeurad083d4dcl43h=ta[dgfdia[]]]]]]
<commit_msg>remove error<commit_after>'use strict';

module.exports = function () {
    // returns true
    // comment
    return true;
};
<|endoftext|>