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

  describe('SpeechKITT', function() {

    it('should exist in global namespace', function () {
      expect(SpeechKITT).toEqual(jasmine.any(Object));
    });

    it('should contain setStartCommand method', function () {
      expect(SpeechKITT.setStartCommand).toEqual(jasmine.any(Function));
    });

    it('should contain setAbortCommand method', function () {
      expect(SpeechKITT.setAbortCommand).toEqual(jasmine.any(Function));
    });

    it('should contain startRecognition method', function () {
      expect(SpeechKITT.startRecognition).toEqual(jasmine.any(Function));
    });

    it('should contain abortRecognition method', function () {
      expect(SpeechKITT.abortRecognition).toEqual(jasmine.any(Function));
    });

    it('should contain toggleRecognition method', function () {
      expect(SpeechKITT.toggleRecognition).toEqual(jasmine.any(Function));
    });

    it('should contain onStart method', function () {
      expect(SpeechKITT.onStart).toEqual(jasmine.any(Function));
    });

    it('should contain onEnd method', function () {
      expect(SpeechKITT.onEnd).toEqual(jasmine.any(Function));
    });

    it('should contain render method', function () {
      expect(SpeechKITT.render).toEqual(jasmine.any(Function));
    });

    it('should contain vroom method', function () {
      expect(SpeechKITT.vroom).toEqual(jasmine.any(Function));
    });

    it('should contain hide method', function () {
      expect(SpeechKITT.hide).toEqual(jasmine.any(Function));
    });

    it('should contain show method', function () {
      expect(SpeechKITT.show).toEqual(jasmine.any(Function));
    });

    it('should contain isListening method', function () {
      expect(SpeechKITT.isListening).toEqual(jasmine.any(Function));
    });

    it('should contain setStylesheet method', function () {
      expect(SpeechKITT.setStylesheet).toEqual(jasmine.any(Function));
    });

    it('should contain setToggleLabelText method', function () {
      expect(SpeechKITT.setToggleLabelText).toEqual(jasmine.any(Function));
    });

    it('should contain getInstructionsText method', function () {
      expect(SpeechKITT.setInstructionsText).toEqual(jasmine.any(Function));
    });

    it('should contain setSampleCommands method', function () {
      expect(SpeechKITT.setSampleCommands).toEqual(jasmine.any(Function));
    });

    it('should contain annyang method', function () {
      expect(SpeechKITT.annyang).toEqual(jasmine.any(Function));
    });

    it('should contain rememberStatus method', function () {
      expect(SpeechKITT.rememberStatus).toEqual(jasmine.any(Function));
    });

    it('should contain setRecognizedSentence method', function () {
      expect(SpeechKITT.setRecognizedSentence).toEqual(jasmine.any(Function));
      // @TODO: annyang should call this automatically.
    });

    it('should contain getLastRecognizedSentence method', function () {
      expect(SpeechKITT.getLastRecognizedSentence).toEqual(jasmine.any(Function));
    });

  });

  describe('SpeechKITT.setStartCommand', function() {

    it('should throw an error when called without a callback function', function () {
      expect(function() {
        SpeechKITT.setStartCommand();
      }).toThrowError();
    });

    it('should throw an error when called with an invalid callback function', function () {
      expect(function() {
        SpeechKITT.setStartCommand('blerg');
      }).toThrowError();
    });

    it('should throw an error when called with an undefined callback function', function () {
      expect(function() {
        SpeechKITT.setStartCommand(undefined);
      }).toThrowError();
    });

    //@TODO: define a test for different contexts

  });

  describe('SpeechKITT.setAbortCommand', function() {

    it('should throw an error when called without a callback function', function () {
      expect(function() {
        SpeechKITT.setAbortCommand();
      }).toThrowError();
    });

    it('should throw an error when called with an invalid callback function', function () {
      expect(function() {
        SpeechKITT.setAbortCommand('blerg');
      }).toThrowError();
    });

    it('should throw an error when called with an undefined callback function', function () {
      expect(function() {
        SpeechKITT.setAbortCommand(undefined);
      }).toThrowError();
    });

  });

  describe('SpeechKITT.startRecognition', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should throw an error when called before setting a start command', function () {
      expect(function() {
        SpeechKITT.startRecognition();
      }).toThrowError();
    });

    it('should start SpeechRecognition', function () {
      SpeechKITT.setStartCommand(recognition.start);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      expect(recognition.isStarted()).toBe(true);
    });

    it('should throw an exception if called on an already running SpeechRecognition object', function () {
      SpeechKITT.setStartCommand(recognition.start);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      expect(recognition.isStarted()).toBe(true);
      expect(function() {
        SpeechKITT.startRecognition();
      }).toThrowError();
    });

  });

  describe('SpeechKITT.abortRecognition', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should throw an error when called before setting an abort command', function () {
      expect(function() {
        SpeechKITT.abortRecognition();
      }).toThrowError();
    });

    it('should abort SpeechRecognition', function () {
      SpeechKITT.setStartCommand(recognition.start);
      SpeechKITT.setAbortCommand(recognition.abort);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      expect(recognition.isStarted()).toBe(true);
      SpeechKITT.abortRecognition();
      expect(SpeechKITT.isListening()).toBe(false);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.abortRecognition();
      expect(SpeechKITT.isListening()).toBe(false);
      expect(recognition.isStarted()).toBe(false);
    });

  });

  describe('SpeechKITT.toggleRecognition', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should alternate between aborting and starting SpeechRecognition', function () {
      SpeechKITT.setStartCommand(recognition.start);
      SpeechKITT.setAbortCommand(recognition.abort);
      SpeechKITT.startRecognition();
      expect(recognition.isStarted()).toBe(true);
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.toggleRecognition();
      expect(recognition.isStarted()).toBe(false);
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.toggleRecognition();
      expect(recognition.isStarted()).toBe(true);
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.toggleRecognition();
    });

  });

  describe('SpeechKITT.setStylesheet', function() {

    it('should be callable and return undefined', function () {
      expect(SpeechKITT.setStylesheet()).toBe(undefined);
    });

  });

  describe('SpeechKITT.isListening', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should return false initially', function () {
      expect(SpeechKITT.isListening()).toBe(false);
    });

    it('should return true after starting SpeechKITT', function () {
      SpeechKITT.setStartCommand(recognition.start);
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
    });

  });

  describe('SpeechKITT.annyang', function() {

    beforeEach(function() {
      jasmine.clock().install();
    });

    afterEach(function() {
      annyang.abort();
      jasmine.clock().tick(101);
      jasmine.clock().uninstall();
    });

    it('should set start command to annyang.start', function () {
      expect(annyang.isListening()).toBe(false);
      SpeechKITT.annyang();
      SpeechKITT.startRecognition();
      expect(annyang.isListening()).toBe(true);
    });

    it('should set abort command to annyang.abort', function () {
      expect(annyang.isListening()).toBe(false);
      SpeechKITT.annyang();
      SpeechKITT.startRecognition();
      expect(annyang.isListening()).toBe(true);
      SpeechKITT.abortRecognition();
      expect(annyang.isListening()).toBe(false);
    });

    it('should add a callback to SpeechKITT.onStart to annyang\'s start event', function () {
      SpeechKITT.annyang();
      expect(SpeechKITT.isListening()).toBe(false);
      annyang.start();
      expect(SpeechKITT.isListening()).toBe(true);
    });

    it('should add a callback to SpeechKITT.onEnd to annyang\'s end event', function () {
      SpeechKITT.annyang();
      annyang.start();
      expect(SpeechKITT.isListening()).toBe(true);
      annyang.abort();
      jasmine.clock().tick(101);
      expect(SpeechKITT.isListening()).toBe(false);
    });

  });

  describe('SpeechKITT.onStart', function() {

    it('should set Speech KITT to listening mode if it was not already listening', function () {
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.onStart();
      expect(SpeechKITT.isListening()).toBe(true);
    });

    it('should leave Speech KITT in listening mode if it was already listening', function () {
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onStart();
      expect(SpeechKITT.isListening()).toBe(true);
    });

  });

  describe('SpeechKITT.onEnd', function() {

    beforeEach(function() {
      jasmine.clock().install();
    });

    afterEach(function() {
      jasmine.clock().uninstall();
    });

    it('should set Speech KITT to not listening mode if it was listening only after 100ms have passed without it being restarted', function () {
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onEnd();
      expect(SpeechKITT.isListening()).toBe(true);
      jasmine.clock().tick(101);
      expect(SpeechKITT.isListening()).toBe(false);
    });

    it('should leave Speech KITT in listening mode if it was called, but then onStart was called within 100ms', function () {
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onEnd();
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onStart();
      jasmine.clock().tick(101);
      expect(SpeechKITT.isListening()).toBe(true);
    });

    it('should leave Speech KITT in not listening mode if it was not listening', function () {
      SpeechKITT.abortRecognition();
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.onEnd();
      expect(SpeechKITT.isListening()).toBe(false);
    });

  });

  describe('SpeechKITT.getLastRecognizedSentence', function() {

    it('should return undefined if called before anything said', function () {
      expect(SpeechKITT.getLastRecognizedSentence()).toBe(undefined);
    });

    it('should return the last said sentence if one was set by setRecognizedSentence', function () {
      var sentence1 = 'Next time you want to stab me in the back, have the guts to do it to my face';
      var sentence2 = "Man walks down the street in a hat like that, you know he's not afraid of anything";
      SpeechKITT.setRecognizedSentence(sentence1);
      SpeechKITT.setRecognizedSentence(sentence2);
      expect(SpeechKITT.getLastRecognizedSentence()).toEqual(sentence2);
    });

  });

  describe('SpeechKITT.setRecognizedSentence', function() {

    it('should always return undefined', function () {
      expect(SpeechKITT.setRecognizedSentence()).toBe(undefined);
      expect(SpeechKITT.setRecognizedSentence('Next time you want to stab me in the back, have the guts to do it to my face')).toBe(undefined);
    });

    it('should add the sentence said to Speech KITT', function () {
      var sentence = 'Next time you want to stab me in the back, have the guts to do it to my face';
      SpeechKITT.setRecognizedSentence(sentence);
      expect(SpeechKITT.getLastRecognizedSentence()).toEqual(sentence);
    });

  });

})();
<commit_msg>Created test group for initial state and moved test for SpeechKITT.getLastRecognizedSentence into it<commit_after>(function() {
  "use strict";

  describe('SpeechKITT', function() {

    it('should exist in global namespace', function () {
      expect(SpeechKITT).toEqual(jasmine.any(Object));
    });

    it('should contain setStartCommand method', function () {
      expect(SpeechKITT.setStartCommand).toEqual(jasmine.any(Function));
    });

    it('should contain setAbortCommand method', function () {
      expect(SpeechKITT.setAbortCommand).toEqual(jasmine.any(Function));
    });

    it('should contain startRecognition method', function () {
      expect(SpeechKITT.startRecognition).toEqual(jasmine.any(Function));
    });

    it('should contain abortRecognition method', function () {
      expect(SpeechKITT.abortRecognition).toEqual(jasmine.any(Function));
    });

    it('should contain toggleRecognition method', function () {
      expect(SpeechKITT.toggleRecognition).toEqual(jasmine.any(Function));
    });

    it('should contain onStart method', function () {
      expect(SpeechKITT.onStart).toEqual(jasmine.any(Function));
    });

    it('should contain onEnd method', function () {
      expect(SpeechKITT.onEnd).toEqual(jasmine.any(Function));
    });

    it('should contain render method', function () {
      expect(SpeechKITT.render).toEqual(jasmine.any(Function));
    });

    it('should contain vroom method', function () {
      expect(SpeechKITT.vroom).toEqual(jasmine.any(Function));
    });

    it('should contain hide method', function () {
      expect(SpeechKITT.hide).toEqual(jasmine.any(Function));
    });

    it('should contain show method', function () {
      expect(SpeechKITT.show).toEqual(jasmine.any(Function));
    });

    it('should contain isListening method', function () {
      expect(SpeechKITT.isListening).toEqual(jasmine.any(Function));
    });

    it('should contain setStylesheet method', function () {
      expect(SpeechKITT.setStylesheet).toEqual(jasmine.any(Function));
    });

    it('should contain setToggleLabelText method', function () {
      expect(SpeechKITT.setToggleLabelText).toEqual(jasmine.any(Function));
    });

    it('should contain getInstructionsText method', function () {
      expect(SpeechKITT.setInstructionsText).toEqual(jasmine.any(Function));
    });

    it('should contain setSampleCommands method', function () {
      expect(SpeechKITT.setSampleCommands).toEqual(jasmine.any(Function));
    });

    it('should contain annyang method', function () {
      expect(SpeechKITT.annyang).toEqual(jasmine.any(Function));
    });

    it('should contain rememberStatus method', function () {
      expect(SpeechKITT.rememberStatus).toEqual(jasmine.any(Function));
    });

    it('should contain setRecognizedSentence method', function () {
      expect(SpeechKITT.setRecognizedSentence).toEqual(jasmine.any(Function));
      // @TODO: annyang should call this automatically.
    });

    it('should contain getLastRecognizedSentence method', function () {
      expect(SpeechKITT.getLastRecognizedSentence).toEqual(jasmine.any(Function));
    });

  });

  describe('Initial state', function() {

    describe('SpeechKITT.getLastRecognizedSentence', function() {

      it('should return undefined if called before anything said', function () {
        expect(SpeechKITT.getLastRecognizedSentence()).toBe(undefined);
      });

    });

  });

  describe('SpeechKITT.setStartCommand', function() {

    it('should throw an error when called without a callback function', function () {
      expect(function() {
        SpeechKITT.setStartCommand();
      }).toThrowError();
    });

    it('should throw an error when called with an invalid callback function', function () {
      expect(function() {
        SpeechKITT.setStartCommand('blerg');
      }).toThrowError();
    });

    it('should throw an error when called with an undefined callback function', function () {
      expect(function() {
        SpeechKITT.setStartCommand(undefined);
      }).toThrowError();
    });

    //@TODO: define a test for different contexts

  });

  describe('SpeechKITT.setAbortCommand', function() {

    it('should throw an error when called without a callback function', function () {
      expect(function() {
        SpeechKITT.setAbortCommand();
      }).toThrowError();
    });

    it('should throw an error when called with an invalid callback function', function () {
      expect(function() {
        SpeechKITT.setAbortCommand('blerg');
      }).toThrowError();
    });

    it('should throw an error when called with an undefined callback function', function () {
      expect(function() {
        SpeechKITT.setAbortCommand(undefined);
      }).toThrowError();
    });

  });

  describe('SpeechKITT.startRecognition', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should throw an error when called before setting a start command', function () {
      expect(function() {
        SpeechKITT.startRecognition();
      }).toThrowError();
    });

    it('should start SpeechRecognition', function () {
      SpeechKITT.setStartCommand(recognition.start);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      expect(recognition.isStarted()).toBe(true);
    });

    it('should throw an exception if called on an already running SpeechRecognition object', function () {
      SpeechKITT.setStartCommand(recognition.start);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      expect(recognition.isStarted()).toBe(true);
      expect(function() {
        SpeechKITT.startRecognition();
      }).toThrowError();
    });

  });

  describe('SpeechKITT.abortRecognition', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should throw an error when called before setting an abort command', function () {
      expect(function() {
        SpeechKITT.abortRecognition();
      }).toThrowError();
    });

    it('should abort SpeechRecognition', function () {
      SpeechKITT.setStartCommand(recognition.start);
      SpeechKITT.setAbortCommand(recognition.abort);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      expect(recognition.isStarted()).toBe(true);
      SpeechKITT.abortRecognition();
      expect(SpeechKITT.isListening()).toBe(false);
      expect(recognition.isStarted()).toBe(false);
      SpeechKITT.abortRecognition();
      expect(SpeechKITT.isListening()).toBe(false);
      expect(recognition.isStarted()).toBe(false);
    });

  });

  describe('SpeechKITT.toggleRecognition', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should alternate between aborting and starting SpeechRecognition', function () {
      SpeechKITT.setStartCommand(recognition.start);
      SpeechKITT.setAbortCommand(recognition.abort);
      SpeechKITT.startRecognition();
      expect(recognition.isStarted()).toBe(true);
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.toggleRecognition();
      expect(recognition.isStarted()).toBe(false);
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.toggleRecognition();
      expect(recognition.isStarted()).toBe(true);
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.toggleRecognition();
    });

  });

  describe('SpeechKITT.setStylesheet', function() {

    it('should be callable and return undefined', function () {
      expect(SpeechKITT.setStylesheet()).toBe(undefined);
    });

  });

  describe('SpeechKITT.isListening', function() {

    var recognition;

    beforeEach(function() {
      Corti.patch();
      recognition = new SpeechRecognition();
    });

    afterEach(function() {
      Corti.unpatch();
    });

    it('should return false initially', function () {
      expect(SpeechKITT.isListening()).toBe(false);
    });

    it('should return true after starting SpeechKITT', function () {
      SpeechKITT.setStartCommand(recognition.start);
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
    });

  });

  describe('SpeechKITT.annyang', function() {

    beforeEach(function() {
      jasmine.clock().install();
    });

    afterEach(function() {
      annyang.abort();
      jasmine.clock().tick(101);
      jasmine.clock().uninstall();
    });

    it('should set start command to annyang.start', function () {
      expect(annyang.isListening()).toBe(false);
      SpeechKITT.annyang();
      SpeechKITT.startRecognition();
      expect(annyang.isListening()).toBe(true);
    });

    it('should set abort command to annyang.abort', function () {
      expect(annyang.isListening()).toBe(false);
      SpeechKITT.annyang();
      SpeechKITT.startRecognition();
      expect(annyang.isListening()).toBe(true);
      SpeechKITT.abortRecognition();
      expect(annyang.isListening()).toBe(false);
    });

    it('should add a callback to SpeechKITT.onStart to annyang\'s start event', function () {
      SpeechKITT.annyang();
      expect(SpeechKITT.isListening()).toBe(false);
      annyang.start();
      expect(SpeechKITT.isListening()).toBe(true);
    });

    it('should add a callback to SpeechKITT.onEnd to annyang\'s end event', function () {
      SpeechKITT.annyang();
      annyang.start();
      expect(SpeechKITT.isListening()).toBe(true);
      annyang.abort();
      jasmine.clock().tick(101);
      expect(SpeechKITT.isListening()).toBe(false);
    });

  });

  describe('SpeechKITT.onStart', function() {

    it('should set Speech KITT to listening mode if it was not already listening', function () {
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.onStart();
      expect(SpeechKITT.isListening()).toBe(true);
    });

    it('should leave Speech KITT in listening mode if it was already listening', function () {
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onStart();
      expect(SpeechKITT.isListening()).toBe(true);
    });

  });

  describe('SpeechKITT.onEnd', function() {

    beforeEach(function() {
      jasmine.clock().install();
    });

    afterEach(function() {
      jasmine.clock().uninstall();
    });

    it('should set Speech KITT to not listening mode if it was listening only after 100ms have passed without it being restarted', function () {
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onEnd();
      expect(SpeechKITT.isListening()).toBe(true);
      jasmine.clock().tick(101);
      expect(SpeechKITT.isListening()).toBe(false);
    });

    it('should leave Speech KITT in listening mode if it was called, but then onStart was called within 100ms', function () {
      SpeechKITT.startRecognition();
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onEnd();
      expect(SpeechKITT.isListening()).toBe(true);
      SpeechKITT.onStart();
      jasmine.clock().tick(101);
      expect(SpeechKITT.isListening()).toBe(true);
    });

    it('should leave Speech KITT in not listening mode if it was not listening', function () {
      SpeechKITT.abortRecognition();
      expect(SpeechKITT.isListening()).toBe(false);
      SpeechKITT.onEnd();
      expect(SpeechKITT.isListening()).toBe(false);
    });

  });

  describe('SpeechKITT.getLastRecognizedSentence', function() {

    it('should return the last said sentence if one was set by setRecognizedSentence', function () {
      var sentence1 = 'Next time you want to stab me in the back, have the guts to do it to my face';
      var sentence2 = "Man walks down the street in a hat like that, you know he's not afraid of anything";
      SpeechKITT.setRecognizedSentence(sentence1);
      SpeechKITT.setRecognizedSentence(sentence2);
      expect(SpeechKITT.getLastRecognizedSentence()).toEqual(sentence2);
    });

  });

  describe('SpeechKITT.setRecognizedSentence', function() {

    it('should always return undefined', function () {
      expect(SpeechKITT.setRecognizedSentence()).toBe(undefined);
      expect(SpeechKITT.setRecognizedSentence('Next time you want to stab me in the back, have the guts to do it to my face')).toBe(undefined);
    });

    it('should add the sentence said to Speech KITT', function () {
      var sentence = 'Next time you want to stab me in the back, have the guts to do it to my face';
      SpeechKITT.setRecognizedSentence(sentence);
      expect(SpeechKITT.getLastRecognizedSentence()).toEqual(sentence);
    });

  });

})();
<|endoftext|>


