<commit_before>'use strict';

/* Controllers */

function HangDownListCntr($scope) {
  $scope.apiLive = false;
  var _apiRequiredFunction = function(innerFunction){ return function(){
    if ($scope.apiLive) innerFunction.apply(this, arguments);
  }; };

  $scope.topics = [];

  var _activeTopicId = null;
  $scope.activeTopicIndex = 0;
  $scope.currentUser = null;

  $scope.conversationStart = null;

  var _timeCounterEvent = null;

  $scope.model = {
    getTopicIndex: function(topicId){
      var result = null;
      for (var i = $scope.topics.length - 1; i >= 0; i--) {
        if ($scope.topics[i].id == topicId) {
          result = i;
          break;
        }
      };
      return result;
    },
    activateTopicIndex: function(topicIndex){
      // If this index doesn't exist, do nothing.
      if (topicIndex < 0 || topicIndex >= $scope.topics.length) return;

      var topic = $scope.topics[topicIndex];
      // If the timer isn't already running, give it a go.
      topic.endTime = topic.duration = null;
      if (topic.startTime == null) topic.startTime = new Date().getTime();

      // Set up the model.
      $scope.activeTopicIndex = topicIndex;
      _activeTopicId = topic.id;
    },

    // TODO:
    // Move the rest of the model logic in here.
    // Make sure that only the model is updated on any of these calls.
    // Change _apiRequiredFunction() to _apiUpdatingFunction() and have
    //  it test for GAPI *and* call pushSharedState() at the end.
    // Use _apiUpdatingFunction() to create the publicly-visible scope functions
    //  by wrapping the internal model functions.
    // This will leave the model testable independently of any API nonsense.
  };

  $scope.topicSortConfig = {
    stop: function(e, ui){
      // Determing the new index for the current topic.
      var newIndex = $scope.model.getTopicIndex(_activeTopicId);

      // Make sure that that topic is the active topic.
      $scope.model.activateTopicIndex(newIndex);

      // TODO: Clear out all startTimes for any topic past the current one.

      // Push state.
      pushSharedState();
    }
  };

  $scope.formatDuration = function(fromTime, toTime){
    if (toTime == undefined) toTime = new Date().getTime();
    var timeDiff = toTime - fromTime;

    var hours = parseInt(timeDiff / (60*60*1000));
    var hourRem = timeDiff % (60*60*1000);
    var minutes = parseInt(hourRem / (60*1000));
    var minuteRem = hourRem % (60*1000);
    var seconds = parseInt(minuteRem / (1000));

    var result = hours.toString() + ":";
    if (minutes < 10) result += "0";
    result += minutes.toString() + ":";
    if (seconds < 10) result += "0";
    result += seconds.toString();

    return result;
  };

  $scope.regressTopic = _apiRequiredFunction(function(){
    // Only regress if the topic is not already the first.
    if ($scope.activeTopicIndex > 0) {
      // Null the current topic's start time, end time, and duration.
      $scope.topics[$scope.activeTopicIndex].startTime
        = $scope.topics[$scope.activeTopicIndex].endTime
        = $scope.topics[$scope.activeTopicIndex].duration
        = null;

      // Regress the topic.
      $scope.model.activateTopicIndex($scope.activeTopicIndex-1);

      // Submit changes to Google.
      pushSharedState();
    }
  });

  $scope.advanceTopic = _apiRequiredFunction(function(){
    // Only advance if the topic is not already the last.
    if ($scope.activeTopicIndex < $scope.topics.length - 1) {
      // Close out the previous topic's end time and duration.
      $scope.topics[$scope.activeTopicIndex].endTime = new Date().getTime();
      $scope.topics[$scope.activeTopicIndex].duration =
        $scope.formatDuration(
          $scope.topics[$scope.activeTopicIndex].startTime,
          $scope.topics[$scope.activeTopicIndex].endTime
        );

      // Advance the topic.
      $scope.model.activateTopicIndex($scope.activeTopicIndex+1);

      // Submit changes to Google.
      pushSharedState();
    }
  });

  var _topicIndex = 0;
  var createTopic = function(newLabel){
    return {
      id: new Date().getTime() + '-' + $scope.currentUser.id + '-' + _topicIndex++,
      label: newLabel,
      creator: $scope.currentUser.person.displayName,
      startTime: null,
      endTime: null,
      duration: null
    };
  };

  // TODO: Get rid of the requirements on the buffer here.
  $scope.newTopicBuffer = '';
  $scope.addNewTopic = _apiRequiredFunction(function(){
    // If there is no topic set, bail.
    if (!$scope.newTopicBuffer.length) return;

    // If there are any ';;', break the topic into multiple topics.
    var newTopics = $scope.newTopicBuffer.split(';;');
    $scope.newTopicBuffer = '';

    // Push add all topics.
    for (var i = 0; i < newTopics.length; i++) {
      $scope.topics.push(createTopic(newTopics[i].trim()));
    };

    // If there is no active topic yet, set the active topic.
    if (_activeTopicId == null) {
      _activeTopicId = $scope.topics[0].id;
      $scope.activeTopicIndex = 0;

      // Set the conversation and topic start times.
      $scope.conversationStart = $scope.topics[$scope.activeTopicIndex].startTime = new Date().getTime();
    }

    // If there is no time counting event running, create one.
    if (_timeCounterEvent == null) {
      _timeCounterEvent = setInterval(function(){
        // Update the current topic duration.
        $scope.topics[$scope.activeTopicIndex].duration =
          $scope.formatDuration($scope.topics[$scope.activeTopicIndex].startTime);

        // Apply the changes.
        $scope.$apply();
      }, 1000);
    }

    // Submit changes to Google.
    pushSharedState();
  });

  $scope.deleteTopic = _apiRequiredFunction(function(deleteTopicId){
    // If we're about to delete the current topic,
    // determine the next topic to select.
    if (deleteTopicId == _activeTopicId) {
      // If the next topic exists, use it.
      if ($scope.topics.length > ($scope.activeTopicIndex + 1))
        _activeTopicId = $scope.topics[$scope.activeTopicIndex+1].id;

      // Otherwise, if the previous topic exists, use it.
      else if ($scope.activeTopicIndex > 0)
        _activeTopicId = $scope.topics[$scope.activeTopicIndex-1].id;

      // Otherwise, our topics list is about to be empty.
      // Other plans will have to be made.
    }

    // Filter the array.
    var initialLength = $scope.topics.length;
    $scope.topics = $scope.topics.filter(function(topic){ return topic.id != deleteTopicId; });

    // If the length hasn't changed, we're done.
    if (initialLength == $scope.topics.length) return;

    // If we're replacing the current topic, set a new topic.
    var newIndex = $scope.model.getTopicIndex(_activeTopicId);
    if (newIndex == null) newIndex = 0;
    $scope.model.activateTopicIndex(newIndex);

    // If the topic list is empty, stop the counter and end the conversation.
    if (!$scope.topics.length) {
      // Stop any counter event.
      if (_timeCounterEvent != null)
        clearInterval(_timeCounterEvent);

      // Clear out all model fields.
      _timeCounterEvent = null;
      $scope.conversationStart = null;
      $scope.activeTopicIndex = 0;
      _activeTopicId = null;
    }

    // Push state.
    pushSharedState();
  });

  var initGapiModel = function(){
    // Create expected values in the shared model.
    gapi.hangout.data.submitDelta({
      activeTopicIndex: JSON.stringify(0),
      topics: JSON.stringify([]),
      conversationStart: JSON.stringify(null)
    });
  };

  var pushSharedState = function(stateDelta){
    // If there was no state provided, just push the whole system.
    if (!stateDelta) {
      stateDelta = {
        activeTopicIndex: JSON.stringify($scope.activeTopicIndex),
        topics: JSON.stringify($scope.topics),
        conversationStart: JSON.stringify($scope.conversationStart)
      };
    }

    // Next, set the current updater.
    stateDelta.modifier = $scope.currentUser.id;

    // Then submit the delta to GAPI.
    gapi.hangout.data.submitDelta( stateDelta );
  };

  var processStateUpdate = function(stateChangedEvent){
    // If the current shared state update was self-originated, skip.
    if (stateChangedEvent.state.modifier == $scope.currentUser.id) return;

    // Otherwise, apply the shared state.
    applySharedState(stateChangedEvent.state);
  };

  var applySharedState = function(newState){
    // Update the internal model.
    $scope.topics = JSON.parse(newState.topics);
    if (newState.conversationStart)
      $scope.conversationStart = JSON.parse(newState.conversationStart);

    // Make sure that the activeTopicIndex is updated.
    $scope.model.activateTopicIndex(JSON.parse(newState.activeTopicIndex));

    $scope.$apply();  // Have to do this to force the view to update.
  };

  // Add a callback to initialize gAPI elements.
  gapi.hangout.onApiReady.add(function(eventObj){
    var initialState = gapi.hangout.data.getState();

    // If the state has not been initialized, do that now.
    if (initialState.activeTopicIndex == undefined) initGapiModel();
    // Otherwise, update internal state with shared state.
    else applySharedState(initialState);

    // Set up internal model to work with gapi.
    $scope.apiLive = true;
    $scope.currentUser = gapi.hangout.getLocalParticipant();

    // Install the event handler for a change in model state.
    gapi.hangout.data.onStateChanged.add(processStateUpdate);
  });
}

//HangDownListCntr.$inject = ['$scope'];
<commit_msg>Last few tweaks to prevent the timer from disappearing and reappearing.<commit_after>'use strict';

/* Controllers */