<commit_before>var Metalsmith = require('metalsmith'),
  markdown = require('metalsmith-markdown'),
  templates = require('metalsmith-templates'),
  collections = require('metalsmith-collections'),
  setMetadata = require('metalsmith-filemetadata'),
  filepath = require('metalsmith-filepath'),
  assets = require('metalsmith-assets'),
  pandoc = require('metalsmith-pandoc');

module.exports = function build(){
  Metalsmith(__dirname)
  .use(assets({
      source:'./assets',
      destination:'./assets'
  }))
  // set template for exercises
  .use(setMetadata([
    { pattern: 'python/**/*.md',  metadata: { template: 'python.jade' }},
    { pattern: 'scratch/**/*.md', metadata: { template: 'scratch.jade' }}
  ]))
  // create collections for index scaffolding
  .use(collections({
    python: 'python/**/*.md',
    scratch: 'scratch/**/*.md'
  }))
  // convert to html
//  .use(markdown())
  .use(pandoc())
  // add file.link metadata
  .use(filepath())
  // apply templates
  .use(templates('jade'))
  //build
  .destination('./build')
  .build(function(err){
    if (err) console.log(err);
  });
}
<commit_msg>section divs, smart quotes, html5<commit_after>var Metalsmith = require('metalsmith'),
  markdown = require('metalsmith-markdown'),
  templates = require('metalsmith-templates'),
  collections = require('metalsmith-collections'),
  setMetadata = require('metalsmith-filemetadata'),
  filepath = require('metalsmith-filepath'),
  assets = require('metalsmith-assets'),
  pandoc = require('metalsmith-pandoc');