function HangDownListCntr($scope) {
  $scope.apiLive = false;
  var _apiRequiredFunction = function(innerFunction){ return function(){
    if ($scope.apiLive) innerFunction.apply(this, arguments);
  }; };

  $scope.topics = [];

  var _activeTopicId = null;
  $scope.activeTopicIndex = 0;
  $scope.currentUser = null;

  $scope.conversationStart = null;

  var _timeCounterEvent = null;

  $scope.model = {
    getTopicIndex: function(topicId){
      var result = null;
      for (var i = $scope.topics.length - 1; i >= 0; i--) {
        if ($scope.topics[i].id == topicId) {
          result = i;
          break;
        }
      };
      return result;
    },
    activateTopicIndex: function(topicIndex){
      // If this index doesn't exist, do nothing.
      if (topicIndex < 0 || topicIndex >= $scope.topics.length) return;

      var topic = $scope.topics[topicIndex];
      // If the timer isn't already running, give it a go.
      topic.endTime = null;
      if (topic.startTime == null) topic.startTime = new Date().getTime();
      topic.duration = $scope.formatDuration(topic.startTime);

      // Set up the model.
      $scope.activeTopicIndex = topicIndex;
      _activeTopicId = topic.id;
    },

    // TODO:
    // Move the rest of the model logic in here.
    // Make sure that only the model is updated on any of these calls.
    // Change _apiRequiredFunction() to _apiUpdatingFunction() and have
    //  it test for GAPI *and* call pushSharedState() at the end.
    // Use _apiUpdatingFunction() to create the publicly-visible scope functions
    //  by wrapping the internal model functions.
    // This will leave the model testable independently of any API nonsense.
  };

  $scope.topicSortConfig = {
    stop: function(e, ui){
      // Determing the new index for the current topic.
      var newIndex = $scope.model.getTopicIndex(_activeTopicId);

      // Make sure that that topic is the active topic.
      $scope.model.activateTopicIndex(newIndex);

      // TODO: Clear out all startTimes for any topic past the current one.

      // Push state.
      pushSharedState();
    }
  };

  $scope.formatDuration = function(fromTime, toTime){
    if (toTime == undefined) toTime = new Date().getTime();
    var timeDiff = toTime - fromTime;

    var hours = parseInt(timeDiff / (60*60*1000));
    var hourRem = timeDiff % (60*60*1000);
    var minutes = parseInt(hourRem / (60*1000));
    var minuteRem = hourRem % (60*1000);
    var seconds = parseInt(minuteRem / (1000));

    var result = hours.toString() + ":";
    if (minutes < 10) result += "0";
    result += minutes.toString() + ":";
    if (seconds < 10) result += "0";
    result += seconds.toString();

    return result;
  };

  $scope.regressTopic = _apiRequiredFunction(function(){
    // Only regress if the topic is not already the first.
    if ($scope.activeTopicIndex > 0) {
      // Null the current topic's start time, end time, and duration.
      $scope.topics[$scope.activeTopicIndex].startTime
        = $scope.topics[$scope.activeTopicIndex].endTime
        = $scope.topics[$scope.activeTopicIndex].duration
        = null;

      // Regress the topic.
      $scope.model.activateTopicIndex($scope.activeTopicIndex-1);

      // Submit changes to Google.
      pushSharedState();
    }
  });

  $scope.advanceTopic = _apiRequiredFunction(function(){
    // Only advance if the topic is not already the last.
    if ($scope.activeTopicIndex < $scope.topics.length - 1) {
      // Close out the previous topic's end time and duration.
      $scope.topics[$scope.activeTopicIndex].endTime = new Date().getTime();
      $scope.topics[$scope.activeTopicIndex].duration =
        $scope.formatDuration(
          $scope.topics[$scope.activeTopicIndex].startTime,
          $scope.topics[$scope.activeTopicIndex].endTime
        );

      // Advance the topic.
      $scope.model.activateTopicIndex($scope.activeTopicIndex+1);

      // Submit changes to Google.
      pushSharedState();
    }
  });

  var _topicIndex = 0;
  var createTopic = function(newLabel){
    return {
      id: new Date().getTime() + '-' + $scope.currentUser.id + '-' + _topicIndex++,
      label: newLabel,
      creator: $scope.currentUser.person.displayName,
      startTime: null,
      endTime: null,
      duration: null
    };
  };

  // TODO: Get rid of the requirements on the buffer here.
  $scope.newTopicBuffer = '';
  $scope.addNewTopic = _apiRequiredFunction(function(){
    // If there is no topic set, bail.
    if (!$scope.newTopicBuffer.length) return;

    // If there are any ';;', break the topic into multiple topics.
    var newTopics = $scope.newTopicBuffer.split(';;');
    $scope.newTopicBuffer = '';

    // Push add all topics.
    for (var i = 0; i < newTopics.length; i++) {
      $scope.topics.push(createTopic(newTopics[i].trim()));
    };

    // If this is the first topic, go ahead an activate it.
    if ($scope.topics.length == 1) {
      $scope.model.activateTopicIndex(0);

      // Set the conversation and topic start times.
      $scope.conversationStart = $scope.topics[$scope.activeTopicIndex].startTime = new Date().getTime();
    }

    // If there is no time counting event running, create one.
    if (_timeCounterEvent == null) {
      _timeCounterEvent = setInterval(function(){
        // Update the current topic duration.
        $scope.topics[$scope.activeTopicIndex].duration =
          $scope.formatDuration($scope.topics[$scope.activeTopicIndex].startTime);

        // Apply the changes.
        $scope.$apply();
      }, 1000);
    }

    // Submit changes to Google.
    pushSharedState();
  });

  $scope.deleteTopic = _apiRequiredFunction(function(deleteTopicId){
    // If we're about to delete the current topic,
    // determine the next topic to select.
    if (deleteTopicId == _activeTopicId) {
      // If the next topic exists, use it.
      if ($scope.topics.length > ($scope.activeTopicIndex + 1))
        _activeTopicId = $scope.topics[$scope.activeTopicIndex+1].id;

      // Otherwise, if the previous topic exists, use it.
      else if ($scope.activeTopicIndex > 0)
        _activeTopicId = $scope.topics[$scope.activeTopicIndex-1].id;

      // Otherwise, our topics list is about to be empty.
      // Other plans will have to be made.
    }

    // Filter the array.
    var initialLength = $scope.topics.length;
    $scope.topics = $scope.topics.filter(function(topic){ return topic.id != deleteTopicId; });

    // If the length hasn't changed, we're done.
    if (initialLength == $scope.topics.length) return;

    // If we're replacing the current topic, set a new topic.
    var newIndex = $scope.model.getTopicIndex(_activeTopicId);
    if (newIndex == null) newIndex = 0;
    $scope.model.activateTopicIndex(newIndex);

    // If the topic list is empty, stop the counter and end the conversation.
    if (!$scope.topics.length) {
      // Stop any counter event.
      if (_timeCounterEvent != null)
        clearInterval(_timeCounterEvent);

      // Clear out all model fields.
      _timeCounterEvent = null;
      $scope.conversationStart = null;
      $scope.activeTopicIndex = 0;
      _activeTopicId = null;
    }

    // Push state.
    pushSharedState();
  });

  var initGapiModel = function(){
    // Create expected values in the shared model.
    gapi.hangout.data.submitDelta({
      activeTopicIndex: JSON.stringify(0),
      topics: JSON.stringify([]),
      conversationStart: JSON.stringify(null)
    });
  };

  var pushSharedState = function(stateDelta){
    // If there was no state provided, just push the whole system.
    if (!stateDelta) {
      stateDelta = {
        activeTopicIndex: JSON.stringify($scope.activeTopicIndex),
        topics: JSON.stringify($scope.topics),
        conversationStart: JSON.stringify($scope.conversationStart)
      };
    }

    // Next, set the current updater.
    stateDelta.modifier = $scope.currentUser.id;

    // Then submit the delta to GAPI.
    gapi.hangout.data.submitDelta( stateDelta );
  };

  var processStateUpdate = function(stateChangedEvent){
    // If the current shared state update was self-originated, skip.
    if (stateChangedEvent.state.modifier == $scope.currentUser.id) return;

    // Otherwise, apply the shared state.
    applySharedState(stateChangedEvent.state);
  };

  var applySharedState = function(newState){
    // Update the internal model.
    $scope.topics = JSON.parse(newState.topics);
    if (newState.conversationStart)
      $scope.conversationStart = JSON.parse(newState.conversationStart);

    // Make sure that the activeTopicIndex is updated.
    $scope.model.activateTopicIndex(JSON.parse(newState.activeTopicIndex));

    $scope.$apply();  // Have to do this to force the view to update.
  };

  // Add a callback to initialize gAPI elements.
  gapi.hangout.onApiReady.add(function(eventObj){
    var initialState = gapi.hangout.data.getState();

    // If the state has not been initialized, do that now.
    if (initialState.activeTopicIndex == undefined) initGapiModel();
    // Otherwise, update internal state with shared state.
    else applySharedState(initialState);

    // Set up internal model to work with gapi.
    $scope.apiLive = true;
    $scope.currentUser = gapi.hangout.getLocalParticipant();

    // Install the event handler for a change in model state.
    gapi.hangout.data.onStateChanged.add(processStateUpdate);
  });
}

//HangDownListCntr.$inject = ['$scope'];
<|endoftext|>


<commit_before>var todoModule = angular.module('todoApp', []);

todoApp.controller('TaskCtrl', ['$scope', function($scope) {
    $scope.todos = [];
}]);
<commit_msg>fixed a bug<commit_after>var todoControllers = angular.module('todoControllers', []);

todoControllers.controller('TaskCtrl', ['$scope', function($scope) {
    $scope.todos = [];
}]);
<|endoftext|>


<commit_before>// ========================================================================
// RootResponder Tests
// ========================================================================
/*globals module test ok isObj equals expects */

/**
  This file is slightly subtle, in that we want to make sure SproutCore is
  set up properly before any QUnit tests are run. Therefore...
*/

module("QUnit") ;

test("tests should not run until SproutCore is ready", function() {
  equals(SC.isReady, true, "SC.isReady");
});

test("tests should not run until the root responder has been setup", function() {
  expect(1);
  ok(SC.RootResponder.responder, "SC.RootResponder.responder");
});<commit_msg>new qUnit test: main() function should be overridable in a unit test<commit_after>// ========================================================================
// RootResponder Tests
// ========================================================================
/*globals module test ok isObj equals expects */

/**
  This file is slightly subtle, in that we want to make sure SproutCore is
  set up properly before any QUnit tests are run. Therefore...
*/

var mainRan = NO ;

main = function() { mainRan = YES; } ;

module("QUnit") ;

test("tests should not run until SproutCore is ready", function() {
  equals(SC.isReady, true, "SC.isReady");
});

test("tests should not run until the root responder has been setup", function() {
  expect(1);
  ok(SC.RootResponder.responder, "SC.RootResponder.responder");
});

test("main() function should be overridable in a unit test", function() {
  ok(mainRan, "main function defined in unit test did not run");
});<|endoftext|>


<commit_before>console.log("shareHelper.js connected");
//share the filtered images to an email
//var images = document.querySelectorAll("a.pig-figure");
// first get the filtered pictures
var imageURLS = "";
var images = document.querySelectorAll("a.pig-figure");

$("a.shareBtn").click(picturesToShare);
$("button#applyShare").click(sendMail);
$("a#confirmShare").click(hideModal);

// share all pictures currently showing
function picturesToShare() {

   clearImageURLS();
   images = document.querySelectorAll("a.pig-figure");
   console.log(images);
   for (var i = 0; i < images.length; i++) {
      imageURLS += ("\n\n" + images[i].getAttribute("href"));
   }
   console.log(images);
   console.log(imageURLS);
}

function clearImageURLS() {
   //images = "";
   imageURLS = "";
}

function sendMail() {

   var user = document.querySelectorAll("#email");
   var subject = document.querySelectorAll("#subject");
   var message = document.querySelectorAll("#message");
   console.log(Object.prototype.toString.call(user[0].value));
   console.log(subject[0].value);
   console.log(user[0].getAttribute("value"));
   var link = "mailto:" + escape(user[0].value) + "?subject=" +
	   escape(subject[0].value) + "&body=" + escape(message[0].value +
			   "\n") + escape(imageURLS);
   console.log(imageURLS);
   console.log(images);
   console.log(link);
   var send = document.querySelectorAll("#confirmShare");
   console.log(send[0].getAttribute("href"));
   send[0].setAttribute("href", link);
   console.log(send[0].getAttribute("href"));

   send[0].setAttribute("style", "color: #0f0");
   console.log("lmao")
}

function hideModal() {
   var modal = document.querySelector("#shareModal");
   $(div#shareModal).modal("hide");
}

<commit_msg>fixed share again goddammit<commit_after>console.log("shareHelper.js connected");
//share the filtered images to an email
//var images = document.querySelectorAll("a.pig-figure");
// first get the filtered pictures
var imageURLS = "";
var images = document.querySelectorAll("a.pig-figure");

$("a.shareBtn").click(picturesToShare);
$("button#applyShare").click(sendMail);
$("a#confirmShare").click(hideModal);

// share all pictures currently showing
function picturesToShare() {

   clearImageURLS();
   images = document.querySelectorAll("a.pig-figure");
   console.log(images);
   for (var i = 0; i < images.length; i++) {
      imageURLS += ("\n\n" + images[i].getAttribute("href"));
   }
   console.log(images);
   console.log(imageURLS);
}

function clearImageURLS() {
   //images = "";
   imageURLS = "";
}

function sendMail() {

   var user = document.querySelectorAll("#email");
   var subject = document.querySelectorAll("#subject");
   var message = document.querySelectorAll("#message");
   console.log(Object.prototype.toString.call(user[0].value));
   console.log(subject[0].value);
   console.log(user[0].getAttribute("value"));
   var link = "mailto:" + escape(user[0].value) + "?subject=" +
	   escape(subject[0].value) + "&body=" + escape(message[0].value +
			   "\n") + escape(imageURLS);
   console.log(imageURLS);
   console.log(images);
   console.log(link);
   var send = document.querySelectorAll("#confirmShare");
   console.log(send[0].getAttribute("href"));
   send[0].setAttribute("href", link);
   console.log(send[0].getAttribute("href"));

   send[0].setAttribute("style", "color: #0f0");
   console.log("lmao")
}

function hideModal() {
   var modal = document.querySelector("#shareModal");
   $("div#shareModal").modal("hide");
}

<|endoftext|>


<commit_before>var Achicken = Achicken || {};

Achicken.GameState = {

  init: function(currentLevel) {
    //constants
    this.MAX_DISTANCE_SHOOT = 190;
    this.MAX_SPEED_SHOOT = 1100;
    this.SHOOT_FACTOR = 12;
    this.KILL_DIFF = 25;

    //keep track of the current level
    this.currentLevel = currentLevel ? currentLevel : 'level1';

    //gravity
    this.game.physics.p2.gravity.y = 1000;

    //collision groups - if you want to specify what collides with what
    this.blocksCollisionGroup = this.game.physics.p2.createCollisionGroup();
    this.enemiesCollisionGroup = this.game.physics.p2.createCollisionGroup();
    this.chickensCollisionGroup = this.game.physics.p2.createCollisionGroup();

  },
  create: function() {

    //sky background
    this.sky = this.add.tileSprite(0, 0, this.game.world.width, this.game.world.height, 'sky');
    this.game.world.sendToBack(this.sky);

    this.chickenHUD = this.add.group();

    //enemies
    this.enemies = this.add.group();
    this.enemies.enableBody = true;
    this.enemies.physicsBodyType = Phaser.Physics.P2JS;

    //blocks
    this.blocks = this.add.group();
    this.blocks.enableBody = true;
    this.blocks.physicsBodyType = Phaser.Physics.P2JS;

    //bodies in p2 -> they get their anchor points set to 0.5
    this.floor = this.add.tileSprite(this.game.world.width/2, this.game.world.height - 24, this.game.world.width, 48, 'floor');
    this.blocks.add(this.floor);

    //specify collision for the floor
    this.floor.body.setCollisionGroup(this.blocksCollisionGroup);
    this.floor.body.collides([this.blocksCollisionGroup, this.enemiesCollisionGroup, this.chickensCollisionGroup]);
    this.floor.body.static = true;

    //load level information
    this.loadLevel();

    //init chicken shooting
    this.pole = this.add.sprite(180, 500, 'pole');
    this.pole.anchor.setTo(0.5, 0);

    this.game.input.onDown.add(this.prepareShot, this);

    //prepare our first chicken
    this.setupChicken();
  },

  hitEnemy: function(bodyB, shapeA, shapeB, equation) {
    var velocityDiff = Phaser.Point.distance(
      new Phaser.Point(equation[0].bodyA.velocity[0], equation[0].bodyA.velocity[1]),
      new Phaser.Point(equation[0].bodyB.velocity[0], equation[0].bodyB.velocity[1])
    );

    if(velocityDiff > Achicken.GameState.KILL_DIFF) {
      this.kill();

      //update the dead enemies
      Achicken.GameState.updateDeadCount();
    }
  },

  update: function() {
    if(this.isPreparingShot) {
      //make the chicken follow the user input pointer
      this.chicken.x = this.game.input.activePointer.position.x;
      this.chicken.y = this.game.input.activePointer.position.y;

      //if too far away stop shot preparation
      var distance = Phaser.Point.distance(this.chicken.position, this.pole.position);

      if(distance > this.MAX_DISTANCE_SHOOT) {
        this.isPreparingShot = false;
        this.isChickenReady = true;

        this.chicken.x = this.pole.x;
        this.chicken.y = this.pole.y;
      }

      //shoot when releasing
      if(this.game.input.activePointer.isUp) {
        this.isPreparingShot = false;

        this.throwChicken();
      }

    }
  },
  gameOver: function() {
    this.game.state.start('Game', true, false, this.currentLevel);
  },
  loadLevel: function() {
    this.levelData = JSON.parse(this.game.cache.getText(this.currentLevel));

    //create all blocks
    this.levelData.blocks.forEach(function(block){
      this.createBlock(block);
    }, this);

    //create all enemies
    this.levelData.enemies.forEach(function(enemy){
      this.createEnemy(enemy);
    }, this);

    this.countDeadEnemies = 0;
    this.totalNumEnemies = this.levelData.enemies.length;
    this.numChickens = 3;
  },
  createBlock: function(data) {
    var block = new Phaser.Sprite(this.game, data.x, data.y, data.asset);
    this.blocks.add(block);

    //set mass
    block.body.mass = data.mass;

    //set the collision group
    block.body.setCollisionGroup(this.blocksCollisionGroup);

    //they will collide with
    block.body.collides([this.blocksCollisionGroup, this.enemiesCollisionGroup, this.chickensCollisionGroup]);

    return block;
  },
  createEnemy: function(data) {
    var enemy = new Phaser.Sprite(this.game, data.x, data.y, data.asset);
    this.enemies.add(enemy);

    //set the collision group
    enemy.body.setCollisionGroup(this.enemiesCollisionGroup);

    //they will collide with
    enemy.body.collides([this.blocksCollisionGroup, this.enemiesCollisionGroup, this.chickensCollisionGroup]);

    //call hitEnemy when enemies hit something
    enemy.body.onBeginContact.add(this.hitEnemy, enemy);

    return enemy;
  },
  prepareShot: function(event) {
    if(this.isChickenReady) {
      this.isPreparingShot = true;
      this.isChickenReady = false;
    }
  },
  setupChicken: function() {
    //add chicken to starting position
    this.chicken = this.add.sprite(this.pole.x, this.pole.y, 'chicken');
    this.chicken.anchor.setTo(0.5);

    this.isChickenReady = true;

    this.refreshStats();
  },
  throwChicken: function() {
    //enable physics once thrown
    this.game.physics.p2.enable(this.chicken);

    //set collision group
    this.chicken.body.setCollisionGroup(this.chickensCollisionGroup);

    //what it will collide with
    this.chicken.body.collides([this.blocksCollisionGroup, this.enemiesCollisionGroup, this.chickensCollisionGroup]);

    //calculate difference between the current position and the top of the pole
    var diff = Phaser.Point.subtract(this.pole.position,this.chicken.position);

    //set chicken velocity according to the difference vector
    this.chicken.body.velocity.x = Math.abs(diff.x * this.SHOOT_FACTOR)/(diff.x * this.SHOOT_FACTOR) * Math.min(Math.abs(diff.x * this.SHOOT_FACTOR), this.MAX_SPEED_SHOOT);
    this.chicken.body.velocity.y = Math.abs(diff.y * this.SHOOT_FACTOR)/(diff.y * this.SHOOT_FACTOR) * Math.min(Math.abs(diff.y * this.SHOOT_FACTOR), this.MAX_SPEED_SHOOT);

    //what happens after the bird is thrown
    this.endTurn();
  },
  updateDeadCount: function() {
    this.countDeadEnemies++;

    if(this.countDeadEnemies == this.totalNumEnemies) {
      console.log('youve won');
      this.gameOver();
    }
  },
  endTurn: function() {
    //decrease the number of chickens left to throw
    this.numChickens--;

    //next chicken or game over some seconds later
    this.game.time.events.add(3 * Phaser.Timer.SECOND, function(){
      this.chicken.kill();

      //a second later we should show a new chicken
      this.game.time.events.add(Phaser.Timer.SECOND, function(){
        //if there are no more chickens, then game over
        if(this.numChickens > 0) {
          this.setupChicken();
        }
        else {
          this.gameOver();
        }
      }, this);
    }, this);
  },
  refreshStats: function() {
    this.chickenHUD.removeAll();

    var i = 0;
    while(i < this.numChickens) {
      this.chickenHUD.create(this.game.width - 100 - i * 80, 30, 'chicken');
      i++;
    }
  }

};
<commit_msg>remove blocks<commit_after>var Achicken = Achicken || {};

Achicken.GameState = {

  init: function(currentLevel) {
    //constants
    this.MAX_DISTANCE_SHOOT = 190;
    this.MAX_SPEED_SHOOT = 1100;
    this.SHOOT_FACTOR = 12;
    this.KILL_DIFF = 25;

    //keep track of the current level
    this.currentLevel = currentLevel ? currentLevel : 'level1';

    //gravity
    this.game.physics.p2.gravity.y = 1000;

    //collision groups - if you want to specify what collides with what
    this.blocksCollisionGroup = this.game.physics.p2.createCollisionGroup();
    this.enemiesCollisionGroup = this.game.physics.p2.createCollisionGroup();
    this.chickensCollisionGroup = this.game.physics.p2.createCollisionGroup();

  },
  create: function() {

    //sky background
    this.sky = this.add.tileSprite(0, 0, this.game.world.width, this.game.world.height, 'sky');
    this.game.world.sendToBack(this.sky);

    this.chickenHUD = this.add.group();

    //enemies
    this.enemies = this.add.group();
    this.enemies.enableBody = true;
    this.enemies.physicsBodyType = Phaser.Physics.P2JS;

    //blocks
    this.blocks = this.add.group();
    this.blocks.enableBody = true;
    this.blocks.physicsBodyType = Phaser.Physics.P2JS;

    //bodies in p2 -> they get their anchor points set to 0.5
    this.floor = this.add.tileSprite(this.game.world.width/2, this.game.world.height - 24, this.game.world.width, 48, 'floor');
    this.blocks.add(this.floor);

    //specify collision for the floor
    this.floor.body.setCollisionGroup(this.blocksCollisionGroup);
    this.floor.body.collides([this.blocksCollisionGroup, this.enemiesCollisionGroup, this.chickensCollisionGroup]);
    this.floor.body.static = true;
  },

  update: function() {

  }
};
<|endoftext|>


<commit_before>// device.js: a unified way to handle those newspangled JavaScript APIs.

var device = {};

// an object type to return from onPaste
function ClipboardValue(type, data, attachments) {
  // either 'text', 'image', 'html'
  this.type = type;
  // a string (plaintext), a file handle, html source, depending on the type
  this.data = data;
  this.attachments = attachments;
}

// clipboard
device.initPaste = function() {
  var pasteCatcher = document.createElement('div');
  pasteCatcher.setAttribute('contenteditable', '');
  // make div invisible
  pasteCatcher.style.opacity = 0;
  pasteCatcher.style.marginLeft = "-9001px";
  pasteCatcher.style.marginTop = "-9001px";
  pasteCatcher.id = "pasteCatcher";
  document.body.appendChild(pasteCatcher);

  // initially focus on nothing.
  document.body.focus();
  function onkeydown(event) {
    // we only want to take away focus if no text element was focused
    // to begin with, or there is no text selection (so user can copy)
    var selectionEmpty = true;
    if (window.getSelection) {
      selectionEmpty = !(window.getSelection().toString());
    } else if (document.selection && document.selection.type !== 'Control') {
      selectionEmpty = !document.selection.createRange().text;
    }
    if (document.activeElement === document.body && selectionEmpty) {
      switch (event.keyCode || event.which || window.event.keyCode) {
        case 16: // shift for shift + insert
        case 17: // ctrl for ctrl + v
        case 91: // cmd for cmd + v in chrome?
        case 224: // cmd in firefox?
          // reaim the focus
          pasteCatcher.focus();
          break;
      }
    }
  }
  document.addEventListener('keydown', onkeydown);
  // take advantage of IE's onbeforepaste as well, which triggers
  // when a menu containing the paste command is opened
  window.onbeforepaste = window.onkeydown;
};

// this method only fires when the focus is not on a text input, so
// that pasting in the regular text input works as normal.
device.onPaste = function(handler) {

  function checkPasteCatcher() {
    var pasteCatcher = document.getElementById("pasteCatcher");
    var child = pasteCatcher.childNodes[0];
    console.log(child);
    // TODO: convert child into a ClipboardValue and pass into handler
    handler(null);
    pasteCatcher.innerHTML = "";
  }

  document.onpaste = function(event) {
    // only if we're pasting into the pasteCatcher do we want to do anything.
    if (event.target.id === 'pasteCatcher') {
      // clear the paste catcher so it only contains the clipboard data
      document.getElementById('pasteCatcher').innerHTML = "";

      var data = event.clipboardData || event.originalEvent.clipboardData;
      // are we in Chrome? Chrome and Firefox support event.clipboardData
      if (data) {
        var items = data.items;
        //console.log(JSON.stringify(data.files));
        // does it have the .items attribute? If so, we're in luck
        // and probably using Chrome.
        if (items) {
          console.log(JSON.stringify(data));
          // clipboardData is a DataTransfer object with:
          // clipboardData.items is a DataTransferItemsList object. Each
          // element of the list has a .kind which is either "string" or
          // "file", and has a .type which is a mimetype string. If it is
          // a file, get the File object with .getAsFile(). If it is a string,
          // get it with .getAsString(callback) where callback takes in the
          // string.
          // clipboardData.files is a FileList object containing any
          // images/attachment refs in an HTML paste (with type text/html).
          // First, loop through the items array to find an image.
          for (var i = 0; i < items.length; i++) {
            if (items[i].type.indexOf('image') !== -1) {
              var file = items[i].getAsFile();
              return handler(new ClipboardValue('image', file));
            }
          }
          // no image found, try to find html
          for (var i = 0; i < items.length; i++) {
            if (items[i].type === 'text/html') {
              return items[i].getAsString(function(str) {
                return handler(new ClipboardValue('html', str));
              });
            }
          }
          // no html, find plain text
          for (var i = 0; i < items.length; i++) {
            if (items[i].type === 'text/plain') {
              return items[i].getAsString(function(str) {
                return handler(new ClipboardValue('text', str));
              });
            }
          }
          // no image or text found, return nothing and don't call handler.
          return null;
        }
        // if not, try to read contents from the div. We don't do this with
        // Chrome because you cannot directly paste images into html nodes
        // in Chrome.
      }
      // IE supports window.clipboardData, but it only supports .getData on
      // the 'Text' and 'URL' types, so we'll read from the div as well.

      // wait some time for the content to be pasted, then get its contents
      // since the onpaste event runs before the content is inserted
      setTimeout(checkPasteCatcher, 100);
    }
  };
};

// drag and drop
device.dragAndDrop = false;
device.onDrop = function(handler) {

};

// video/audio recording
device.record = false;
device.startRecording = function(handler) {

};
device.interruptRecording = function(handler) {

};
device.stopRecording = function(handler) {

};
device.isRecording = function(handler) {

};
device.takePicture = function(handler) {

};

// geolocation
device.geolocation = false;
device.onLocationUpdate = function(handler) {

};

// battery management & page visibility
device.battery = false;
device.getBatteryLevel = function(handler) {

};
device.useBatteryStrategy = function(strategy) {

};

device.initPaste();
device.onPaste(function(){
  console.log('paste received!');
});
<commit_msg>Finish paste code for Firefox<commit_after>// device.js: a unified way to handle those newspangled JavaScript APIs.

var device = {};

// an object type to return from onPaste
function ClipboardValue(type, data) {
  // either 'text', 'image', 'html'
  this.type = type;
  // a string (plaintext), a Blob, html source, depending on the type
  this.data = data;
}

// clipboard
device.initPaste = function() {
  if (device.pasteCatcher) return;
  var pasteCatcher = document.createElement('div');
  pasteCatcher.setAttribute('contenteditable', '');
  // make div invisible
  pasteCatcher.style.opacity = 0;
  pasteCatcher.style.marginLeft = "-9001px";
  pasteCatcher.style.marginTop = "-9001px";
  pasteCatcher.id = "pasteCatcher";
  document.body.appendChild(pasteCatcher);
  device.pasteCatcher = pasteCatcher;

  // initially focus on nothing.
  document.body.focus();
  function onkeydown(event) {
    // we only want to take away focus if no text element was focused
    // to begin with, or there is no text selection (so user can copy)
    var selectionEmpty = true;
    if (window.getSelection) {
      selectionEmpty = !window.getSelection().toString();
    } else if (document.selection && document.selection.type !== 'Control') {
      selectionEmpty = !document.selection.createRange().text;
    }
    if (document.activeElement === document.body && selectionEmpty) {
      switch (event.keyCode || event.which || window.event.keyCode) {
        case 16: // shift for shift + insert
        case 17: // ctrl for ctrl + v
        case 91: // cmd for cmd + v in chrome?
        case 224: // cmd in firefox?
          // reaim the focus
          pasteCatcher.focus();
          break;
      }
    }
  }
  document.addEventListener('keydown', onkeydown);
  // take advantage of IE's onbeforepaste as well, which triggers
  // when a menu containing the paste command is opened
  window.onbeforepaste = window.onkeydown;
};

// this method only fires when the focus is not on a text input, so
// that pasting in the regular text input works as normal.
device.onPaste = function(handler) {
  var pasteCatcher = device.pasteCatcher;

  // thanks http://stackoverflow.com/questions/4998908
  function dataURItoBlob(dataURI) {
    var byteString = atob(dataURI.split(',')[1]);
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: mimeString });
  }

  function checkPasteCatcher() {
    var nodes = pasteCatcher.childNodes;
    if (nodes.length === 0) {
      return null;
    }
    // if there is one HTMLImageElement, an image has been pasted
    if (nodes.length === 1 && nodes[0].tagName === "IMG") {
      var imageBlob = dataURItoBlob(nodes[0].src);
      return handler(new ClipboardValue('image', imageBlob));
    }
    // if there are no nodes besides Text nodes, return the plain text
    if (pasteCatcher.children.length === 0) {
      return handler(new ClipboardValue('text', nodes[0].wholeText));
    }
    // otherwise, treat everything as some HTML and return it
    return handler(new ClipboardValue('html', pasteCatcher.innerHTML));
  }

  pasteCatcher.onpaste = function(event) {
    // only if we're pasting into the pasteCatcher do we want to do anything.
    //if (event.target.id === 'pasteCatcher') {
      // clear the paste catcher so it only contains the clipboard data
      pasteCatcher.innerHTML = "";

      var data = event.clipboardData || event.originalEvent.clipboardData;
      // are we in Chrome? Chrome and Firefox support event.clipboardData
      if (data) {
        var items = data.items;
        // does it have the .items attribute? If so, we're in luck
        // and probably using Chrome.
        if (items) {
          // clipboardData is a DataTransfer object with:
          // clipboardData.items is a DataTransferItemsList object. Each
          // element of the list has a .kind which is either "string" or
          // "file", and has a .type which is a mimetype string. If it is
          // a file, get the File object with .getAsFile(). If it is a string,
          // get it with .getAsString(callback) where callback takes in the
          // string.
          for (var i = 0; i < items.length; i++) {
            if (items[i].type.indexOf('image') !== -1) {
              var file = items[i].getAsFile();
              return handler(new ClipboardValue('image', file));
            }
          }
          // no image found, try to find html
          for (var i = 0; i < items.length; i++) {
            if (items[i].type === 'text/html') {
              return items[i].getAsString(function(str) {
                return handler(new ClipboardValue('html', str));
              });
            }
          }
          // no html, find plain text
          for (var i = 0; i < items.length; i++) {
            if (items[i].type === 'text/plain') {
              return items[i].getAsString(function(str) {
                return handler(new ClipboardValue('text', str));
              });
            }
          }
          // no image or text found, return nothing and don't call handler.
          return null;
        }
        // if not, try to read contents from the div. We don't do this with
        // Chrome because you cannot directly paste images into html nodes
        // in Chrome.
      }
      // IE supports window.clipboardData, but it only supports .getData on
      // the 'Text' and 'URL' types, so we'll read from the div as well.

      // wait some time for the content to be pasted, then get its contents
      // since the onpaste event runs before the content is inserted
      setTimeout(checkPasteCatcher, 100);
    //}
  };
};