module.exports = function build(){
  Metalsmith(__dirname)
  .use(assets({
      source:'./assets',
      destination:'./assets'
  }))
  // set template for exercises
  .use(setMetadata([
    { pattern: 'python/**/*.md',  metadata: { template: 'python.jade' }},
    { pattern: 'scratch/**/*.md', metadata: { template: 'scratch.jade' }}
  ]))
  // create collections for index scaffolding
  .use(collections({
    python: 'python/**/*.md',
    scratch: 'scratch/**/*.md'
  }))
  // convert to html
//  .use(markdown())
  .use(pandoc({
    to: 'html5',
    args: ['--section-divs', '--smart']
  }))
  // add file.link metadata
  .use(filepath())
  // apply templates
  .use(templates('jade'))
  //build
  .destination('./build')
  .build(function(err){
    if (err) console.log(err);
  });
}
<|endoftext|>


<commit_before>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

/**
 * Method using a factory pattern variant to get a reducer
 * for a particular page or page style.
 *
 * For a new page - create a constant object with the
 * methods from reducerMethods which are composed to create
 * a reducer. Add to PAGE_REDUCERS.
 *
 * Each key value pair in a reducer object should be in the form
 * action type: reducer function, returning a new state object
 *
 */

import {
  filterData,
  focusNextCell,
  selectRow,
  deselectRow,
  deselectAll,
  focusCell,
  sortData,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
} from './reducerMethods';

/**
 * Used for actions that should be in all pages using a data table.
 */
const BASE_TABLE_PAGE_REDUCER = {
  focusNextCell,
  focusCell,
  sortData,
};

const customerInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  editField,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
};

const customerInvoices = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  deleteRecordsById,
};

const supplierInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  closeBasicModal,
  openBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addItem,
  editField,
  deleteRecordsById,
};

const supplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
  deleteRecordsById,
};

const programSupplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
};

const supplierRequisitions = {
  sortData,
  filterData,
  selectRow,
  deselectRow,
  openBasicModal,
  closeBasicModal,
  refreshData,
};

const programSupplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  useSuggestedQuantities,
  hideOverStocked,
  showOverStocked,
};

const PAGE_REDUCERS = {
  customerInvoice,
  customerInvoices,
  supplierInvoice,
  supplierRequisitions,
  supplierRequisition,
  programSupplierRequisition,
};

const getReducer = page => {
  const reducer = PAGE_REDUCERS[page];
  return (state, action) => {
    const { type } = action;
    if (!reducer[type]) return state;
    return reducer[type](state, action);
  };
};

export default getReducer;
<commit_msg>Add corrected sorting behaviour for supplierRequisitionPage<commit_after>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

/**
 * Method using a factory pattern variant to get a reducer
 * for a particular page or page style.
 *
 * For a new page - create a constant object with the
 * methods from reducerMethods which are composed to create
 * a reducer. Add to PAGE_REDUCERS.
 *
 * Each key value pair in a reducer object should be in the form
 * action type: reducer function, returning a new state object
 *
 */

import {
  filterData,
  focusNextCell,
  selectRow,
  deselectRow,
  deselectAll,
  focusCell,
  sortData,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
} from './reducerMethods';

/**
 * Used for actions that should be in all pages using a data table.
 */
const BASE_TABLE_PAGE_REDUCER = {
  focusNextCell,
  focusCell,
  sortData,
};

const customerInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  editField,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
};

const customerInvoices = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  deleteRecordsById,
};

const supplierInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  closeBasicModal,
  openBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addItem,
  editField,
  deleteRecordsById,
};

const supplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
  deleteRecordsById,
};

const programSupplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
};

const supplierRequisitions = {
  sortData,
  filterData,
  selectRow,
  deselectRow,
  openBasicModal,
  closeBasicModal,
  refreshData,
};

const PAGE_REDUCERS = {
  customerInvoice,
  customerInvoices,
  supplierInvoice,
  supplierRequisitions,
  supplierRequisition,
  programSupplierRequisition,
};

const getReducer = page => {
  const reducer = PAGE_REDUCERS[page];
  return (state, action) => {
    const { type } = action;
    if (!reducer[type]) return state;
    return reducer[type](state, action);
  };
};

export default getReducer;
<|endoftext|>


<commit_before>/*!
 * TerrificJS modularizes your frontend code by solely relying on naming conventions.
 * http://terrifically.org
 *
 * @copyright   Copyright (c) <%= grunt.template.today('yyyy') %> Remo Brunschwiler
 * @license     Licensed under MIT license
 * @version     <%= pkg.version %>
 */

/**
 * @module T
 */

/**
 * Responsible for application-wide issues such as the creation of modules.
 *
 * @author Remo Brunschwiler
 * @namespace T
 * @class Application
 *
 * @constructor
 * @param {Node} ctx
 *      The context node
 * @param {Object} config
 *      The configuration
 */
/* global Sandbox, Module, Utils */
function Application(ctx, config) {
	// validate params
	if (!ctx && !config) {
		// both empty
		ctx = document;
		config = {};
	}
	else if (config instanceof Node) {
		// reverse order of arguments
		var tmpConfig = config;
		config = ctx;
		ctx = tmpConfig;
	}
	else if (!(ctx instanceof Node) && !config) {
		// only config is given
		config = ctx;
		ctx = document;
	}
	else if (ctx instanceof Node && !config) {
		// only ctx is given
		config = {};
	}

	/**
	 * The context node.
	 *
	 * @property _ctx
	 * @type Node
	 */
	this._ctx = ctx;

	/**
	 * The sandbox to get the resources from.
	 * The singleton is shared between all modules.
	 *
	 * @property _sandbox
	 * @type Sandbox
	 */
	this._sandbox = new Sandbox(this, config);

	/**
	 * Contains references to all modules on the page.
	 *
	 * @property _modules
	 * @type Object
	 */
	this._modules = {};

	/**
	 * The next unique module id to use.
	 *
	 * @property id
	 * @type Number
	 */
	this._id = 1;
}