// drag and drop
device.dragAndDrop = false;
device.onDrop = function(handler) {

};

// video/audio recording
device.record = false;
device.startRecording = function(handler) {

};
device.interruptRecording = function(handler) {

};
device.stopRecording = function(handler) {

};
device.isRecording = function(handler) {

};
device.takePicture = function(handler) {

};

// geolocation
device.geolocation = false;
device.onLocationUpdate = function(handler) {

};

// battery management & page visibility
device.battery = false;
device.getBatteryLevel = function(handler) {

};
device.useBatteryStrategy = function(strategy) {

};

device.initPaste();
device.onPaste(function(value) {
  console.log(value.type + ' paste received!');
  console.log(value.data);
});
<|endoftext|>


<commit_before>// Invoke 'strict' JavaScript mode
'use strict';

// Load the module dependencies
var passport = require('passport'),
	url = require('url'),
	FacebookStrategy = require('passport-facebook').Strategy,
	config = require('../config'),
	users = require('../../app/controllers/users.server.controller');

// Create the Facebook strategy configuration method
module.exports = function() {
	// Use the Passport's Facebook strategy
	passport.use(new FacebookStrategy({
			clientID: config.facebook.clientID,
			clientSecret: config.facebook.clientSecret,
			callbackURL: config.facebook.callbackURL,
			passReqToCallback: true
		},
		function(req, accessToken, refreshToken, profile, done) {
			// Set the user's provider data and include tokens
			var providerData = profile._json;
			providerData.accessToken = accessToken;
			providerData.refreshToken = refreshToken;

			// Create the user OAuth profile
			var providerUserProfile = {
				firstName: profile.name.givenName,
				lastName: profile.name.familyName,
				fullName: profile.displayName,
				email: profile.emails[0].value,
				username: profile.username,
				provider: 'facebook',
				providerId: profile.id,
				providerData: providerData
			};

			// Save the user OAuth profile
			users.saveOAuthUserProfile(req, providerUserProfile, done);
		}
	));
};<commit_msg>Login con fb- debug<commit_after>// Invoke 'strict' JavaScript mode
'use strict';