/**
 * Register modules within the context
 * Automatically registers all modules within the context,
 * as long as the modules use the naming conventions.
 *
 * @method registerModules
 * @param {Node} ctx
 *      The context node
 * @return {Object}
 *      A collection containing the registered modules
 */
Application.prototype.registerModules = function (ctx) {
	var modules = {};

	ctx = ctx || this._ctx;

	var fragment = document.createDocumentFragment();
	fragment.appendChild(ctx);

	[].forEach.call(fragment.querySelectorAll('[data-t-name]'), function (ctx) {

		/*
		 * A module can have different data attributes.
		 * See below for possible values.
		 */

		/*
		 * @config data-t-name="{mod-name}"
		 *
		 * Indicates that a JavaScript module should be bound.
		 * It can occur at most once.
		 *
		 * Example: data-t-name="basic"
		 */

		/*
		 * @config data-t-skin="{skin-name}"
		 *
		 * Indicates that the module Basic should be decorated by the JS skin Submarine. It can occur at most
		 * once. Multiple skins should be comma-separated.
		 *
		 * Example: data-t-skin="submarine"
		 */

		var mod = Utils.capitalize(Utils.camelize(ctx.getAttribute('data-t-name').trim()));
		var skins = ctx.getAttribute('data-t-skin') ? ctx.getAttribute('data-t-skin').split(',') : [];

		skins = skins.map(function (skin) {
			return Utils.capitalize(Utils.camelize(skin.trim()));
		});

		var module = this.registerModule(ctx, mod, skins);

		if (module) {
			modules[module.id] = module;
		}
	}.bind(this));

	return modules;
};

/**
 * Unregisters the modules given by the module instances.
 *
 * @method unregisterModules
 * @param {Object} modules
 *      A collection containing the modules to unregister
 */
Application.prototype.unregisterModules = function (modules) {
	modules = modules || this._modules;

	// unregister the given modules
	for (var id in modules) {
		if (modules.hasOwnProperty(id)) {
			delete this._modules[id];
		}
	}
};

/**
 * Starts (intializes) the registered modules.
 *
 * @method start
 * @param {Object} modules
 *      A collection of modules to start
 * @return {Promise}
 *      The after callback sync Promise
 */
Application.prototype.start = function (modules) {
	modules = modules || this._modules;

	var promises = [];

	// start the modules
	for (var id in modules) {
		if (modules.hasOwnProperty(id)) {
			var promise = modules[id].start();
			if (!(promise instanceof Promise)) {
				throw Error('The module with the id ' + id +
				' does not return a Promise on start');
			}
			promises.push(promise);
		}
	}

	// return self-fullfilling Promise if no modules are found
	if (promises.length === 0) {
		return new Promise(function (resolve) {
			resolve([]);
		});
	}

	// synchronize after callbacks
	var all = Promise.all(promises);
	all.then(function (callbacks) {
		for(var i = 0, len = callbacks.length; i < len; i++) {
			callbacks[i]();
		}
	}.bind(this))
		.catch(function (error) {
			throw Error('Synchronizing the after callbacks failed: ' + error);
		});

	return all;
};

/**
 * Stops the registered modules.
 *
 * @method stop
 * @param {Object} modules
 *      A collection of modules to stop
 */
Application.prototype.stop = function (modules) {
	modules = modules || this._modules;

	// stop the modules
	for (var id in modules) {
		if (modules.hasOwnProperty(id)) {
			modules[id].stop();
		}
	}
};

/**
 * Registers a module.
 *
 * @method registerModule
 * @param {Node} ctx
 *      The context node
 * @param {String} mod
 *      The module name. It must match the class name of the module
 * @param {Array} skins
 *      A list of skin names. Each entry must match a class name of a skin
 * @return {Module}
 *      The reference to the registered module
 */
Application.prototype.registerModule = function (ctx, mod, skins) {
	var modules = this._modules;

	mod = mod || undefined;
	skins = skins || [];

	if (mod && Module[mod]) {
		// assign the module a unique id
		var id = this._id++;
		ctx.setAttribute('data-t-id', id);

		// instantiate module
		modules[id] = new Module[mod](ctx, this._sandbox, id);

		// decorate it
		for(var i = 0, len = skins.length; i < len; i++) {
			var skin = skins[i];

			if (Module[mod][skin]) {
				Module[mod][skin](modules[id]);
			}
		}

		return modules[id];
	}

	return null;
};

/**
 * Gets the appropriate module for the given ID.
 *
 * @method getModuleById
 * @param {int} id
 *      The module ID
 * @return {Module}
 *      The appropriate module
 */
Application.prototype.getModuleById = function (id) {
	if (this._modules[id] !== undefined) {
		return this._modules[id];
	}
	else {
		throw Error('The module with the id ' + id +
		' does not exist');
	}
};
<commit_msg>#52 trigger first build<commit_after>/*!
 * TerrificJS modularizes your frontend code by solely relying on naming conventions.
 * http://terrifically.org
 *
 * @copyright   Copyright (c) <%= gulp.template.today('yyyy') %> Remo Brunschwiler
 * @license     Licensed under MIT license
 * @version     <%= pkg.version %>
 */

/**
 * @module T
 */

/**
 * Responsible for application-wide issues such as the creation of modules.
 *
 * @author Remo Brunschwiler
 * @namespace T
 * @class Application
 *
 * @constructor
 * @param {Node} ctx
 *      The context node
 * @param {Object} config
 *      The configuration
 */
/* global Sandbox, Module, Utils */
function Application(ctx, config) {
	// validate params
	if (!ctx && !config) {
		// both empty
		ctx = document;
		config = {};
	}
	else if (config instanceof Node) {
		// reverse order of arguments
		var tmpConfig = config;
		config = ctx;
		ctx = tmpConfig;
	}
	else if (!(ctx instanceof Node) && !config) {
		// only config is given
		config = ctx;
		ctx = document;
	}
	else if (ctx instanceof Node && !config) {
		// only ctx is given
		config = {};
	}

	/**
	 * The context node.
	 *
	 * @property _ctx
	 * @type Node
	 */
	this._ctx = ctx;

	/**
	 * The sandbox to get the resources from.
	 * The singleton is shared between all modules.
	 *
	 * @property _sandbox
	 * @type Sandbox
	 */
	this._sandbox = new Sandbox(this, config);

	/**
	 * Contains references to all modules on the page.
	 *
	 * @property _modules
	 * @type Object
	 */
	this._modules = {};

	/**
	 * The next unique module id to use.
	 *
	 * @property id
	 * @type Number
	 */
	this._id = 1;
}

/**
 * Register modules within the context
 * Automatically registers all modules within the context,
 * as long as the modules use the naming conventions.
 *
 * @method registerModules
 * @param {Node} ctx
 *      The context node
 * @return {Object}
 *      A collection containing the registered modules
 */
Application.prototype.registerModules = function (ctx) {
	var modules = {};

	ctx = ctx || this._ctx;

	var fragment = document.createDocumentFragment();
	fragment.appendChild(ctx);

	[].forEach.call(fragment.querySelectorAll('[data-t-name]'), function (ctx) {

		/*
		 * A module can have different data attributes.
		 * See below for possible values.
		 */

		/*
		 * @config data-t-name="{mod-name}"
		 *
		 * Indicates that a JavaScript module should be bound.
		 * It can occur at most once.
		 *
		 * Example: data-t-name="basic"
		 */

		/*
		 * @config data-t-skin="{skin-name}"
		 *
		 * Indicates that the module Basic should be decorated by the JS skin Submarine. It can occur at most
		 * once. Multiple skins should be comma-separated.
		 *
		 * Example: data-t-skin="submarine"
		 */

		var mod = Utils.capitalize(Utils.camelize(ctx.getAttribute('data-t-name').trim()));
		var skins = ctx.getAttribute('data-t-skin') ? ctx.getAttribute('data-t-skin').split(',') : [];

		skins = skins.map(function (skin) {
			return Utils.capitalize(Utils.camelize(skin.trim()));
		});

		var module = this.registerModule(ctx, mod, skins);

		if (module) {
			modules[module.id] = module;
		}
	}.bind(this));

	return modules;
};

/**
 * Unregisters the modules given by the module instances.
 *
 * @method unregisterModules
 * @param {Object} modules
 *      A collection containing the modules to unregister
 */
Application.prototype.unregisterModules = function (modules) {
	modules = modules || this._modules;

	// unregister the given modules
	for (var id in modules) {
		if (modules.hasOwnProperty(id)) {
			delete this._modules[id];
		}
	}
};

/**
 * Starts (intializes) the registered modules.
 *
 * @method start
 * @param {Object} modules
 *      A collection of modules to start
 * @return {Promise}
 *      The after callback sync Promise
 */
Application.prototype.start = function (modules) {
	modules = modules || this._modules;

	var promises = [];

	// start the modules
	for (var id in modules) {
		if (modules.hasOwnProperty(id)) {
			var promise = modules[id].start();
			if (!(promise instanceof Promise)) {
				throw Error('The module with the id ' + id +
				' does not return a Promise on start');
			}
			promises.push(promise);
		}
	}

	// return self-fullfilling Promise if no modules are found
	if (promises.length === 0) {
		return new Promise(function (resolve) {
			resolve([]);
		});
	}

	// synchronize after callbacks
	var all = Promise.all(promises);
	all.then(function (callbacks) {
		for(var i = 0, len = callbacks.length; i < len; i++) {
			callbacks[i]();
		}
	}.bind(this))
		.catch(function (error) {
			throw Error('Synchronizing the after callbacks failed: ' + error);
		});

	return all;
};