// Load the module dependencies
var passport = require('passport'),
	url = require('url'),
	FacebookStrategy = require('passport-facebook').Strategy,
	config = require('../config'),
	users = require('../../app/controllers/users.server.controller');

// Create the Facebook strategy configuration method
module.exports = function() {
	// Use the Passport's Facebook strategy
	passport.use(new FacebookStrategy({
			clientID: config.facebook.clientID,
			clientSecret: config.facebook.clientSecret,
			callbackURL: config.facebook.callbackURL,
			passReqToCallback: true
		},
		function(req, accessToken, refreshToken, profile, done) {
			// Set the user's provider data and include tokens
			var providerData = profile._json;
			providerData.accessToken = accessToken;
			providerData.refreshToken = refreshToken;

			// Create the user OAuth profile
			console.log("FB profile");
			console.log(profile);
			var providerUserProfile = {
				firstName: profile.name.givenName,
				lastName: profile.name.familyName,
				fullName: profile.displayName,
				email: profile.emails[0].value,
				username: profile.username,
				provider: 'facebook',
				providerId: profile.id,
				providerData: providerData
			};

			// Save the user OAuth profile
			users.saveOAuthUserProfile(req, providerUserProfile, done);
		}
	));
};
<|endoftext|>


<commit_before>angular.module('carpooler')
  .factory('Travel', function($resource) {
    return $resource('/api/travels/:_id');
  });
<commit_msg>changed route<commit_after>angular.module('carpooler')
  .factory('Travel', function($resource) {
    return $resource('/api/carpooler/:id');
  });
<|endoftext|>


<commit_before>var spacebox = angular.module('spacebox',
    [ 'ngAnimate', 'ngRoute', 'ngResource', 'ngTouch', 'ngCookies', 'angular-carousel', 'angularMoment', 'LocalStorageModule', 'ui.bootstrap.modal', 'ui.bootstrap.tpls']);

spacebox.config(['config', '$routeProvider', '$logProvider', '$compileProvider',
    function (config, $routeProvider, $logProvider, $compileProvider) {
        $routeProvider.
            when('/login', {
                templateUrl: 'src/js/app/templates/views/login.html',
                controller: 'LoginViewController'
            }).
            when('/', {
                templateUrl: 'src/js/app/templates/views/users.html',
                controller: 'UsersViewController',
                controllerAs: 'main'
            }).
            when('/friends', {
                templateUrl: 'src/js/app/templates/views/friends.html',
                controller: 'FriendsViewController',
                controllerAs: 'friends'
            }).
            when('/error', {
                templateUrl: 'src/js/app/templates/views/error.html',
                controller: 'ErrorViewController'
            }).
            when('/properties', {
                templateUrl: 'src/js/app/templates/views/properties.html',
                controller: 'PropertiesViewController'
            }).
            otherwise({
                redirectTo: '/login'
            });

        if (!angular.equals(config.DEVELOPMENT, true)) {
            $compileProvider.debugInfoEnabled(false);
            $logProvider.debugEnabled(false);
        }
    }]);

spacebox.run(['$rootScope', '$location', '$log', '$route', 'VkService', 'ConfigService', 'UserService', 'ErrorHandler', 'amMoment', 'localStorageService',
    function ($rootScope, $location, $log, $route, VkService, ConfigService, UserService, ErrorHandler, amMoment, localStorageService) {
        amMoment.changeLocale('ru');
        $rootScope.$on('$locationChangeStart', function (event) {
            var path = $location.path();

            if (Modernizr.standalone && angular.isString(path)) {
                localStorageService.set('app.route', path);
            }

            function login (info) {
                ConfigService.init(info);
                if (Modernizr.standalone) {
                    var route = localStorageService.get('app.route');
                    if (angular.isUndefined(route)) {
                        localStorageService.set('app.route', $location.path());
                    }
                    else {
                        $location.path(route);
                    }
                }
                else {
                    $route.reload();
                }
            }

            if (!ConfigService.isAuthorized() && path != '/login') {
                event.preventDefault();
                VkService.asyncGetLoginStatus().then(function (id) {
                    $log.debug('User is authorized, change location path to ', path);
                    UserService.asyncUpdateInfo(id).then(login, ErrorHandler.handle);
                }, function (error) {
                    $log.debug('User is not authorized, prevent location change ', path);
                    $location.path('/login');
                });
            }
    });
}]);<commit_msg>Bug fixes.<commit_after>var spacebox = angular.module('spacebox',
    [ 'ngAnimate', 'ngRoute', 'ngResource', 'ngTouch', 'ngCookies', 'angular-carousel', 'angularMoment', 'LocalStorageModule', 'ui.bootstrap.modal', 'ui.bootstrap.tpls']);

spacebox.config(['config', '$routeProvider', '$logProvider', '$compileProvider',
    function (config, $routeProvider, $logProvider, $compileProvider) {
        $routeProvider.
            when('/login', {
                templateUrl: 'src/js/app/templates/views/login.html',
                controller: 'LoginViewController'
            }).
            when('/', {
                templateUrl: 'src/js/app/templates/views/users.html',
                controller: 'UsersViewController',
                controllerAs: 'main'
            }).
            when('/friends', {
                templateUrl: 'src/js/app/templates/views/friends.html',
                controller: 'FriendsViewController',
                controllerAs: 'friends'
            }).
            when('/error', {
                templateUrl: 'src/js/app/templates/views/error.html',
                controller: 'ErrorViewController'
            }).
            when('/properties', {
                templateUrl: 'src/js/app/templates/views/properties.html',
                controller: 'PropertiesViewController'
            }).
            otherwise({
                redirectTo: '/login'
            });

        if (!angular.equals(config.DEVELOPMENT, true)) {
            $compileProvider.debugInfoEnabled(false);
            $logProvider.debugEnabled(false);
        }
    }]);

spacebox.run(['$rootScope', '$location', '$log', '$route', 'VkService', 'ConfigService', 'UserService', 'ErrorHandler', 'amMoment', 'localStorageService',
    function ($rootScope, $location, $log, $route, VkService, ConfigService, UserService, ErrorHandler, amMoment, localStorageService) {
        amMoment.changeLocale('ru');
        $rootScope.$on('$locationChangeStart', function (event) {
            var path = $location.path();

            if (Modernizr.standalone && angular.isString(path)) {
                localStorageService.set('app.route', path);
            }

            function login (info) {
                ConfigService.init(info);
                if (Modernizr.standalone) {
                    var route = localStorageService.get('app.route');
                    if (angular.isUndefined(route)) {
                        localStorageService.set('app.route', $location.path());
                    }
                    else {
                        $location.path(route);
                    }
                }

                $route.reload();
            }

            if (!ConfigService.isAuthorized() && path != '/login') {
                event.preventDefault();
                VkService.asyncGetLoginStatus().then(function (id) {
                    $log.debug('User is authorized, change location path to ', path);
                    UserService.asyncUpdateInfo(id).then(login, ErrorHandler.handle);
                }, function (error) {
                    $log.debug('User is not authorized, prevent location change ', path);
                    $location.path('/login');
                });
            }
    });
}]);<|endoftext|>


<commit_before>/*
 * debugger.io: An interactive web scripting sandbox
 *
 * locales.js: localized strings
 */

define(function(require) {
  'use strict';

  var $      = require('jquery');
  var _      = require('underscore');
  var bus    = require('bus');
  var config = require('config');
  var utils  = require('utils');

  var observers = require('observers');

  // ---

  var locales = utils.module('locales');

  var dir = '/locales';
  var cache = {};
  var sync = {};

  var prefix = '@';

  bus.init(function(av) {
    locales.console.log('init locales module');

    // localize nodes with `data-localize` attribute as added
    observers.register_listener(function(mutation) {
      var $localize = $(mutation.addedNodes).filter('[data-localize]');
      locales.localize_dom_nodes($localize);
    });

    bus.on('config:locale', function(localeStr) {
      locales.string('onbeforeunload');
      locales.localize_dom_nodes();
    });
  });

  /**
   * Load locales, extending the base locale, into cache
   *
   * @param {String | Array} - locale(s) to load
   */
  locales.load = function(ids) {
    _.each(utils.ensure_array(ids), function(id) {
      id = utils.sanitize_resource_id(id);
      if (!id || cache[id]) { return; }

      var d = $.Deferred();
      cache[id] = d.promise();

      var localeUri = _.sprintf('%s/%s.json', dir, id);
      if (!config.prod) { localeUri += '?v=' + (new Date()).getTime(); }

      $.getJSON(localeUri).done(function(locale, status, xhr) {
        if (id !== config.base_locale) {
          locales.get(config.base_locale).done(function(baseLocale) {
            d.resolve(_.extend(baseLocale, locale));
          }).fail(d.reject);
        } else {
          d.resolve(locale);
        }
      }).fail(function(xhr, status, err) {
        d.reject(err);
      });
    });
  };

  /**
   * Make sure a locale is loaded (either from cache or the server),
   * then return a promise to return extended locale
   *
   * @param {String} id - locale id
   * @return {Promise} promise to return the extended locale
   */
  locales.get = function(id) {
    id = utils.sanitize_resource_id(id);
    locales.load(id);
    var d = $.Deferred();

    cache[id].done(function(locale) {
      d.resolve(utils.clone(locale));
    }).fail(d.reject);

    return d.promise();
  };

  /**
   * Flush the entire locale cache, forcing the next call to locales.load or
   * locales.get to fetch a fresh version of the locale
   */
  locales.flush = function() {
    cache = {};
  };

  /**
   * Returned a localized string from a string ID
   *
   * @param {String} strId - a string ID
   * @param {String} [...] - strings to pass to _.sprintf, if applicable
   * @return {Promise} to return localed string matching `strId`
   */
  locales.string = function(strId) {
    var d = $.Deferred();

    var args = _.rest(arguments);

    locales.get(config.locale).done(function(locale) {
      var str = (locale.strings && strId) ? locale.strings[strId] : null;
      if (!str) { return d.resolve(null); }

      // count the number of sprintf placeholders are present
      var sprintfMatches = str.match(/\%s/g);
      var sprintfCount = sprintfMatches ? sprintfMatches.length : 0;

      // an array of the same length, with missing values set to an empty string
      var sprintfArgs = _.map((new Array(sprintfCount)), function(val, i) {
        var arg = args[i];
        return (arg || (arg === 0)) ? arg : '';
      });

      sprintfArgs.unshift(str);
      var formattedStr = _.sprintf.apply(null, sprintfArgs);
      sync[strId] = formattedStr; // sprintfArgs are not cached
      d.resolve(formattedStr);
    }).fail(function(err) {
      d.reject(null);
    });

    return d.promise();
  };

  /**
   * Returns a promsie to localize a string if a leading prefix is found
   *
   * @param {Mixed}
   * @return {Promise|String}
   */
  locales.prefixed = function(val) {
    return (_.isString(val) && !val.indexOf(prefix)) ?
      locales.string(_.strRight(val, prefix)) : val;
  };

  /**
   * Localize DOM nodes with `data-localize` attribute
   *
   * @param {jQuery} [$localize] - set of nodes to localize
   * @return {Promise} to resolve upon completion
   */
  locales.localize_dom_nodes = function($localize) {
    var d = $.Deferred();
    $localize = $localize || $('[data-localize]');

    locales.get(config.locale).done(function(locale) {
      $localize.each(function() {
        // get the locale string ID
        var localize = $(this).attr('data-localize');

        // replace the first text node with the localized string, if present
        $(this).contents().filter(function() { return this.nodeType === 3; })
          .first().each(function() {
            var that = this;
            locales.string(localize).done(function(localizedValue) {
              if (localizedValue) { that.nodeValue = localizedValue; }
            });
          });
      });

      d.resolve(true);
    }).fail(d.reject)

    return d.promise();
  };

  /**
   * Return a synchronous value from existing cache
   *
   * @param {String} strId - a string ID
   * @return {String} Localed string matching `strId`
   */
  locales.sync = function(strId) {
    return sync[strId];
  };

  return locales;
});
<commit_msg>Fix comment typo<commit_after>/*
 * debugger.io: An interactive web scripting sandbox
 *
 * locales.js: localized strings
 */