/**
 * Stops the registered modules.
 *
 * @method stop
 * @param {Object} modules
 *      A collection of modules to stop
 */
Application.prototype.stop = function (modules) {
	modules = modules || this._modules;

	// stop the modules
	for (var id in modules) {
		if (modules.hasOwnProperty(id)) {
			modules[id].stop();
		}
	}
};

/**
 * Registers a module.
 *
 * @method registerModule
 * @param {Node} ctx
 *      The context node
 * @param {String} mod
 *      The module name. It must match the class name of the module
 * @param {Array} skins
 *      A list of skin names. Each entry must match a class name of a skin
 * @return {Module}
 *      The reference to the registered module
 */
Application.prototype.registerModule = function (ctx, mod, skins) {
	var modules = this._modules;

	mod = mod || undefined;
	skins = skins || [];

	if (mod && Module[mod]) {
		// assign the module a unique id
		var id = this._id++;
		ctx.setAttribute('data-t-id', id);

		// instantiate module
		modules[id] = new Module[mod](ctx, this._sandbox, id);

		// decorate it
		for(var i = 0, len = skins.length; i < len; i++) {
			var skin = skins[i];

			if (Module[mod][skin]) {
				Module[mod][skin](modules[id]);
			}
		}

		return modules[id];
	}

	return null;
};

/**
 * Gets the appropriate module for the given ID.
 *
 * @method getModuleById
 * @param {int} id
 *      The module ID
 * @return {Module}
 *      The appropriate module
 */
Application.prototype.getModuleById = function (id) {
	if (this._modules[id] !== undefined) {
		return this._modules[id];
	}
	else {
		throw Error('The module with the id ' + id +
		' does not exist');
	}
};
<|endoftext|>


<commit_before>/*
 * Windshaft-CartoDB
 * ===============
 *
 * ./app.js [environment]
 *
 * environments: [development, production]
 */

// sanity check
var ENV = process.argv[2]
if (ENV != 'development' && ENV != 'production' && ENV != 'staging' ){
    console.error("\nnode app.js [environment]");
    console.error("environments: [development, production, staging]\n");
    process.exit(1);
}

var _ = require('underscore')
    , Step       = require('step')
	, CartodbWindshaft = require('./lib/cartodb/cartodb_windshaft');

// set environment specific variables
global.settings     = require(__dirname + '/config/settings');
global.environment  = require(__dirname + '/config/environments/' + ENV);
_.extend(global.settings, global.environment);

// Include cart_data.js only _after_ the "global" variable is set
// See https://github.com/Vizzuality/Windshaft-cartodb/issues/28
var cartoData = require('./lib/cartodb/carto_data');

var Windshaft = require('windshaft');
var serverOptions = require('./lib/cartodb/server_options');

ws = CartodbWindshaft(serverOptions);

// Maximum number of connections for one process
// 128 is a good number if you have up to 1024 filedescriptors
// 4 is good if you have max 32 filedescriptors
// 1 is good if you have max 16 filedescriptors
ws.maxConnections = global.environment.maxConnections || 128;

ws.listen(global.environment.port, global.environment.host);

ws.on('listening', function() {
  console.log("Windshaft tileserver started on " + global.environment.host + ':' + global.environment.port);
});

// DEPRECATED, use SIGUSR2
process.on('SIGUSR1', function() {
  console.log('WARNING: handling of SIGUSR1 by Windshaft-CartoDB is deprecated, please send SIGUSR2 instead');
  ws.dumpCacheStats();
});

process.on('SIGUSR2', function() {
  ws.dumpCacheStats();
});
<commit_msg>Drop unneeded include from outermost app<commit_after>/*
 * Windshaft-CartoDB
 * ===============
 *
 * ./app.js [environment]
 *
 * environments: [development, production]
 */

// sanity check
var ENV = process.argv[2]
if (ENV != 'development' && ENV != 'production' && ENV != 'staging' ){
    console.error("\nnode app.js [environment]");
    console.error("environments: [development, production, staging]\n");
    process.exit(1);
}

var _ = require('underscore')
    , Step       = require('step')
	, CartodbWindshaft = require('./lib/cartodb/cartodb_windshaft');

// set environment specific variables
global.settings     = require(__dirname + '/config/settings');
global.environment  = require(__dirname + '/config/environments/' + ENV);
_.extend(global.settings, global.environment);

var Windshaft = require('windshaft');
var serverOptions = require('./lib/cartodb/server_options');

ws = CartodbWindshaft(serverOptions);

// Maximum number of connections for one process
// 128 is a good number if you have up to 1024 filedescriptors
// 4 is good if you have max 32 filedescriptors
// 1 is good if you have max 16 filedescriptors
ws.maxConnections = global.environment.maxConnections || 128;

ws.listen(global.environment.port, global.environment.host);

ws.on('listening', function() {
  console.log("Windshaft tileserver started on " + global.environment.host + ':' + global.environment.port);
});

// DEPRECATED, use SIGUSR2
process.on('SIGUSR1', function() {
  console.log('WARNING: handling of SIGUSR1 by Windshaft-CartoDB is deprecated, please send SIGUSR2 instead');
  ws.dumpCacheStats();
});

process.on('SIGUSR2', function() {
  ws.dumpCacheStats();
});
<|endoftext|>


<commit_before>const UPDATE_PLAN = 'scenarioEditor/UPDATE_STEP';

// import clone from 'lodash';

const initialState = {
  escapeRoutes: '',
  itemsToCollect: '',
  locationsAndContacts: '',
  argumentLocations: '',
  codeword: ''
};

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case UPDATE_PLAN:
      return action.obj;
    default:
      return state;
  }
}

export function updatePlan(obj) {
  return {
    type: UPDATE_PLAN,
    obj
  };
}
<commit_msg>Fixed safety plan bug<commit_after>const UPDATE_PLAN = 'safetyPlan/UPDATE_PLAN';

// import clone from 'lodash';

const initialState = {
  escapeRoutes: '',
  itemsToCollect: '',
  locationsAndContacts: '',
  argumentLocations: '',
  codeword: ''
};

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case UPDATE_PLAN:
      return action.obj;
    default:
      return state;
  }
}

export function updatePlan(obj) {
  return {
    type: UPDATE_PLAN,
    obj
  };
}
<|endoftext|>


<commit_before>const express = require('express');
const DeviceDetector = require('device-detector-js');

const router = express.Router();
const api = require('../api');
const { cookieDomain } = require('../helpers/authentication');

const deviceDetector = new DeviceDetector();

const detectIE = (req) => {
	const device = deviceDetector.parse(req.headers['user-agent']);
	const isIE = (((device || {}).client || {}).name || '').includes('Internet Explorer');
	return isIE;
};

/*
 * Warnings for users who wan't to use the old register version if not teacher
 */
router.get(['/register', '/register/*'], (req, res, next) => res.render('registration/deprecated_warning'));

/*
 * EzD Dataprivacy Routes
 */
router.post('/registration/pincreation', (req, res, next) => {
	if (req.body && req.body.email) {
		return api(req).post('/registrationPins/', {
			json: {
				email: req.body.email,
				mailTextForRole: req.body.mailTextForRole,
			},
		}).then(() => {
			res.sendStatus(200);
		}).catch(err => res.status(500).send(err));
	}
	return res.sendStatus(500);
});

router.post(['/registration/submit', '/registration/submit/:sso/:accountId'], (req, res, next) => {
	const isIE = detectIE(req);

	if (isIE) {
		return res.status(500).send('Absenden der Registrierung mit Internet Explorer nicht erlaubt.');
	}

	// normalize form data
	req.body.privacyConsent = req.body.privacyConsent === 'true';
	req.body.thirdPartyConsent = req.body.thirdPartyConsent === 'true';
	req.body.termsOfUseConsent = req.body.termsOfUseConsent === 'true';
	req.body.roles = Array.isArray(req.body.roles) ? req.body.roles : [req.body.roles];

	return api(req)
		.post('/registration/', {
			json: req.body,
		})
		.then((response) => {
			const eMailAdresses = [response.user.email];
			if (response.parent) {
				eMailAdresses.push(response.parent.email);
			}
			eMailAdresses.forEach((eMailAdress) => {
				let passwordText = '';
				let studentInfotext = '';
				if (req.body.roles.includes('student')) {
					passwordText = `Startpasswort: ${req.body.password_1}`;
					studentInfotext = `Für Schüler: Nach dem ersten Login musst du ein persönliches Passwort festlegen.
Wenn du zwischen 14 und 16 Jahre alt bist, bestätige bitte zusätzlich die Einverständniserklärung,
damit du die ${res.locals.theme.short_title} nutzen kannst.`;
				}
				return api(req).post('/mails/', {
					json: {
						email: eMailAdress,
						subject: `Willkommen in der ${res.locals.theme.title}!`,
						headers: {},
						content: {
							text: `Hallo ${response.user.firstName}
mit folgenden Anmeldedaten kannst du dich in der ${res.locals.theme.title} einloggen:
Adresse: ${req.headers.origin || process.env.HOST}
E-Mail: ${response.user.email}
${passwordText}
${studentInfotext}
Viel Spaß und einen guten Start wünscht dir dein
${res.locals.theme.short_title}-Team`,
						},
					},
				});
			});
		})
		.then(() => {
			if (req.params.sso) {
				res.cookie(
					'jwt',
					req.cookies.jwt,
					Object.assign({},
						{ expires: new Date(Date.now() - 100000) },
						cookieDomain(res)),
				);
			}
		})
		.then(() => {
			res.sendStatus(200);
		})
		.catch((err) => {
			res.status(500).send((err.error || {}).message || err.message || 'Fehler bei der Registrierung.');
		});
});

router.get(['/registration/:classOrSchoolId/byparent', '/registration/:classOrSchoolId/byparent/:sso/:accountId'],
	async (req, res, next) => {
		const isIE = detectIE(req);

		if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
			if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
				return res.sendStatus(400);
			}
		}

		const user = {};
		user.importHash = req.query.importHash;
		user.classOrSchoolId = req.params.classOrSchoolId;
		user.sso = req.params.sso === 'sso';
		user.account = req.params.accountId || '';

		if (user.importHash) {
			const existingUser = await api(req).get(`/users/linkImport/${user.importHash}`);
			Object.assign(user, existingUser);
		}
		return res.render('registration/registration-parent', {
			title: 'Registrierung - Eltern',
			hideMenu: true,
			user,
			isIE,
		});
	});

router.get(['/registration/:classOrSchoolId/bystudent', '/registration/:classOrSchoolId/bystudent/:sso/:accountId'],
	async (req, res, next) => {
		const isIE = detectIE(req);

		if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
			if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
				return res.sendStatus(400);
			}
		}

		const user = {};
		user.importHash = req.query.importHash;
		user.classOrSchoolId = req.params.classOrSchoolId;
		user.sso = req.params.sso === 'sso';
		user.account = req.params.accountId || '';

		if (user.importHash) {
			const existingUser = await api(req).get(`/users/linkImport/${user.importHash}`);
			Object.assign(user, existingUser);
		}

		return res.render('registration/registration-student', {
			title: 'Registrierung - Schüler*',
			hideMenu: true,
			user,
			isIE,
		});
	});

router.get(['/registration/:classOrSchoolId/:byRole'], async (req, res, next) => {
	const isIE = detectIE(req);

	if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
		if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
			return res.sendStatus(400);
		}
	}

	const user = {};
	user.importHash = req.query.importHash || req.query.id; // req.query.id is deprecated
	user.classOrSchoolId = req.params.classOrSchoolId;

	if (user.importHash) {
		const existingUser = await api(req).get(`/users/linkImport/${user.importHash}`);
		Object.assign(user, existingUser);
	}

	let roleText;
	if (req.params.byRole === 'byemployee') {
		roleText = 'Lehrer*/Admins*';
	} else {
		delete user.firstName;
		delete user.lastName;
		roleText = 'Experte*';
	}

	return res.render('registration/registration-employee', {
		title: `Registrierung - ${roleText}`,
		hideMenu: true,
		user,
		isIE,
	});
});

router.get(['/registration/:classOrSchoolId', '/registration/:classOrSchoolId/:sso/:accountId'], (req, res, next) => {
	const isIE = detectIE(req);

	if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
		if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
			return res.sendStatus(400);
		}
	}

	return res.render('registration/registration', {
		title: 'Herzlich Willkommen bei der Registrierung',
		hideMenu: true,
		importHash: req.query.importHash || req.query.id, // req.query.id is deprecated
		classOrSchoolId: req.params.classOrSchoolId,
		sso: req.params.sso === 'sso',
		account: req.params.accountId || '',
		isIE,
	});
});

module.exports = router;
<commit_msg>var naming<commit_after>const express = require('express');
const DeviceDetector = require('device-detector-js');

const router = express.Router();
const api = require('../api');
const { cookieDomain } = require('../helpers/authentication');

const deviceDetectorObj = new DeviceDetector();

const detectIE = (req) => {
	const device = deviceDetectorObj.parse(req.headers['user-agent']);
	const isIE = (((device || {}).client || {}).name || '').includes('Internet Explorer');
	return isIE;
};

/*
 * Warnings for users who wan't to use the old register version if not teacher
 */
router.get(['/register', '/register/*'], (req, res, next) => res.render('registration/deprecated_warning'));

/*
 * EzD Dataprivacy Routes
 */
router.post('/registration/pincreation', (req, res, next) => {
	if (req.body && req.body.email) {
		return api(req).post('/registrationPins/', {
			json: {
				email: req.body.email,
				mailTextForRole: req.body.mailTextForRole,
			},
		}).then(() => {
			res.sendStatus(200);
		}).catch(err => res.status(500).send(err));
	}
	return res.sendStatus(500);
});

router.post(['/registration/submit', '/registration/submit/:sso/:accountId'], (req, res, next) => {
	const isIE = detectIE(req);

	if (isIE) {
		return res.status(500).send('Absenden der Registrierung mit Internet Explorer nicht erlaubt.');
	}

	// normalize form data
	req.body.privacyConsent = req.body.privacyConsent === 'true';
	req.body.thirdPartyConsent = req.body.thirdPartyConsent === 'true';
	req.body.termsOfUseConsent = req.body.termsOfUseConsent === 'true';
	req.body.roles = Array.isArray(req.body.roles) ? req.body.roles : [req.body.roles];

	return api(req)
		.post('/registration/', {
			json: req.body,
		})
		.then((response) => {
			const eMailAdresses = [response.user.email];
			if (response.parent) {
				eMailAdresses.push(response.parent.email);
			}
			eMailAdresses.forEach((eMailAdress) => {
				let passwordText = '';
				let studentInfotext = '';
				if (req.body.roles.includes('student')) {
					passwordText = `Startpasswort: ${req.body.password_1}`;
					studentInfotext = `Für Schüler: Nach dem ersten Login musst du ein persönliches Passwort festlegen.
Wenn du zwischen 14 und 16 Jahre alt bist, bestätige bitte zusätzlich die Einverständniserklärung,
damit du die ${res.locals.theme.short_title} nutzen kannst.`;
				}
				return api(req).post('/mails/', {
					json: {
						email: eMailAdress,
						subject: `Willkommen in der ${res.locals.theme.title}!`,
						headers: {},
						content: {
							text: `Hallo ${response.user.firstName}
mit folgenden Anmeldedaten kannst du dich in der ${res.locals.theme.title} einloggen:
Adresse: ${req.headers.origin || process.env.HOST}
E-Mail: ${response.user.email}
${passwordText}
${studentInfotext}
Viel Spaß und einen guten Start wünscht dir dein
${res.locals.theme.short_title}-Team`,
						},
					},
				});
			});
		})
		.then(() => {
			if (req.params.sso) {
				res.cookie(
					'jwt',
					req.cookies.jwt,
					Object.assign({},
						{ expires: new Date(Date.now() - 100000) },
						cookieDomain(res)),
				);
			}
		})
		.then(() => {
			res.sendStatus(200);
		})
		.catch((err) => {
			res.status(500).send((err.error || {}).message || err.message || 'Fehler bei der Registrierung.');
		});
});

router.get(['/registration/:classOrSchoolId/byparent', '/registration/:classOrSchoolId/byparent/:sso/:accountId'],
	async (req, res, next) => {
		const isIE = detectIE(req);

		if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
			if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
				return res.sendStatus(400);
			}
		}

		const user = {};
		user.importHash = req.query.importHash;
		user.classOrSchoolId = req.params.classOrSchoolId;
		user.sso = req.params.sso === 'sso';
		user.account = req.params.accountId || '';

		if (user.importHash) {
			const existingUser = await api(req).get(`/users/linkImport/${user.importHash}`);
			Object.assign(user, existingUser);
		}
		return res.render('registration/registration-parent', {
			title: 'Registrierung - Eltern',
			hideMenu: true,
			user,
			isIE,
		});
	});

router.get(['/registration/:classOrSchoolId/bystudent', '/registration/:classOrSchoolId/bystudent/:sso/:accountId'],
	async (req, res, next) => {
		const isIE = detectIE(req);

		if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
			if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
				return res.sendStatus(400);
			}
		}

		const user = {};
		user.importHash = req.query.importHash;
		user.classOrSchoolId = req.params.classOrSchoolId;
		user.sso = req.params.sso === 'sso';
		user.account = req.params.accountId || '';

		if (user.importHash) {
			const existingUser = await api(req).get(`/users/linkImport/${user.importHash}`);
			Object.assign(user, existingUser);
		}

		return res.render('registration/registration-student', {
			title: 'Registrierung - Schüler*',
			hideMenu: true,
			user,
			isIE,
		});
	});

router.get(['/registration/:classOrSchoolId/:byRole'], async (req, res, next) => {
	const isIE = detectIE(req);

	if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
		if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
			return res.sendStatus(400);
		}
	}

	const user = {};
	user.importHash = req.query.importHash || req.query.id; // req.query.id is deprecated
	user.classOrSchoolId = req.params.classOrSchoolId;

	if (user.importHash) {
		const existingUser = await api(req).get(`/users/linkImport/${user.importHash}`);
		Object.assign(user, existingUser);
	}

	let roleText;
	if (req.params.byRole === 'byemployee') {
		roleText = 'Lehrer*/Admins*';
	} else {
		delete user.firstName;
		delete user.lastName;
		roleText = 'Experte*';
	}

	return res.render('registration/registration-employee', {
		title: `Registrierung - ${roleText}`,
		hideMenu: true,
		user,
		isIE,
	});
});