define(function(require) {
  'use strict';

  var $      = require('jquery');
  var _      = require('underscore');
  var bus    = require('bus');
  var config = require('config');
  var utils  = require('utils');

  var observers = require('observers');

  // ---

  var locales = utils.module('locales');

  var dir = '/locales';
  var cache = {};
  var sync = {};

  var prefix = '@';

  bus.init(function(av) {
    locales.console.log('init locales module');

    // localize nodes with `data-localize` attribute as added
    observers.register_listener(function(mutation) {
      var $localize = $(mutation.addedNodes).filter('[data-localize]');
      locales.localize_dom_nodes($localize);
    });

    bus.on('config:locale', function(localeStr) {
      locales.string('onbeforeunload');
      locales.localize_dom_nodes();
    });
  });

  /**
   * Load locales, extending the base locale, into cache
   *
   * @param {String | Array} - locale(s) to load
   */
  locales.load = function(ids) {
    _.each(utils.ensure_array(ids), function(id) {
      id = utils.sanitize_resource_id(id);
      if (!id || cache[id]) { return; }

      var d = $.Deferred();
      cache[id] = d.promise();

      var localeUri = _.sprintf('%s/%s.json', dir, id);
      if (!config.prod) { localeUri += '?v=' + (new Date()).getTime(); }

      $.getJSON(localeUri).done(function(locale, status, xhr) {
        if (id !== config.base_locale) {
          locales.get(config.base_locale).done(function(baseLocale) {
            d.resolve(_.extend(baseLocale, locale));
          }).fail(d.reject);
        } else {
          d.resolve(locale);
        }
      }).fail(function(xhr, status, err) {
        d.reject(err);
      });
    });
  };

  /**
   * Make sure a locale is loaded (either from cache or the server),
   * then return a promise to return extended locale
   *
   * @param {String} id - locale id
   * @return {Promise} promise to return the extended locale
   */
  locales.get = function(id) {
    id = utils.sanitize_resource_id(id);
    locales.load(id);
    var d = $.Deferred();

    cache[id].done(function(locale) {
      d.resolve(utils.clone(locale));
    }).fail(d.reject);

    return d.promise();
  };

  /**
   * Flush the entire locale cache, forcing the next call to locales.load or
   * locales.get to fetch a fresh version of the locale
   */
  locales.flush = function() {
    cache = {};
  };

  /**
   * Returned a localized string from a string ID
   *
   * @param {String} strId - a string ID
   * @param {String} [...] - strings to pass to _.sprintf, if applicable
   * @return {Promise} to return localed string matching `strId`
   */
  locales.string = function(strId) {
    var d = $.Deferred();

    var args = _.rest(arguments);

    locales.get(config.locale).done(function(locale) {
      var str = (locale.strings && strId) ? locale.strings[strId] : null;
      if (!str) { return d.resolve(null); }

      // count the number of sprintf placeholders are present
      var sprintfMatches = str.match(/\%s/g);
      var sprintfCount = sprintfMatches ? sprintfMatches.length : 0;

      // an array of the same length, with missing values set to an empty string
      var sprintfArgs = _.map((new Array(sprintfCount)), function(val, i) {
        var arg = args[i];
        return (arg || (arg === 0)) ? arg : '';
      });

      sprintfArgs.unshift(str);
      var formattedStr = _.sprintf.apply(null, sprintfArgs);
      sync[strId] = formattedStr; // sprintfArgs are not cached
      d.resolve(formattedStr);
    }).fail(function(err) {
      d.reject(null);
    });

    return d.promise();
  };

  /**
   * Returns a promise to localize a string if a leading prefix is found
   *
   * @param {Mixed}
   * @return {Promise|String}
   */
  locales.prefixed = function(val) {
    return (_.isString(val) && !val.indexOf(prefix)) ?
      locales.string(_.strRight(val, prefix)) : val;
  };

  /**
   * Localize DOM nodes with `data-localize` attribute
   *
   * @param {jQuery} [$localize] - set of nodes to localize
   * @return {Promise} to resolve upon completion
   */
  locales.localize_dom_nodes = function($localize) {
    var d = $.Deferred();
    $localize = $localize || $('[data-localize]');

    locales.get(config.locale).done(function(locale) {
      $localize.each(function() {
        // get the locale string ID
        var localize = $(this).attr('data-localize');

        // replace the first text node with the localized string, if present
        $(this).contents().filter(function() { return this.nodeType === 3; })
          .first().each(function() {
            var that = this;
            locales.string(localize).done(function(localizedValue) {
              if (localizedValue) { that.nodeValue = localizedValue; }
            });
          });
      });

      d.resolve(true);
    }).fail(d.reject)

    return d.promise();
  };

  /**
   * Return a synchronous value from existing cache
   *
   * @param {String} strId - a string ID
   * @return {String} Localed string matching `strId`
   */
  locales.sync = function(strId) {
    return sync[strId];
  };

  return locales;
});
<|endoftext|>


<commit_before>const baseConfig = require('tdd-buffet/config/jest.config');
const path = require('path');
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('../tsconfig');

const rootDir = path.join(__dirname, '../');

module.exports = {
  ...baseConfig,

  rootDir,
  // For some reason Jest will complain that this is duplicating the packages/mugshot/package.json.
  modulePathIgnorePatterns: ['<rootDir>/package.json'],
  moduleNameMapper: {
    ...pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/packages/' }),
    // For some reason the ts-jest helper doesn't pick this one up.
    '^mugshot/(.*)$': '<rootDir>/packages/mugshot/$1'
  },

  // We're doing multiple coverage runs so we don't want to print the table every time
  // and we want to check thresholds once at the end with nyc.
  coverageReporters: ['json', 'html'],
  coverageThreshold: undefined
};
<commit_msg>Remove jest config duplication<commit_after>const baseConfig = require('tdd-buffet/config/jest.config');

module.exports = {
  ...baseConfig,

  // For some reason Jest will complain that this is duplicating the packages/mugshot/package.json.
  modulePathIgnorePatterns: ['<rootDir>/package.json'],
  moduleNameMapper: {
    ...baseConfig.moduleNameMapper,
    // For some reason the ts-jest helper doesn't pick this one up.
    '^mugshot/(.*)$': '<rootDir>/packages/mugshot/$1'
  },

  // We're doing multiple coverage runs so we don't want to print the table every time
  // and we want to check thresholds once at the end with nyc.
  coverageReporters: ['json', 'html'],
  coverageThreshold: undefined
};
<|endoftext|>


<commit_before>/* eslint-disable no-console, global-require */
import { readFile } from 'fs-extra';
import React from 'react';
import { combineReducers } from 'redux';
import { renderToString } from 'react-dom/server';
import { extractCritical } from 'emotion-server';
import { flushChunkNames } from 'react-universal-component/server';
import flushChunks from 'webpack-flush-chunks';
import { mapValues } from 'lodash';
import { addPackage } from 'worona-deps';
import { Helmet } from 'react-helmet';
import { buildPath } from '../../../.build/pwa/buildInfo.json'; // eslint-disable-line
import buildModule from '../packages/build';
import settingsModule from '../packages/settings';
import App from '../shared/components/App';
import initStore from '../shared/store';
import reducers from '../shared/store/reducers';
import serverSagas from './sagas';
import { getSettings } from './settings';
import { requireModules } from './requires';

const dev = process.env.NODE_ENV !== 'production';

addPackage({ namespace: 'build', module: buildModule });
addPackage({ namespace: 'settings', module: settingsModule });

export default ({ clientStats }) => async (req, res) => {
  const { siteId } = req.query;
  const env = req.query.env === 'prod' ? 'prod' : 'pre';

  let app;
  try {
    if (!siteId) throw new Error("'?siteid=' query not found.");

    // Get settings.
    const settings = await getSettings({ siteId, env });
    if (!settings)
      throw new Error(`Settings for ${siteId} not found in the ${env.toUpperCase()} database.`);

    // Extract activated packages array from settings.
    const activatedPackages = settings
      ? Object.values(settings)
          .filter(pkg => pkg.woronaInfo.namespace !== 'generalSite')
          .filter(pkg => pkg.woronaInfo.namespace !== 'generalApp')
          .reduce((obj, pkg) => ({ ...obj, [pkg.woronaInfo.namespace]: pkg.woronaInfo.name }), {})
      : {};

    // Load the modules.
    const pkgModules = await requireModules(Object.entries(activatedPackages));

    // Load reducers and sagas.
    let connection = null;
    const stores = {};
    pkgModules.forEach(pkg => {
      if (pkg.namespace === 'connection') connection = pkg.module;
      if (pkg.module.Store) pkg.module.store = pkg.module.Store.create({});
      if (pkg.module.store) stores[pkg.namespace] = pkg.module.store;
      if (pkg.module.reducers) reducers[pkg.namespace] = pkg.module.reducers(pkg.module.store);
      if (pkg.serverSaga) serverSagas[pkg.name] = pkg.serverSaga;
      addPackage({ namespace: pkg.namespace, module: pkg.module });
    });
    if (!connection) throw new Error("At least one 'connection' package must be active.");

    // Init redux store.
    const store = initStore({ reducer: combineReducers(reducers) });

    // Add settings to the state.
    store.dispatch(buildModule.actions.serverStarted());
    store.dispatch(
      buildModule.actions.buildUpdated({
        siteId,
        env,
        packages: activatedPackages,
      }),
    );
    store.dispatch(settingsModule.actions.settingsUpdated({ settings }));

    // Run and wait until all the server sagas have run.
    const startSagas = new Date();
    const sagaPromises = Object.values(serverSagas).map(saga => store.runSaga(saga).done);
    store.dispatch(buildModule.actions.serverSagasInitialized());
    store.dispatch(connection.actions.routeChangeSucceed({ selected: { listType: 'latest' } }));
    await Promise.all(sagaPromises);
    store.dispatch(buildModule.actions.serverFinished({ timeToRunSagas: new Date() - startSagas }));

    // Generate React SSR.
    app = renderToString(
      <App store={store} packages={Object.values(activatedPackages)} stores={stores} />,
    );

    const { html, ids, css } = extractCritical(app);

    // Get static helmet strings.
    const helmet = Helmet.renderStatic();

    // Flush chunk names and extract scripts, css and css<->scripts object.
    const chunkNames = flushChunkNames();
    const { cssHashRaw, scripts, stylesheets } = flushChunks(clientStats, { chunkNames });

    const publicPath = req.query.static
      ? `${req.query.static.replace(/\/$/g, '')}/static/`
      : '/static/';
    const cssHash = JSON.stringify(mapValues(cssHashRaw, cssPath => `${publicPath}${cssPath}`));
    const scriptsWithoutBootstrap = scripts.filter(script => !/bootstrap/.test(script));
    const chunksForArray = scriptsWithoutBootstrap.map(script => `'${script}'`).join(',');
    const bootstrapFileName = scripts.filter(script => /bootstrap/.test(script));
    const bootstrapString = await readFile(
      `${buildPath}/.build/pwa/client/${bootstrapFileName}`,
      'utf8',
    );
    const preloadScripts = scriptsWithoutBootstrap
      .map(script => `<link rel="preload" href="${publicPath}${script}" as="script">`)
      .join('\n');
    const styles = stylesheets
      .map(
        stylesheet =>
          `<link rel="stylesheet" charset="utf-8" type="text/css" href="${publicPath}${
            stylesheet
          }" />`,
      )
      .join('\n');

    console.log('PATH', req.path);
    console.log('DYNAMIC CHUNK NAMES RENDERED', chunkNames);
    console.log('SCRIPTS SERVED', scripts);
    console.log('STYLESHEETS SERVED', stylesheets);

    res.send(
      `<!doctype html>

            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
            ${styles}
            ${preloadScripts}
            ${helmet.title.toString()}
            ${helmet.meta.toString()}
            ${helmet.link.toString()}

${html}

        `,
    );
  } catch (error) {
    console.error(error);
    res.status(500);
    if (dev) {
      const RedBox = require('redbox-react').RedBoxError;
      app = renderToString(<RedBox error={error} />);
    } else {
      app = `<div>${error.message}</div>`;
    }
    res.send(
      `<!doctype html>

            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

            ${app}

        `,
    );
  }
};
<commit_msg>Don't dispatch the route change automatically<commit_after>/* eslint-disable no-console, global-require */
import { readFile } from 'fs-extra';
import React from 'react';
import { combineReducers } from 'redux';
import { renderToString } from 'react-dom/server';
import { extractCritical } from 'emotion-server';
import { flushChunkNames } from 'react-universal-component/server';
import flushChunks from 'webpack-flush-chunks';
import { mapValues } from 'lodash';
import { addPackage } from 'worona-deps';
import { Helmet } from 'react-helmet';
import { buildPath } from '../../../.build/pwa/buildInfo.json'; // eslint-disable-line
import buildModule from '../packages/build';
import settingsModule from '../packages/settings';
import App from '../shared/components/App';
import initStore from '../shared/store';
import reducers from '../shared/store/reducers';
import serverSagas from './sagas';
import { getSettings } from './settings';
import { requireModules } from './requires';