router.get(['/registration/:classOrSchoolId', '/registration/:classOrSchoolId/:sso/:accountId'], (req, res, next) => {
	const isIE = detectIE(req);

	if (!RegExp('^[0-9a-fA-F]{24}$').test(req.params.classOrSchoolId)) {
		if (req.params.sso && !RegExp('^[0-9a-fA-F]{24}$').test(req.params.accountId)) {
			return res.sendStatus(400);
		}
	}

	return res.render('registration/registration', {
		title: 'Herzlich Willkommen bei der Registrierung',
		hideMenu: true,
		importHash: req.query.importHash || req.query.id, // req.query.id is deprecated
		classOrSchoolId: req.params.classOrSchoolId,
		sso: req.params.sso === 'sso',
		account: req.params.accountId || '',
		isIE,
	});
});

module.exports = router;
<|endoftext|>


<commit_before>/*
* @Author: mjreich
* @Date:   2015-05-18 17:03:15
* @Last Modified 2015-12-15
* @Last Modified time: 2015-12-15 08:44:15
*/

import _ from 'underscore'
import util from 'util'
import fs from 'fs'
import domain from 'domain'
import path from 'path'

import Dispatcher from './Dispatcher'
import Module from './Module'
import PluginManager from './PluginManager'
import ConfigurationManager from './ConfigurationManager'
import Watcher from './Watcher'

var logBanner = (message) => {
  console.log(' --- ')
  console.log(' --- '+ message)
}

/**
 * The Core Application class.
 *
 * @param {Object} opts the configuration options
 * @extends Dispatcher
 * @example
 * var App = require('@nxus/core').Application
 * var app = new App();
 * app.start()
 * module.exports = app;
 *
 */
export default class Application extends Dispatcher {

  constructor(opts = {}) {
    super()
    this._modules = {}
    this._pluginInfo = {}
    this._bootEvents = [
      'init',
      'load',
      'startup',
      'launch'
    ]

    this._setupLog()

    opts.appDir = opts.appDir || path.dirname(require.main.filename)

    this.config = Object.assign(opts, new ConfigurationManager(opts).getConfig())
    if(typeof this.config.debug === 'undefined') this.config.debug = (!process.env.NODE_ENV || process.env.NODE_ENV == 'development')
  }

  /**
   * Sets up the internal log object. Falls back to console.log.
   *
   * @private
   */
  _setupLog() {
    this.log = (...args) => {
      if(this.config.debug) console.log.apply(this, args)
    }

    this.log = Object.assign(this.log, console, {
      debug: (...args) => {
        if(this.config.debug) console.log.apply(this, args)
      },
      info: (...args) => {
        if(this.config.debug) console.log.apply(this, args)
      }
    })
  }

  /**
   * Loads the internal _modules object by instantiating the PluginManager class.
   *
   * @private
   */
  _setupPluginManager() {
    this._modules = new PluginManager(this.config)
    _.each(this._modules, (plugin) => {
      this._pluginInfo[plugin._pluginInfo.name] = plugin._pluginInfo
    })
  }

  /**
   * Returns an internal Module object for the given name.
   *
   * @param  {string} name The name of the module to return
   * @return {Module}
   */
  get(name) {
    if(!this._modules[name]) this._modules[name] = new Module(this, name)
    return this._modules[name]
  }

  /**
   * Initializes the application by loading plugins, then booting the application.
   *
   * **Note**: this should rarely be called directly. Instead use #start
   *
   * @return {Promise}
   */
  init() {
    return this._loadPlugins().then(this.boot.bind(this)).then(() => {
      if (!this.config.script && this.config.NODE_ENV != 'production') {
        this.appWatcher = new Watcher(this, this._getWatchPaths(), 'change', this._getAppIgnorePaths())
      }
    });
  }

  /**
   * Boots the application, cycling through the internal boot stages.
   *
   * **Note**: Should rarely be called directly. Instead use #start
   *
   * @return {Promise}
   */
  boot() {
    if (this.config.debug) logBanner('Booting Application')

    return new Promise.mapSeries(this._bootEvents, (e) => {
      if (this.config.debug) logBanner(`Booting Stage: ${e}`)
      return this.emit(e)
    })
  }

  /**
   * Stops the currently running application, removing all event listeners.
   *
   * @return {Promise}
   */
  stop() {
    if (this.config.debug) logBanner('Stopping')
    return this.emit("stop").then(() => {
      return Promise.resolve().then(() => {
        Object.keys(this._events).map((event) =>  this.removeAllListeners(event) );
      })
    })
  }

  /**
   * Starts the Nxus application.
   *
   * @return {Promise}
   */
  start() {
    this.log('*** NXUS APP Started at ' + new Date() + ' ***')
    return this.init()
  }

  /**
   * Restarts the Nxus application.
   *
   * @return {Promise}
   */
  restart() {
    console.log("Restarting App");
    return this._invalidatePluginsInRequireCache()
    .then(this.stop.bind(this))
    .then(this.start.bind(this))
  }

  /**
   * Invalidates the internal require plugin cache, ensuring all plugins are reloaded from the files.
   *
   * @private
   * @return {Promise}
   */
  _invalidatePluginsInRequireCache() {
    return Promise.resolve().then(() => {
      // we only want to reload nxus code
      var ignore = new RegExp("^(.*node_modules/(?!@nxus).*)")
      // but we need to always reload mongoose so that models can be rebuilt
      var mongoose = new RegExp("node_modules/mongoose")
      _.each(require.cache, (v, k) => {
        if (ignore.test(k) && !mongoose.test(k)) return
        delete require.cache[k]
      })
    })
  }

  /**
   * Returns an array of watch paths, either as defined by `config.watch` or the default paths
   * `/node_modules` and `/modules`
   *
   * @private
   * @return {Array}
   */
  _getWatchPaths() {
    return this.config.watch || ["**/node_modules/**", "**/modules/**"];
  }

  /**
   * Returns an array of paths to ignore, used by the watcher.
   *
   * @private
   * @return {Array}
   */
  _getAppIgnorePaths() {
    var opts = this.config.ignore || [];
    return opts.concat([
      '**/.git/**',
      '**.ejs'
    ]);
  }

  /**
   * Loads the plugins, then boots them and handles any errors.
   *
   * @private
   * @return {Promise}
   */
  _loadPlugins() {
    this._setupPluginManager()
    if (this.config.debug) {
      logBanner('Loading plugins')
    }

    return this._bootPlugins().catch((err) => {
      if (err) {
        console.log(err)
        process.exit()
      }
    })
  }

  /**
   * Iterates through all loaded plugins, instantiating them and returning a promise once every plugin has successfully started.
   *
   * @private
   * @return {Promise}
   */
  _bootPlugins() {
    return Promise.map(
      this._modules,
      this._bootPlugin.bind(this)
    ).catch((e) => {
      console.log('Error booting plugin')
      console.trace(e);
    })
  }

  /**
   * Accepts an instatiatable object (function or class) as a plugin, then boots it.
   *
   * @private
   * @param  {Function|Class} plugin the instantiable plugin
   * @return {[type]}
   */
  _bootPlugin(plugin) {
    //if (this.config.debug) console.log(' ------- ', plugin)
    try {
      var plugin = new plugin(this);
    } catch(e) {
      console.log(e.stack)
      process.exit();
    }
    return Promise.resolve(plugin)
  }
}
<commit_msg>Added fix for ES6 style exports<commit_after>/*
* @Author: mjreich
* @Date:   2015-05-18 17:03:15
* @Last Modified 2015-12-16
* @Last Modified time: 2015-12-16 06:28:09
*/

import _ from 'underscore'
import util from 'util'
import fs from 'fs'
import domain from 'domain'
import path from 'path'

import Dispatcher from './Dispatcher'
import Module from './Module'
import PluginManager from './PluginManager'
import ConfigurationManager from './ConfigurationManager'
import Watcher from './Watcher'

var logBanner = (message) => {
  console.log(' --- ')
  console.log(' --- '+ message)
}

/**
 * The Core Application class.
 *
 * @param {Object} opts the configuration options
 * @extends Dispatcher
 * @example
 * var App = require('@nxus/core').Application
 * var app = new App();
 * app.start()
 * module.exports = app;
 *
 */
export default class Application extends Dispatcher {

  constructor(opts = {}) {
    super()
    this._modules = {}
    this._pluginInfo = {}
    this._bootEvents = [
      'init',
      'load',
      'startup',
      'launch'
    ]

    this._setupLog()

    opts.appDir = opts.appDir || path.dirname(require.main.filename)

    this.config = Object.assign(opts, new ConfigurationManager(opts).getConfig())
    if(typeof this.config.debug === 'undefined') this.config.debug = (!process.env.NODE_ENV || process.env.NODE_ENV == 'development')
  }

  /**
   * Sets up the internal log object. Falls back to console.log.
   *
   * @private
   */
  _setupLog() {
    this.log = (...args) => {
      if(this.config.debug) console.log.apply(this, args)
    }

    this.log = Object.assign(this.log, console, {
      debug: (...args) => {
        if(this.config.debug) console.log.apply(this, args)
      },
      info: (...args) => {
        if(this.config.debug) console.log.apply(this, args)
      }
    })
  }

  /**
   * Loads the internal _modules object by instantiating the PluginManager class.
   *
   * @private
   */
  _setupPluginManager() {
    this._modules = new PluginManager(this.config)
    _.each(this._modules, (plugin) => {
      this._pluginInfo[plugin._pluginInfo.name] = plugin._pluginInfo
    })
  }

  /**
   * Returns an internal Module object for the given name.
   *
   * @param  {string} name The name of the module to return
   * @return {Module}
   */
  get(name) {
    if(!this._modules[name]) this._modules[name] = new Module(this, name)
    return this._modules[name]
  }