const dev = process.env.NODE_ENV !== 'production';

addPackage({ namespace: 'build', module: buildModule });
addPackage({ namespace: 'settings', module: settingsModule });

export default ({ clientStats }) => async (req, res) => {
  const { siteId } = req.query;
  const env = req.query.env === 'prod' ? 'prod' : 'pre';

  let app;
  try {
    if (!siteId) throw new Error("'?siteid=' query not found.");

    // Get settings.
    const settings = await getSettings({ siteId, env });
    if (!settings)
      throw new Error(`Settings for ${siteId} not found in the ${env.toUpperCase()} database.`);

    // Extract activated packages array from settings.
    const activatedPackages = settings
      ? Object.values(settings)
          .filter(pkg => pkg.woronaInfo.namespace !== 'generalSite')
          .filter(pkg => pkg.woronaInfo.namespace !== 'generalApp')
          .reduce((obj, pkg) => ({ ...obj, [pkg.woronaInfo.namespace]: pkg.woronaInfo.name }), {})
      : {};

    // Load the modules.
    const pkgModules = await requireModules(Object.entries(activatedPackages));

    // Load reducers and sagas.
    const stores = {};
    pkgModules.forEach(pkg => {
      if (pkg.module.Store) pkg.module.store = pkg.module.Store.create({});
      if (pkg.module.store) stores[pkg.namespace] = pkg.module.store;
      if (pkg.module.reducers) reducers[pkg.namespace] = pkg.module.reducers(pkg.module.store);
      if (pkg.serverSaga) serverSagas[pkg.name] = pkg.serverSaga;
      addPackage({ namespace: pkg.namespace, module: pkg.module });
    });

    // Init redux store.
    const store = initStore({ reducer: combineReducers(reducers) });

    // Add settings to the state.
    store.dispatch(buildModule.actions.serverStarted());
    store.dispatch(
      buildModule.actions.buildUpdated({
        siteId,
        env,
        packages: activatedPackages,
      }),
    );
    store.dispatch(settingsModule.actions.settingsUpdated({ settings }));

    // Run and wait until all the server sagas have run.
    const startSagas = new Date();
    const sagaPromises = Object.values(serverSagas).map(saga => store.runSaga(saga).done);
    store.dispatch(buildModule.actions.serverSagasInitialized());
    await Promise.all(sagaPromises);
    store.dispatch(buildModule.actions.serverFinished({ timeToRunSagas: new Date() - startSagas }));

    // Generate React SSR.
    app = renderToString(
      <App store={store} packages={Object.values(activatedPackages)} stores={stores} />,
    );

    const { html, ids, css } = extractCritical(app);

    // Get static helmet strings.
    const helmet = Helmet.renderStatic();

    // Flush chunk names and extract scripts, css and css<->scripts object.
    const chunkNames = flushChunkNames();
    const { cssHashRaw, scripts, stylesheets } = flushChunks(clientStats, { chunkNames });

    const publicPath = req.query.static
      ? `${req.query.static.replace(/\/$/g, '')}/static/`
      : '/static/';
    const cssHash = JSON.stringify(mapValues(cssHashRaw, cssPath => `${publicPath}${cssPath}`));
    const scriptsWithoutBootstrap = scripts.filter(script => !/bootstrap/.test(script));
    const chunksForArray = scriptsWithoutBootstrap.map(script => `'${script}'`).join(',');
    const bootstrapFileName = scripts.filter(script => /bootstrap/.test(script));
    const bootstrapString = await readFile(
      `${buildPath}/.build/pwa/client/${bootstrapFileName}`,
      'utf8',
    );
    const preloadScripts = scriptsWithoutBootstrap
      .map(script => `<link rel="preload" href="${publicPath}${script}" as="script">`)
      .join('\n');
    const styles = stylesheets
      .map(
        stylesheet =>
          `<link rel="stylesheet" charset="utf-8" type="text/css" href="${publicPath}${
            stylesheet
          }" />`,
      )
      .join('\n');

    console.log('PATH', req.path);
    console.log('DYNAMIC CHUNK NAMES RENDERED', chunkNames);
    console.log('SCRIPTS SERVED', scripts);
    console.log('STYLESHEETS SERVED', stylesheets);

    res.send(
      `<!doctype html>

            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
            ${styles}
            ${preloadScripts}
            ${helmet.title.toString()}
            ${helmet.meta.toString()}
            ${helmet.link.toString()}

${html}

        `,
    );
  } catch (error) {
    console.error(error);
    res.status(500);
    if (dev) {
      const RedBox = require('redbox-react').RedBoxError;
      app = renderToString(<RedBox error={error} />);
    } else {
      app = `<div>${error.message}</div>`;
    }
    res.send(
      `<!doctype html>

            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

            ${app}

        `,
    );
  }
};
<|endoftext|>


<commit_before>export * from './js/Runtime.js';
export * from './js/core/Arc.js';
export * from './js/core/Host.js';
export * from './js/core/Decorator.js';
export * from './js/recipe/Chef.js';
export * from './js/isolation/ses.js';
export * as utils from './js/utils/utils.js';
export {logFactory} from './js/utils/utils.js';
<commit_msg>remove arcs.js<commit_after><|endoftext|>


<commit_before>"use strict";

const util = require('util');

class CommandManager {
  constructor(container) {
    this.container = container;

    this.bot = null;
    this.logger = container.get('logger');

    this._commands = {};
    this._listeners = new Map();
    this._prefix = null;
  }

  botReady() {
    this.bot = this.container.get('bot');
  }

  setPrefix(prefix) {
    this._prefix = prefix;
  }

  add(mod, cmd, func, withNoPrefix) {
    if (withNoPrefix) {
      this._listeners.set(cmd, func);
    } else {
      this._commands[cmd] = func;
    }
  }

  handleCommands(msg, errCb) {
    const content = msg.content.trim();

    if (!content.startsWith(this._prefix)) {
      return false;
    }

    this.logger.debug(`handling ${content}`);

    const fullCmd = content.slice(this._prefix.length);
    const args = fullCmd.split(' ').filter(x => x.length);
    const name = args[0].toLowerCase();

    this.logger.debug(`args: ${args}`);

    const func = this._commands[name];
    if (func) {
      this.logger.debug(`found registered command for ${name}`);

      let res = null;
      try {
        res = func(msg, args.slice(1));
      } catch (err) {
        errCb(err);
      }

      return res;
    }

    return false;
  }

  handleListeners(msg, errCb) {
    const content = msg.content.trim();

    this.logger.debug(`Handling ${util.format(content)}`);

    for (const arr of this._listeners) {
      const cmd = arr[0];
      const func = arr[1];
      const contentMatches = cmd.test(content);

      if (contentMatches) {
        this.logger.debug(`${cmd} matches content`);

        try {
          func(msg);
        } catch (err) {
          errCb(err);
        }
      }
    }
  }

  handle(msg, errCb) {
    if (msg.author.id === this.bot.client.User.id) {
      return false;
    }

    this.handleListeners(msg, errCb);
    return this.handleCommands(msg, errCb);
  }
}

module.exports = CommandManager;
<commit_msg>CommandManager: handle promises returned from command handlers<commit_after>"use strict";

const util = require('util');

class CommandManager {
  constructor(container) {
    this.container = container;

    this.bot = null;
    this.logger = container.get('logger');

    this._commands = {};
    this._listeners = new Map();
    this._prefix = null;
  }

  botReady() {
    this.bot = this.container.get('bot');
  }

  setPrefix(prefix) {
    this._prefix = prefix;
  }

  add(mod, cmd, func, withNoPrefix) {
    if (withNoPrefix) {
      this._listeners.set(cmd, func);
    } else {
      this._commands[cmd] = func;
    }
  }

  handleCommands(msg, errCb) {
    const content = msg.content.trim();

    if (!content.startsWith(this._prefix)) {
      return false;
    }

    this.logger.debug(`handling ${content}`);

    const fullCmd = content.slice(this._prefix.length);
    const args = fullCmd.split(' ').filter(x => x.length);
    const name = args[0].toLowerCase();

    this.logger.debug(`args: ${args}`);

    const func = this._commands[name];
    if (func) {
      this.logger.debug(`found registered command for ${name}`);

      let res = null;
      try {
        res = func(msg, args.slice(1));
      } catch (err) {
        errCb(err);
      }

      const promise = Promise.resolve(res).then((ret) => {
        this.logger.debug(`${name} ret ${ret}`);
      }).catch((err) => {
        this.logger.error(`${name} threw error ${err.stack}`);
        errCb(err);
      });

      return promise;
    }

    return Promise.reject(new Error('no command match found'));
  }

  handleListeners(msg, errCb) {
    const content = msg.content.trim();

    this.logger.debug(`Handling ${util.format(content)}`);

    for (const arr of this._listeners) {
      const cmd = arr[0];
      const func = arr[1];
      const contentMatches = cmd.test(content);

      if (contentMatches) {
        this.logger.debug(`${cmd} matches content`);

        let res = null;
        try {
          res = Promise.resolve(func(msg)).then((ret) => {
            this.logger.debug(`${cmd} ret ${ret}`);
          }).catch((err) => {
            this.logger.error(`${cmd} threw error ${err.stack}`);
            errCb(err);
          });
        } catch (err) {
          return errCb(err);
        }
      }
    }
  }

  handle(msg, errCb) {
    if (msg.author.id === this.bot.client.User.id) {
      return false;
    }

    this.handleListeners(msg, errCb);
    return this.handleCommands(msg, errCb);
  }
}

module.exports = CommandManager;
<|endoftext|>


<commit_before>var fs = require('fs');
var settings = require('./settings');
var http = require('http');
var util = require('./util');

//var CLOUDPATH = "/Users/josh/projects/ArduinoZips";
var CLOUDPATH = 'http://joshondesign.com/p/apps/electron/platforms';
var VERSION = "1.0.5";

console.log("os = ",process.platform);

function Platform() {
    this.os = process.platform;

    this.useSerial = function() {
        return true;
    }
    this.getUserHome = function() {
        return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
    }

    this.getReposPath = function() {
        if(this.os == 'darwin') {
            return this.getUserHome() + '/Library/ElectronIDE/downloads';
        }
        return this.getUserHome() + '/ElectronIDE/downloads';
    }

    this.getUserSketchesDir = function() {
        if(settings.usersketches) return settings.usersketches;

        if(this.os == 'darwin') {
            return this.getUserHome()+'/Documents/Arduino';
        }
        if(this.os == 'win32') {
            return this.getUserHome()+'/My Documents/Arduino';
        }
        return this.getUserHome() + '/Sketchbook';
    }

    this.getUserLibraryDir = function() {
        return this.getUserSketchesDir() + '/libraries';
    }

    this.root = this.getReposPath() + '/platforms/1.0.5/'+this.os;
    //console.log("root should be ", this.root);

    this.getStandardLibraryPath = function() {
        return this.root + '/libraries';
    }
    this.getCorePath = function(device) {
        return this.root + '/hardware/arduino/cores/'+device.build.core;
    }
    this.getVariantPath = function(device) {
        return this.root + '/hardware/arduino/variants/'+device.build.variant;
    }
    this.getCompilerBinaryPath = function(device) {
        return this.root + '/hardware/tools/avr/bin';
    }
    this.getAvrDudeBinary = function(device) {
        if(this.os == 'linux') {
            return this.root + '/hardware/tools/avrdude';
        }
        return this.root + '/hardware/tools/avr/bin/avrdude';
    }
    this.getAvrDudeConf = function(device) {
        if(this.os == 'linux') {
            return this.root + '/hardware/tools/avrdude.conf';
        }
        return this.root + '/hardware/tools/avr/etc/avrdude.conf';
    }
    this.isInstalled = function() {
        return fs.existsSync(this.root);
    }

    this.installIfNeeded = function(cb,update) {
        if(this.isInstalled()) {
            cb();
            return;
        }
        var zippath = CLOUDPATH+'/'+VERSION+'/arduino-'+VERSION+'-'+this.os+'-trimmed.tar.gz';
        util.downloadUntgzTo(zippath,this.root,update, cb);
    }
}
var _default = new Platform();
var _digispark_pro = new Platform();
_digispark_pro.droot = "/Users/josh/projects/Digistump/hardware/digistump/avr";
_digispark_pro.getStandardLibraryPath = function() {   return this.droot + '/libraries';  }
_digispark_pro.getCorePath = function(device) { return this.droot + '/cores/'+device.build.core;   }
_digispark_pro.getVariantPath = function(device) { return this.droot + '/variants/'+device.build.core;   }
_digispark_pro.getAvrDudeBinary = function(device) { return this.droot + '/tools/avrdude'; }
_digispark_pro.parentPlatform = _default;

var _trinket3 = new Platform();
_trinket3.id = 'trinket3';
_trinket3.hroot = _trinket3.getReposPath() + '/hardware/'+_trinket3.id;

_trinket3.parentPlatform = _default;
_trinket3.getVariantPath = function(device) {   return this.hroot + '/hardware/attiny/variants/' + device.build.variant;  }
_trinket3.isInstalled = function() { return fs.existsSync(this.hroot);  }

_trinket3.installIfNeeded = function(cb,update) {
    var self = this;
    this.parentPlatform.installIfNeeded(function() {
        if(self.isInstalled()) {
            cb();
            return;
        }
        var zippath = 'http://learn.adafruit.com/system/assets/assets/000/010/777/original/trinkethardwaresupport.zip?1378321062';
        var path = self.hroot;
        util.downloadUnzipTo(zippath,path,update, function() {
            var confpath = 'http://learn.adafruit.com/system/assets/assets/000/010/980/original/avrdudeconfmac.zip?1379342581';
            util.downloadUnzipTo(confpath,path, update, cb);
        });
    },update);
}
_trinket3.useSerial = function() { return false; }
_trinket3.getAvrDudeConf = function(device) { return this.hroot + '/avrdude.conf'; }
_trinket3.getProgrammerId = function() { return 'usbtiny'; }

exports.getDefaultPlatform = function() {
    return _default;
}

exports.getPlatform = function(device) {
    if(device.id == 'digispark-pro') return _digispark_pro;
    if(device.id == 'digispark') return _digispark_pro;
    if(device.id == 'trinket3') return _trinket3;
    if(device.id == 'trinket5') return _trinket3;
    if(device.id == 'gemma') return _trinket3;
    return _default;
}
<commit_msg>more digispark fixes<commit_after>var fs = require('fs');
var settings = require('./settings');
var http = require('http');
var util = require('./util');

//var CLOUDPATH = "/Users/josh/projects/ArduinoZips";
var CLOUDPATH = 'http://joshondesign.com/p/apps/electron/platforms';
var VERSION = "1.0.5";

console.log("os = ",process.platform);

function Platform() {
    this.os = process.platform;

    this.useSerial = function() {
        return true;
    }
    this.getUserHome = function() {
        return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
    }

    this.getReposPath = function() {
        if(this.os == 'darwin') {
            return this.getUserHome() + '/Library/ElectronIDE/downloads';
        }
        return this.getUserHome() + '/ElectronIDE/downloads';
    }

    this.getUserSketchesDir = function() {
        if(settings.usersketches) return settings.usersketches;

        if(this.os == 'darwin') {
            return this.getUserHome()+'/Documents/Arduino';
        }
        if(this.os == 'win32') {
            return this.getUserHome()+'/My Documents/Arduino';
        }
        return this.getUserHome() + '/Sketchbook';
    }

    this.getUserLibraryDir = function() {
        return this.getUserSketchesDir() + '/libraries';
    }

    this.root = this.getReposPath() + '/platforms/1.0.5/'+this.os;
    //console.log("root should be ", this.root);

    this.getStandardLibraryPath = function() {
        return this.root + '/libraries';
    }
    this.getCorePath = function(device) {
        return this.root + '/hardware/arduino/cores/'+device.build.core;
    }
    this.getVariantPath = function(device) {
        return this.root + '/hardware/arduino/variants/'+device.build.variant;
    }
    this.getCompilerBinaryPath = function(device) {
        return this.root + '/hardware/tools/avr/bin';
    }
    this.getAvrDudeBinary = function(device) {
        if(this.os == 'linux') {
            return this.root + '/hardware/tools/avrdude';
        }
        return this.root + '/hardware/tools/avr/bin/avrdude';
    }
    this.getAvrDudeConf = function(device) {
        if(this.os == 'linux') {
            return this.root + '/hardware/tools/avrdude.conf';
        }
        return this.root + '/hardware/tools/avr/etc/avrdude.conf';
    }
    this.isInstalled = function() {
        return fs.existsSync(this.root);
    }

    this.installIfNeeded = function(cb,update) {
        if(this.isInstalled()) {
            cb();
            return;
        }
        var zippath = CLOUDPATH+'/'+VERSION+'/arduino-'+VERSION+'-'+this.os+'-trimmed.tar.gz';
        util.downloadUntgzTo(zippath,this.root,update, cb);
    }
}
var _default = new Platform();
var _digispark_pro = new Platform();
_digispark_pro.id = 'digispark';
var digifix = '/Digistump/hardware/digistump/avr'
_digispark_pro.droot = _digispark_pro.getReposPath() + '/hardware/'+_digispark_pro.id;
_digispark_pro.getStandardLibraryPath = function() {   return this.droot + digifix +'/libraries';  }
_digispark_pro.getCorePath = function(device) { return this.droot + digifix + '/cores/'+device.build.core;   }
_digispark_pro.getVariantPath = function(device) { return this.droot + digifix+ '/variants/'+device.build.core;   }
_digispark_pro.getAvrDudeBinary = function(device) { return this.droot + digifix+ '/tools/avrdude'; }
_digispark_pro.parentPlatform = _default;
_digispark_pro.isInstalled = function() { return fs.existsSync(this.droot);  }
_digispark_pro.installIfNeeded = function(cb,update) {
    var self = this;
    this.parentPlatform.installIfNeeded(function() {
        if(self.isInstalled()) {
            cb();
            return;
        }
        var zippath = 'unknown path';
        if(self.os == 'darwin') {
            zippath = 'http://digispark.s3.amazonaws.com/digisparkpro_mac.zip';
        }
        if(self.os == 'linux') {
            zippath = 'http://digispark.s3.amazonaws.com/digisparkpro_linux.zip';
        }
        if(self.os == 'win32') {
            zippath = 'http://sourceforge.net/projects/digistump/files/Digistump1.5Addons-v09.zip/download';
        }
        var path = self.droot;
        util.downloadUnzipTo(zippath,path,update, cb);
    },update);
}

var _trinket3 = new Platform();
_trinket3.id = 'trinket3';
_trinket3.hroot = _trinket3.getReposPath() + '/hardware/'+_trinket3.id;

_trinket3.parentPlatform = _default;
_trinket3.getVariantPath = function(device) {   return this.hroot + '/hardware/attiny/variants/' + device.build.variant;  }
_trinket3.isInstalled = function() { return fs.existsSync(this.hroot);  }

_trinket3.installIfNeeded = function(cb,update) {
    var self = this;
    this.parentPlatform.installIfNeeded(function() {
        if(self.isInstalled()) {
            cb();
            return;
        }
        var zippath = 'http://learn.adafruit.com/system/assets/assets/000/010/777/original/trinkethardwaresupport.zip?1378321062';
        var path = self.hroot;
        util.downloadUnzipTo(zippath,path,update, function() {
            var confpath = 'http://learn.adafruit.com/system/assets/assets/000/010/980/original/avrdudeconfmac.zip?1379342581';
            util.downloadUnzipTo(confpath,path, update, cb);
        });
    },update);
}
_trinket3.useSerial = function() { return false; }
_trinket3.getAvrDudeConf = function(device) { return this.hroot + '/avrdude.conf'; }
_trinket3.getProgrammerId = function() { return 'usbtiny'; }

exports.getDefaultPlatform = function() {
    return _default;
}

exports.getPlatform = function(device) {
    if(device.id == 'digispark-pro') return _digispark_pro;
    if(device.id == 'digispark-tiny') return _digispark_pro;
    if(device.id == 'trinket3') return _trinket3;
    if(device.id == 'trinket5') return _trinket3;
    if(device.id == 'gemma') return _trinket3;
    return _default;
}
<|endoftext|>