  /**
   * Initializes the application by loading plugins, then booting the application.
   *
   * **Note**: this should rarely be called directly. Instead use #start
   *
   * @return {Promise}
   */
  init() {
    return this._loadPlugins().then(this.boot.bind(this)).then(() => {
      if (!this.config.script && this.config.NODE_ENV != 'production') {
        this.appWatcher = new Watcher(this, this._getWatchPaths(), 'change', this._getAppIgnorePaths())
      }
    });
  }

  /**
   * Boots the application, cycling through the internal boot stages.
   *
   * **Note**: Should rarely be called directly. Instead use #start
   *
   * @return {Promise}
   */
  boot() {
    if (this.config.debug) logBanner('Booting Application')

    return new Promise.mapSeries(this._bootEvents, (e) => {
      if (this.config.debug) logBanner(`Booting Stage: ${e}`)
      return this.emit(e)
    })
  }

  /**
   * Stops the currently running application, removing all event listeners.
   *
   * @return {Promise}
   */
  stop() {
    if (this.config.debug) logBanner('Stopping')
    return this.emit("stop").then(() => {
      return Promise.resolve().then(() => {
        Object.keys(this._events).map((event) =>  this.removeAllListeners(event) );
      })
    })
  }

  /**
   * Starts the Nxus application.
   *
   * @return {Promise}
   */
  start() {
    this.log('*** NXUS APP Started at ' + new Date() + ' ***')
    return this.init()
  }

  /**
   * Restarts the Nxus application.
   *
   * @return {Promise}
   */
  restart() {
    console.log("Restarting App");
    return this._invalidatePluginsInRequireCache()
    .then(this.stop.bind(this))
    .then(this.start.bind(this))
  }

  /**
   * Invalidates the internal require plugin cache, ensuring all plugins are reloaded from the files.
   *
   * @private
   * @return {Promise}
   */
  _invalidatePluginsInRequireCache() {
    return Promise.resolve().then(() => {
      // we only want to reload nxus code
      var ignore = new RegExp("^(.*node_modules/(?!@nxus).*)")
      // but we need to always reload mongoose so that models can be rebuilt
      var mongoose = new RegExp("node_modules/mongoose")
      _.each(require.cache, (v, k) => {
        if (ignore.test(k) && !mongoose.test(k)) return
        delete require.cache[k]
      })
    })
  }

  /**
   * Returns an array of watch paths, either as defined by `config.watch` or the default paths
   * `/node_modules` and `/modules`
   *
   * @private
   * @return {Array}
   */
  _getWatchPaths() {
    return this.config.watch || ["**/node_modules/**", "**/modules/**"];
  }

  /**
   * Returns an array of paths to ignore, used by the watcher.
   *
   * @private
   * @return {Array}
   */
  _getAppIgnorePaths() {
    var opts = this.config.ignore || [];
    return opts.concat([
      '**/.git/**',
      '**.ejs'
    ]);
  }

  /**
   * Loads the plugins, then boots them and handles any errors.
   *
   * @private
   * @return {Promise}
   */
  _loadPlugins() {
    this._setupPluginManager()
    if (this.config.debug) {
      logBanner('Loading plugins')
    }

    return this._bootPlugins().catch((err) => {
      if (err) {
        console.log(err)
        process.exit()
      }
    })
  }

  /**
   * Iterates through all loaded plugins, instantiating them and returning a promise once every plugin has successfully started.
   *
   * @private
   * @return {Promise}
   */
  _bootPlugins() {
    return Promise.map(
      this._modules,
      this._bootPlugin.bind(this)
    ).catch((e) => {
      console.log('Error booting plugin')
      console.trace(e);
    })
  }

  /**
   * Accepts an instatiatable object (function or class) as a plugin, then boots it.
   *
   * @private
   * @param  {Function|Class} plugin the instantiable plugin
   * @return {[type]}
   */
  _bootPlugin(plugin) {
    //if (this.config.debug) console.log(' ------- ', plugin)
    try {
      if(plugin.default)
        plugin = plugin.default
      plugin = new plugin(this);
    } catch(e) {
      console.log(e.stack)
      process.exit();
    }
    return Promise.resolve(plugin)
  }
}
<|endoftext|>


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

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

//TODO: Selectively load app modules based on what kind of server this is...
const rssBot = require('./app/rss/daemon.js');
const serializer = require('./app/serializer.js');
const ircBot = require('./app/irc/daemon.js');
const httpd = require('./app/http/server.js');
<commit_msg>Well, that looks nicer.<commit_after>#!/usr/bin/env node

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

//TODO: Selectively load app modules based on what kind of server this is...
const
rssBot = require('./app/rss/daemon.js');
serializer = require('./app/serializer.js');
ircBot = require('./app/irc/daemon.js');
httpd = require('./app/http/server.js');
<|endoftext|>


<commit_before>import test from 'ava';
import FileScheme from '../src/file-scheme';

const { URL } = require('url');
const path = require('path'),
  fs = require('fs');

test('file scheme has name', t => {
  const scheme = new FileScheme();
  t.deepEqual(scheme.name, 'file');
});

test('can get', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(__dirname, '..', 'tests', 'file-test.js');
  const content = await scheme.get(context, new URL('file://' + aFile));
  t.true(content !== undefined);
});

test.only('can get archive', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(
    __dirname,
    '..',
    'tests',
    'fixtures',
    'archive.tar#a.txt'
  );
  const content = await scheme.get(context, new URL('file://' + aFile));
  t.true(content !== undefined);
});

test('can stat', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(__dirname, '..', 'tests', 'file-test.js');
  const stat = await scheme.stat(context, new URL('file://' + aFile));
  t.true(stat.size > 1000 && stat.size < 10000);
});

test('can put', async t => {
  const context = undefined;

  const scheme = new FileScheme();
  const aFile = path.join(__dirname, 'file2.tmp');
  await scheme.put(
    context,
    new URL('file://' + aFile),
    fs.createReadStream(path.join(__dirname, '..', 'tests', 'file-test.js'))
  );
  const stat = await scheme.stat(context, new URL('file://' + aFile));
  t.true(stat.size > 1000 && stat.size < 10000);
});

test.cb('can delete', t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(__dirname, 'file.tmp');
  fs.writeFileSync(aFile, 'someData');

  scheme.delete(context, new URL('file://' + aFile)).then(() => {
    fs.stat(aFile, error => t.end(error ? undefined : 'not deleted'));
  });

  return undefined;
});

test('can list', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aDir = path.join(__dirname);
  const list = await scheme.list(context, new URL('file://' + aDir));
  t.true(list.includes('test-bundle.js'));
});

/*
test('can list async iterator', async t => {
const context = undefined;

  const scheme = new FileScheme();
  const aDir = path.join(__dirname);
  const list = scheme._list(context, 'file://' + aDir);

  console.log(list);

  for await (const entry of list) {
    t.deepEqual(entry, 'bundle.js');
  }
});
*/

test('list error', async t => {
  function fn() {
    const context = undefined;
    const scheme = new FileScheme();
    return scheme.list(context, new URL('file:///unknown'));
  }

  const error = await t.throws(fn());
  t.is(error.message, `ENOENT: no such file or directory, scandir '/unknown'`);
});
<commit_msg>test: renable all test<commit_after>import test from 'ava';
import FileScheme from '../src/file-scheme';

const { URL } = require('url');
const path = require('path'),
  fs = require('fs');

test('file scheme has name', t => {
  const scheme = new FileScheme();
  t.deepEqual(scheme.name, 'file');
});

test('can get', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(__dirname, '..', 'tests', 'file-test.js');
  const content = await scheme.get(context, new URL('file://' + aFile));
  t.true(content !== undefined);
});

test('can get archive', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(
    __dirname,
    '..',
    'tests',
    'fixtures',
    'archive.tar#a.txt'
  );
  const content = await scheme.get(context, new URL('file://' + aFile));
  t.true(content !== undefined);
});

test('can stat', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(__dirname, '..', 'tests', 'file-test.js');
  const stat = await scheme.stat(context, new URL('file://' + aFile));
  t.true(stat.size > 1000 && stat.size < 10000);
});

test('can put', async t => {
  const context = undefined;

  const scheme = new FileScheme();
  const aFile = path.join(__dirname, 'file2.tmp');
  await scheme.put(
    context,
    new URL('file://' + aFile),
    fs.createReadStream(path.join(__dirname, '..', 'tests', 'file-test.js'))
  );
  const stat = await scheme.stat(context, new URL('file://' + aFile));
  t.true(stat.size > 1000 && stat.size < 10000);
});

test.cb('can delete', t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aFile = path.join(__dirname, 'file.tmp');
  fs.writeFileSync(aFile, 'someData');

  scheme.delete(context, new URL('file://' + aFile)).then(() => {
    fs.stat(aFile, error => t.end(error ? undefined : 'not deleted'));
  });

  return undefined;
});

test('can list', async t => {
  const context = undefined;
  const scheme = new FileScheme();
  const aDir = path.join(__dirname);
  const list = await scheme.list(context, new URL('file://' + aDir));
  t.true(list.includes('test-bundle.js'));
});

/*
test('can list async iterator', async t => {
const context = undefined;

  const scheme = new FileScheme();
  const aDir = path.join(__dirname);
  const list = scheme._list(context, 'file://' + aDir);

  console.log(list);

  for await (const entry of list) {
    t.deepEqual(entry, 'bundle.js');
  }
});
*/

test('list error', async t => {
  function fn() {
    const context = undefined;
    const scheme = new FileScheme();
    return scheme.list(context, new URL('file:///unknown'));
  }

  const error = await t.throws(fn());
  t.is(error.message, `ENOENT: no such file or directory, scandir '/unknown'`);
});
<|endoftext|>