<commit_before>'use strict';

angular.module('Frontend.Venta', ['ngRoute','angular-jwt','angular-storage'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/venta', {
    templateUrl: 'venta/venta.html',
    controller: 'VentaController'
  });
}])

.controller('VentaController', function($scope, store, jwtHelper, $http, backendAPIservice, $location, $window) {
    $scope.terminado=false;
    $scope.contado=true;
    $scope.cliente=1;
    $scope.base21=0.00;
    $scope.iva21=0.00;
    $scope.base10=0.00;
    $scope.iva10=0.00;
    $scope.base4=0.00;
    $scope.iva4=0.00;
    $scope.total=0.00;
    $scope.articulopr;
    $scope.respuesta;
    $scope.error;
    $scope.codigo;
    $scope.cero=0;
    $scope.prueba;
    $scope.activo;
    $scope.numventa;

    $scope.listaVenta = [];
    $scope.listaProducto = [];
    $scope.listaSocio = [];
    $scope.listaTipo = [];

    if(store.get('token')){
      var token = store.get('token');
      if(!jwtHelper.isTokenExpired(token))
      {
        backendAPIservice.getProductos().success(function (recibe) {
          var productosArray = recibe.response.productos;
          console.log(JSON.stringify(productosArray));
          $scope.listaProducto = productosArray;
          store.set('token',recibe.response.token);

        });

        backendAPIservice.getClientes().success(function (recibe) {
          var sociosArray = recibe.response.socios;
          console.log(JSON.stringify(sociosArray));
          $scope.listaSocio = sociosArray;
          store.set('token',recibe.response.token);
        });

        backendAPIservice.getTipos().success(function (recibe) {
          var tiposArray = recibe.response.tipos;
          console.log(JSON.stringify(tiposArray));
          $scope.listaTipo = tiposArray;
          store.set('token',recibe.response.token);
        });
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    }
    else
    {
      store.remove('token');
      store.set('nombre', "Sin conexion");
      $location.path("/login");
    }

    $scope.Aniadir=function(pid, pnombre, pprecio, piva)
    {
      var elemento;
      var anadido=false;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].id == pid) {
          $scope.listaVenta[elemento].cantidad = $scope.listaVenta[elemento].cantidad+1;
          anadido=true;
        }
      }
      if(anadido==false)
      {
        $scope.listaVenta.push({id:pid, nombre:pnombre, precio:pprecio, iva:piva, cantidad:1 });
      }
      $scope.Totales();
    };

    $scope.clienteElegido=function(value) {
      if($scope.cliente==1){ $scope.contado=true; }
      if (value.id==$scope.cliente){
        return true;
      } else {
        return false;
      }
    };

    $scope.Borrar=function(index) {
      $scope.listaVenta.splice(index, 1);
      $scope.Totales();
    };

    $scope.Totales=function() {
      var elemento;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].iva=="21") {
         $scope.base21 += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva21 = ($scope.base21 * 21.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==10) {
         $scope.base10  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva10 = ($scope.base10 * 10.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==4) {
         $scope.base4  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva4 = ($scope.base4 * 4.00 )/100.00;
        };
      }
      $scope.total = $scope.base21 + $scope.iva21 + $scope.base10 + $scope.iva10 + $scope.base4 + $scope.iva4;
    };

    $scope.Finalizar=function() {
      backendAPIservice.postVenta($scope.cliente, $scope.contado, $scope.listaVenta).success(function(recibe){
        var respuesta1 = recibe.response.respuesta;
        var numventa = recibe.response.venta;
        console.log(JSON.stringify(respuesta1));
        console.log(JSON.stringify(numventa));
        $scope.respuesta = respuesta1;
        $scope.numventa = numventa;
        if(recibe.code==0) store.set('token',recibe.response.token);
        $scope.terminado=true;
      });
    };

    $scope.Continuar=function() {
      /*html2canvas(document.getElementById('imprimeesto'), {
        onrendered: function (canvas) {
          var data = canvas.toDataURL();
          var docDefinition = {
            content: [{
              image: data,
              width: 500,
            }]
          };
          pdfMake.createPdf(docDefinition).download("Score_Details.pdf");
        }
      })*/
      $scope.terminado=false;
      $scope.contado=true;
      $scope.cerrado=false;
      $scope.cliente=1;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      $scope.total=0.00;
      $scope.articulopr;
      $scope.respuesta;
      $scope.error;
      $scope.codigo;
      $scope.cero=0;
      $scope.prueba;
      $scope.activo;

      $scope.listaVenta = [];
      $scope.listaProducto = [];
      $scope.listaSocio = [];
      $scope.listaTipo = [];

      if(store.get('token')){
        var token = store.get('token');
        if(!jwtHelper.isTokenExpired(token))
        {
          backendAPIservice.getProductos().success(function (recibe) {
            var productosArray = recibe.response.productos;
            var codigo = recibe.code;
            if(codigo!=0 $scope.cerrado=true);
            console.log(JSON.stringify(productosArray));
            $scope.listaProducto = productosArray;
            store.set('token',recibe.response.token);

          });

          backendAPIservice.getClientes().success(function (recibe) {
            var sociosArray = recibe.response.socios;
            console.log(JSON.stringify(sociosArray));
            $scope.listaSocio = sociosArray;
            store.set('token',recibe.response.token);
          });

          backendAPIservice.getTipos().success(function (recibe) {
            var tiposArray = recibe.response.tipos;
            console.log(JSON.stringify(tiposArray));
            $scope.listaTipo = tiposArray;
            store.set('token',recibe.response.token);
          });
        }
        else
        {
          store.remove('token');
          store.set('nombre', "Sin conexion");
          $location.path("/login");
        }
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    };

    /*$scope.printDiv=function(divName){
      var printContents = document.getElementById(divName).innerHTML;
      var originalContents = document.body.innerHTML;
      document.body.innerHTML = printContents;
      window.print();
      document.body.innerHTML = originalContents;
    };*/

    $scope.printDiv = function(divName) {
      var printContents = document.getElementById(divName).innerHTML;
      var popupWin = window.open('', '_blank', 'width=300,height=300');
      popupWin.document.open();
      popupWin.document.write('<link rel="stylesheet" type="text/css" href="app.css" />' + printContents + '');
      popupWin.document.close();
    };

    /*$scope.printDiv = function (divName) {

      var printContents = document.getElementById(divName).innerHTML;
      var originalContents = document.body.innerHTML;

      if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
          var popupWin = window.open('', '_blank', 'width=600,height=600,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
          popupWin.window.focus();
          popupWin.document.write('<!DOCTYPE html>' +
              '<link rel="stylesheet" type="text/css" href="app.css" />' +
              '
' + printContents + '
');
          popupWin.onbeforeunload = function (event) {
              popupWin.close();
              return '.\n';
          };
          popupWin.onabort = function (event) {
              popupWin.document.close();
              popupWin.close();
          }
      } else {
          var popupWin = window.open('', '_blank', 'width=800,height=600');
          popupWin.document.open();
          popupWin.document.write('<link rel="stylesheet" type="text/css" href="app.css" />' + printContents + '');
          popupWin.document.close();
      }
      popupWin.document.close();

      return true;
    };*/

});
<commit_msg>20160905-1747<commit_after>'use strict';

angular.module('Frontend.Venta', ['ngRoute','angular-jwt','angular-storage'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/venta', {
    templateUrl: 'venta/venta.html',
    controller: 'VentaController'
  });
}])

.controller('VentaController', function($scope, store, jwtHelper, $http, backendAPIservice, $location, $window) {
    $scope.terminado=false;
    $scope.contado=true;
    $scope.cliente=1;
    $scope.base21=0.00;
    $scope.iva21=0.00;
    $scope.base10=0.00;
    $scope.iva10=0.00;
    $scope.base4=0.00;
    $scope.iva4=0.00;
    $scope.total=0.00;
    $scope.articulopr;
    $scope.respuesta;
    $scope.error;
    $scope.codigo;
    $scope.cero=0;
    $scope.prueba;
    $scope.activo;
    $scope.numventa;

    $scope.listaVenta = [];
    $scope.listaProducto = [];
    $scope.listaSocio = [];
    $scope.listaTipo = [];

    if(store.get('token')){
      var token = store.get('token');
      if(!jwtHelper.isTokenExpired(token))
      {
        backendAPIservice.getProductos().success(function (recibe) {
          var productosArray = recibe.response.productos;
          store.set('token',recibe.response.token);
          if(recibe.code!=0)
          {
            $scope.cerrado=true;
            var respuesta1 = recibe.response.respuesta;
            console.log(JSON.stringify(respuesta1));
            $scope.respuesta = respuesta1;
          }
          else
          {
            console.log(JSON.stringify(productosArray));
            $scope.listaProducto = productosArray;
          }
        });

        backendAPIservice.getClientes().success(function (recibe) {
          var sociosArray = recibe.response.socios;
          console.log(JSON.stringify(sociosArray));
          $scope.listaSocio = sociosArray;
          store.set('token',recibe.response.token);
        });

        backendAPIservice.getTipos().success(function (recibe) {
          var tiposArray = recibe.response.tipos;
          console.log(JSON.stringify(tiposArray));
          $scope.listaTipo = tiposArray;
          store.set('token',recibe.response.token);
        });
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    }
    else
    {
      store.remove('token');
      store.set('nombre', "Sin conexion");
      $location.path("/login");
    }

    $scope.Aniadir=function(pid, pnombre, pprecio, piva)
    {
      var elemento;
      var anadido=false;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].id == pid) {
          $scope.listaVenta[elemento].cantidad = $scope.listaVenta[elemento].cantidad+1;
          anadido=true;
        }
      }
      if(anadido==false)
      {
        $scope.listaVenta.push({id:pid, nombre:pnombre, precio:pprecio, iva:piva, cantidad:1 });
      }
      $scope.Totales();
    };

    $scope.clienteElegido=function(value) {
      if($scope.cliente==1){ $scope.contado=true; }
      if (value.id==$scope.cliente){
        return true;
      } else {
        return false;
      }
    };

    $scope.Borrar=function(index) {
      $scope.listaVenta.splice(index, 1);
      $scope.Totales();
    };

    $scope.Totales=function() {
      var elemento;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].iva=="21") {
         $scope.base21 += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva21 = ($scope.base21 * 21.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==10) {
         $scope.base10  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva10 = ($scope.base10 * 10.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==4) {
         $scope.base4  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva4 = ($scope.base4 * 4.00 )/100.00;
        };
      }
      $scope.total = $scope.base21 + $scope.iva21 + $scope.base10 + $scope.iva10 + $scope.base4 + $scope.iva4;
    };

    $scope.Finalizar=function() {
      backendAPIservice.postVenta($scope.cliente, $scope.contado, $scope.listaVenta).success(function(recibe){
        var respuesta1 = recibe.response.respuesta;
        var numventa = recibe.response.venta;
        console.log(JSON.stringify(respuesta1));
        console.log(JSON.stringify(numventa));
        $scope.respuesta = respuesta1;
        $scope.numventa = numventa;
        store.set('token',recibe.response.token);
        $scope.terminado=true;
      });
    };

    $scope.Continuar=function() {
      /*html2canvas(document.getElementById('imprimeesto'), {
        onrendered: function (canvas) {
          var data = canvas.toDataURL();
          var docDefinition = {
            content: [{
              image: data,
              width: 500,
            }]
          };
          pdfMake.createPdf(docDefinition).download("Score_Details.pdf");
        }
      })*/
      $scope.terminado=false;
      $scope.contado=true;
      $scope.cerrado=false;
      $scope.cliente=1;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      $scope.total=0.00;
      $scope.articulopr;
      $scope.respuesta;
      $scope.error;
      $scope.codigo;
      $scope.cero=0;
      $scope.prueba;
      $scope.activo;

      $scope.listaVenta = [];
      $scope.listaProducto = [];
      $scope.listaSocio = [];
      $scope.listaTipo = [];

      if(store.get('token')){
        var token = store.get('token');
        if(!jwtHelper.isTokenExpired(token))
        {
          backendAPIservice.getProductos().success(function (recibe) {
            var productosArray = recibe.response.productos;
            store.set('token',recibe.response.token);
            if(recibe.code!=0)
            {
              $scope.cerrado=true;
              var respuesta1 = recibe.response.respuesta;
              console.log(JSON.stringify(respuesta1));
              $scope.respuesta = respuesta1;
            }
            else
            {
              console.log(JSON.stringify(productosArray));
              $scope.listaProducto = productosArray;
            }
          });

          backendAPIservice.getClientes().success(function (recibe) {
            var sociosArray = recibe.response.socios;
            console.log(JSON.stringify(sociosArray));
            $scope.listaSocio = sociosArray;
            store.set('token',recibe.response.token);
          });

          backendAPIservice.getTipos().success(function (recibe) {
            var tiposArray = recibe.response.tipos;
            console.log(JSON.stringify(tiposArray));
            $scope.listaTipo = tiposArray;
            store.set('token',recibe.response.token);
          });
        }
        else
        {
          store.remove('token');
          store.set('nombre', "Sin conexion");
          $location.path("/login");
        }
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    };

    /*$scope.printDiv=function(divName){
      var printContents = document.getElementById(divName).innerHTML;
      var originalContents = document.body.innerHTML;
      document.body.innerHTML = printContents;
      window.print();
      document.body.innerHTML = originalContents;
    };*/

    $scope.printDiv = function(divName) {
      var printContents = document.getElementById(divName).innerHTML;
      var popupWin = window.open('', '_blank', 'width=300,height=300');
      popupWin.document.open();
      popupWin.document.write('<link rel="stylesheet" type="text/css" href="app.css" />' + printContents + '');
      popupWin.document.close();
    };

    /*$scope.printDiv = function (divName) {

      var printContents = document.getElementById(divName).innerHTML;
      var originalContents = document.body.innerHTML;

      if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
          var popupWin = window.open('', '_blank', 'width=600,height=600,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
          popupWin.window.focus();
          popupWin.document.write('<!DOCTYPE html>' +
              '<link rel="stylesheet" type="text/css" href="app.css" />' +
              '
' + printContents + '
');
          popupWin.onbeforeunload = function (event) {
              popupWin.close();
              return '.\n';
          };
          popupWin.onabort = function (event) {
              popupWin.document.close();
              popupWin.close();
          }
      } else {
          var popupWin = window.open('', '_blank', 'width=800,height=600');
          popupWin.document.open();
          popupWin.document.write('<link rel="stylesheet" type="text/css" href="app.css" />' + printContents + '');
          popupWin.document.close();
      }
      popupWin.document.close();

      return true;
    };*/

});
<|endoftext|>


<commit_before>'use strict';
console.log('view1.js loading');
angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$location', 'wikiSvc', 'sharedProperties', function ($scope, $location, wikiSvc, sharedProperties) {

        $scope.searchText = '';

        var getResults = function (value) {
            // if value is undefined/empty set results to empty
            if (value === '' || value === undefined) {
                $scope.results = [];
                sharedProperties.setRandomEntry('');

            // else get results
            } else {
                wikiSvc.query(value).then(function (results) {
                    $scope.results = results.data.query.pages;

                    // and select a random entry
                    var count = 0;
                    for (var prop in $scope.results) {
                        if (Math.random() < 1 / ++count) {
                            sharedProperties.setRandomEntry("https://en.wikipedia.org/?curid=" + prop);
                        }
                    }
                });
            }

        };
        // watch for change in sharedProperties.getSearchText()
        $scope.$watch(
            function () {
                return sharedProperties.getSearchText();
            },
            function (newValue, oldValue) {
                if (newValue !== oldValue) { getResults(newValue); }
            }

        );
    }]);
<commit_msg>updated to prevent searches of length < 3 char<commit_after>'use strict';
console.log('view1.js loading');
angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$location', 'wikiSvc', 'sharedProperties', function ($scope, $location, wikiSvc, sharedProperties) {

        $scope.searchText = '';

        var getResults = function (value) {
            // abort search if search value less than 3 to respect wikipidea
            if (value.length < 3) value = undefined;

            // if value is undefined/empty set results to empty
            if (value === '' || value === undefined) {
                $scope.results = [];
                sharedProperties.setRandomEntry('');

            // else get results
            } else {
                wikiSvc.query(value).then(function (results) {
                    $scope.results = results.data.query.pages;

                    // and select a random entry
                    var count = 0;
                    for (var prop in $scope.results) {
                        if (Math.random() < 1 / ++count) {
                            sharedProperties.setRandomEntry("https://en.wikipedia.org/?curid=" + prop);
                        }
                    }
                });
            }

        };
        // watch for change in sharedProperties.getSearchText()
        $scope.$watch(
            function () {
                return sharedProperties.getSearchText();
            },
            function (newValue, oldValue) {
                if (newValue !== oldValue) { getResults(newValue); }
            }

        );
    }]);
<|endoftext|>


<commit_before>'use strict';

angular.module('duskyStar.view1', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/view1', {
    templateUrl: 'view1/view1.html',
    controller: 'View1Ctrl as v1Ctrl'
  });
}])

.controller('View1Ctrl', ['postFactory', function(postFactory) {

  var self = this;
  console.log(postFactory);

  self.test = "helwdwlo worlasdd";

  self.posts = [
    {title: 'post 1', upvotes: 5},
    {title: 'post 2', upvotes: 2},
    {title: 'post 3', upvotes: 15},
    {title: 'post 4', upvotes: 9},
    {title: 'post 5', upvotes: 4}
  ];

  self.addPost = function() {
    if (!self.title || self.title === '') { return; }
    self.posts.push({
      title: self.title,
      link: self.link,
      upvotes: 0
    });
    self.title = '';
    self.link = '';
  };

  self.incrementUpvotes = function(post) {
    post.upvotes += 1;
  };

}]);
<commit_msg>Injected factory into controller<commit_after>'use strict';

angular.module('duskyStar.view1', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/view1', {
    templateUrl: 'view1/view1.html',
    controller: 'View1Ctrl as v1Ctrl'
  });
}])

.controller('View1Ctrl', ['postFactory', function(postFactory) {

  var self = this;

  self.test = "helwdwlo worlasdd";

  self.posts = postFactory.posts;

  self.addPost = function() {
    if (!self.title || self.title === '') { return; }
    self.posts.push({
      title: self.title,
      link: self.link,
      upvotes: 0
    });
    self.title = '';
    self.link = '';
  };

  self.incrementUpvotes = function(post) {
    post.upvotes += 1;
  };

}]);
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', function ($scope) {
        $scope.attributesImportance = [];

        var Sample = function (attributesValue, output) {
            this.values = attributesValue;
            this.output = output;
        };

        // attribute name - attribute index
        var attributes = {"A1": 0, "A2": 1, "A3": 2};
        // attribute name - attribute value
        var values = {"A1": [1, 0], "A2": [1, 0], "A3": [1, 0]};
        // samples for the learning
        var samples = [new Sample([1, 0, 0], 0),
            new Sample([1, 0, 1], 0),
            new Sample([0, 1, 0], 0),
            new Sample([1, 1, 1], 1),
            new Sample([1, 1, 0], 1)];

        var p = 2,
            n = 3;

        //Node structure
        var NodeQuery = function (attribute) {
            this.attribute = attribute;
            this.edge = [];
        };

        var Edge = function (nodeFrom, nodeTo, attributeValue) {
            this.nodeFrom = nodeFrom;
            this.nodeTo = nodeTo;
            this.attributeValue = attributeValue;
        };

        var NodeResult = function (value) {
            this.value = value;
        };

        var entropyInit = entropyB(p / (p + n));

        var tree = getTreeDecision(samples, attributes, samples);

        console.log("DecisionTree");
        console.log(tree);

        function getTreeDecision(samples, attributes, parentSample) {
            var decisionTree = {},
                importanceTmp = null,
                attributeChosen, // A1, A2, A3,
                attributeChosenIndex, // 0, 1, 2
                importanceResults = [];

            // Determine the classification from the parent samples if there is no more sample.
            if (samples.length === 0) {
                return pluralityValue(parentSample);
            }
            // Check if the sample have the same classification.
            var classification = checkClassification(samples);
            if (classification != null) {
                return new NodeResult(classification);
            }
            // Check if the attributes array is empty
            if (Object.keys(attributes).length === 0) {
                return new NodeResult(samples);
            }

            // Retrieve the attribute with the highest 'importance'
            var i = 0;
            for (var attribute in attributes) {
                var imp = importance(attributes[attribute], samples);
                importanceResults.push("Importance for " + attribute + " = " + imp);
                if (importanceTmp == null || importanceTmp < imp) {
                    importanceTmp = imp;
                    attributeChosen = attribute;
                    attributeChosenIndex = i;
                }
                i++;
            }
            $scope.importanceResults = importanceResults;
            $scope.attributeChosen = attributeChosen;

            decisionTree = new NodeQuery(attributeChosen);
            for (var value in values[attributeChosen]) {
                console.log("Retrieving the samples for attribute " + attributeChosen + " : " + value);
                var attributeIndex = attributes[attributeChosen];
                var exs = [];
                for (var index in samples) {
                    var sample = samples[index];
                    if (sample.values[attributeIndex] === parseInt(value)) {
                        exs.push(sample);
                        delete attributes[attributeChosen];
                        var subTree = getTreeDecision(exs, attributes, samples)
                        var edge = new Edge(decisionTree, subTree, value);
                        decisionTree.edge.push(edge);
                    }
                }
            }

            return decisionTree;
        }

        /**
         * Determinate a classification (the most common) corresponding to the sample
         * @param samples
         */
        function pluralityValue(samples) {
            var classifications = {},
                classificationMax = null;
            for (var sample in samples) {
                if (classifications[sample.output] === null) {
                    classifications[sample.output] = 1;
                } else {
                    classifications[sample.output]++;
                }
            }
            for (var output in classifications) {
                if (classificationMax === null) {
                    classificationMax = classifications[output];
                } else if (classificationMax < classifications[output]) {
                    classificationMax = classifications[output];
                }
            }
            console.log("PluralityValue classification : ", classificationMax);
            return new NodeResult(classificationMax);
        }

        /**
         * Return the classification if all the examples have the same classification
         */
        function checkClassification(samples) {
            var sameClassification = true,
                refSample = samples[0];
            if (samples.length > 1) {
                for (var i = 1; i < samples.length; i++) {
                    if (samples[i].output !== refSample.output) {
                        sameClassification = false;
                    }
                }
            }

            return (sameClassification ? refSample.output : null);
        }

        /**
         * Calculate the importance with samples for a corresponding attribute
         * @param attributeIndex
         * @param samples
         * @returns {number} - importance
         */
        function importance(attributeIndex, samples) {
            var restTmp = 0.0;

            for (var i = 0; i < 2; i++) {
                restTmp += rest(samples, attributeIndex, i);
            }

            return entropyInit - restTmp;
        }

        function rest(samples, attributeIndex, value) {
            var nk = 0,
                pk = 0;

            for (var i = 0; i < samples.length; i++) {
                var sample = samples[i];
                if (sample.values[attributeIndex] === value) {
                    if (sample.output === 1) {
                        pk++;
                    } else {
                        nk++;
                    }
                }
            }

            var a = ((pk + nk) / (p + n)) * entropyB(pk / (nk + pk));
            console.log("Rest for " + attributeIndex + " value " + value + " = " + a);
            return a;
        }

        function entropyB(probability) {
            var entropy = 0;

            if (probability != 1) {
                entropy += (1.0 - probability) * Math.log2(1.0 - probability);
            }

            if (probability != 0) {
                entropy += (probability * Math.log2(probability));
            }

            entropy = -entropy;
            console.log("EntropyB for " + probability + " = " + entropy);
            return entropy;
        }

    }]);<commit_msg>We have something that works !<commit_after>'use strict';

angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', function ($scope) {
        $scope.attributesImportance = [];

        var Sample = function (attributesValue, output) {
            this.values = attributesValue;
            this.output = output;
        };

        // attribute name - attribute index
        var attributes = {"A1": 0, "A2": 1, "A3": 2};
        // attribute name - attribute value
        var values = {"A1": [1, 0], "A2": [1, 0], "A3": [1, 0]};
        // samples for the learning
        var samples = [new Sample([1, 0, 0], 0),
            new Sample([1, 0, 1], 0),
            new Sample([0, 1, 0], 0),
            new Sample([1, 1, 1], 1),
            new Sample([1, 1, 0], 1)];

        var p = 2,
            n = 3;

        //Node structure
        var NodeQuery = function (attribute) {
            this.attribute = attribute;
            this.edge = [];
        };

        var Edge = function (nodeFrom, nodeTo, attributeValue) {
            this.nodeFrom = nodeFrom;
            this.nodeTo = nodeTo;
            this.attributeValue = attributeValue;
        };

        var NodeResult = function (value) {
            this.value = value;
        };

        var entropyInit = entropyB(p / (p + n));
        var rootNode = getTreeDecision(samples, attributes, samples);
        var sampleToTest = samples[0];
        var result = getResultFromSample(rootNode, sampleToTest);

        console.log("DecisionTree");
        console.log(rootNode);
        console.log("Result for ", sampleToTest, ' -> ', result);

        function getResultFromSample(rootNode, sample) {
            var result = null;

            if (rootNode instanceof NodeQuery) {
                var currentAttribute = rootNode.attribute;
                var attributeIndex = attributes[currentAttribute];
                var valueAttribute = sample.values[attributeIndex];
                for (var i = 0; i < rootNode.edge.length && result === null; i++) {
                    var edge = rootNode.edge[i];
                    if (parseInt(edge.attributeValue) === valueAttribute) {
                        if (edge.nodeTo instanceof NodeResult) {
                            result = edge.nodeTo.value;
                        } else if (edge.nodeTo instanceof NodeQuery) {
                            result = getResultFromSample(edge.nodeTo, sample);
                        }
                    }
                }
            }

            return result
        }

        function getTreeDecision(samples, attributes, parentSample) {
            var decisionRootNode = {},
                importanceTmp = null,
                attributeChosen, // A1, A2, A3,
                attributeChosenIndex, // 0, 1, 2
                importanceResults = [];

            // Determine the classification from the parent samples if there is no more sample.
            if (samples.length === 0) {
                return pluralityValue(parentSample);
            }
            // Check if the sample have the same classification.
            var classification = checkClassification(samples);
            if (classification != null) {
                return new NodeResult(classification);
            }
            // Check if the attributes array is empty
            if (Object.keys(attributes).length === 0) {
                return new NodeResult(samples);
            }

            // Retrieve the attribute with the highest 'importance'
            var i = 0;
            for (var attribute in attributes) {
                var imp = importance(attributes[attribute], samples);
                importanceResults.push("Importance for " + attribute + " = " + imp);
                if (importanceTmp == null || importanceTmp < imp) {
                    importanceTmp = imp;
                    attributeChosen = attribute;
                    attributeChosenIndex = i;
                }
                i++;
            }
            $scope.importanceResults = importanceResults;
            $scope.attributeChosen = attributeChosen;

            decisionRootNode = new NodeQuery(attributeChosen);
            for (var value in values[attributeChosen]) {
                console.log("Retrieving the samples for attribute " + attributeChosen + " : " + value);
                var attributeIndex = attributes[attributeChosen];
                var exs = [];
                for (var index in samples) {
                    var sample = samples[index];
                    if (sample.values[attributeIndex] === parseInt(value)) {
                        exs.push(sample);
                    }
                }
                var attributesCopy = JSON.parse(JSON.stringify(attributes));
                delete attributesCopy[attributeChosen];
                var subTree = getTreeDecision(exs, attributesCopy, samples)
                var edge = new Edge(decisionRootNode, subTree, value);
                decisionRootNode.edge.push(edge);
            }

            return decisionRootNode;
        }

        /**
         * Determinate a classification (the most common) corresponding to the sample
         * @param samples
         */
        function pluralityValue(samples) {
            var classifications = {},
                classificationMax = null;
            for (var sample in samples) {
                if (classifications[sample.output] === null) {
                    classifications[sample.output] = 1;
                } else {
                    classifications[sample.output]++;
                }
            }
            for (var output in classifications) {
                if (classificationMax === null) {
                    classificationMax = classifications[output];
                } else if (classificationMax < classifications[output]) {
                    classificationMax = classifications[output];
                }
            }
            console.log("PluralityValue classification : ", classificationMax);
            return new NodeResult(classificationMax);
        }

        /**
         * Return the classification if all the examples have the same classification
         */
        function checkClassification(samples) {
            var sameClassification = true,
                refSample = samples[0];
            if (samples.length > 1) {
                for (var i = 1; i < samples.length; i++) {
                    if (samples[i].output !== refSample.output) {
                        sameClassification = false;
                    }
                }
            }

            return (sameClassification ? refSample.output : null);
        }

        /**
         * Calculate the importance with samples for a corresponding attribute
         * @param attributeIndex
         * @param samples
         * @returns {number} - importance
         */
        function importance(attributeIndex, samples) {
            var restTmp = 0.0;

            for (var i = 0; i < 2; i++) {
                restTmp += rest(samples, attributeIndex, i);
            }

            return entropyInit - restTmp;
        }

        function rest(samples, attributeIndex, value) {
            var nk = 0,
                pk = 0;

            for (var i = 0; i < samples.length; i++) {
                var sample = samples[i];
                if (sample.values[attributeIndex] === value) {
                    if (sample.output === 1) {
                        pk++;
                    } else {
                        nk++;
                    }
                }
            }

            var a = ((pk + nk) / (p + n)) * entropyB(pk / (nk + pk));
            console.log("Rest for " + attributeIndex + " value " + value + " = " + a);
            return a;
        }

        function entropyB(probability) {
            var entropy = 0;

            if (probability != 1) {
                entropy += (1.0 - probability) * Math.log2(1.0 - probability);
            }

            if (probability != 0) {
                entropy += (probability * Math.log2(probability));
            }

            entropy = -entropy;
            console.log("EntropyB for " + probability + " = " + entropy);
            return entropy;
        }

    }]);<|endoftext|>


<commit_before>var http = require('http') //loads http module

var port = process.env.PORT || 1337

var server = http.createServer(function (req, res) { //creates server
  res.writeHead(200, {'Content-Type': 'text/plain'})   //sets the right header and status code
  res.end('Hello World\n')  //outputs string with line end symbol
})
server.listen(port, function() {
	console.log('Server is running at %s:%s ', server.address().address, server.address().port) //sets port and IP address of the server
})
<commit_msg>changes :abcd:<commit_after>var http = require('http') // Loads http module

var port = process.env.PORT || 1337

var server = http.createServer(function (req, res) { // Creates server
  res.writeHead(200, {'Content-Type': 'text/plain'})   // Sets the right header and status code
  res.end('Hello World\n')  // Outputs string with line end symbol
})
server.listen(port, function() {
	console.log('Server is running at %s:%s ', server.address().address, server.address().port) //sets port and IP address of the server
})
<|endoftext|>


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

    //For browsers without Object.create
    if (typeof Object.create === "undefined") {
        Object.create = function(o) {
            function F() {
            }
            F.prototype = o;
            return new F();
        };
    }

    var NUM_CLOCKS_X = 30;
    var NUM_CLOCKS_Y = 20;
    var CLOCK_SIZE = 20;
    var ANGLE_STEP = 1;
    var HR_TO_MIN_RATIO = 0.9;

    function Clock(x, y, paper) {
        this.x = x;
        this.y = y;

        this.minAngle = 90.0;
        this.hrAngle = 270.0;

        this.paper = paper;

        paper.circle(x, y, CLOCK_SIZE);
        this.minHand = paper.path("M" + x + "," + y + "l0,-" + CLOCK_SIZE);
        this.hrHand = paper.path("M" + x + "," + y + "l0," + CLOCK_SIZE * HR_TO_MIN_RATIO);
    }

    Clock.prototype.turn = function(hand, angle, time) {
        function recur(rHand) {
            if (angle > ANGLE_STEP) {
                angle -= ANGLE_STEP;
                obj[rHand + "Angle"] = cirAngle(obj[rHand + "Angle"], -1 * ANGLE_STEP);
                obj[rHand + "Hand"].animate({"path": "M" + obj.x + "," + obj.y + "l" + CLOCK_SIZE * Math.cos(rad(obj[rHand + "Angle"])) + "," + -1 * CLOCK_SIZE * Math.sin(rad(obj[rHand + "Angle"]))},
                stepTime,
                        "linear",
                        function() {
                            recur(rHand)
                        });
            } else {
                obj[rHand + "Angle"] = cirAngle(obj[rHand + "Angle"], -1 * angle);
                obj[rHand + "Hand"].animate({"path": "M" + obj.x + "," + obj.y + "l" + CLOCK_SIZE * Math.cos(rad(obj[rHand + "Angle"])) + "," + -1 * CLOCK_SIZE * Math.sin(rad(obj[rHand + "Angle"]))},
                stepTime * (angle / ANGLE_STEP),
                        "linear");
            }

        }

        var stepTime = 1.0 * time / (angle / ANGLE_STEP);
        var obj = this;

        recur(hand);
    };

    Clock.prototype.turnTo = function(hand, posAngle, extraRounds ,time){
        var angle = posAngle - this[hand+"Angle"];

        angle = cirAngle(angle);
        angle += extraRounds*360;
        this.turn(hand, angle, time);
    }

    function rad(deg) {
        return deg / 180 * Math.PI;
    }

    function deg(rad) {
        return rad / Math.PI * 180;
    }

    function cirAngle(angle, step) {
        angle += step;

        if (angle < 0) {
            angle += 360;
        }
        angle %= 360;
        return angle;
    }

    env.AMillionTimes = function(width, height) {
        this.paper = Raphael(20, 20, width, height);

        var c = new Clock(50, 50, this.paper);
        c.turn("min", 360, 10000);
        c.turn("hr",360, 10000);
    }
})(this);<commit_msg>Scheme<commit_after>(function(env) {
    "use strict";

    //For browsers without Object.create
    if (typeof Object.create === "undefined") {
        Object.create = function(o) {
            function F() {
            }
            F.prototype = o;
            return new F();
        };
    }

    var NUM_CLOCKS_X = 30;
    var NUM_CLOCKS_Y = 20;
    var CLOCK_SIZE = 20;
    var ANGLE_STEP = 1;
    var HR_TO_MIN_RATIO = 0.9;

    function Clock(x, y, paper) {
        this.x = x;
        this.y = y;

        this.minAngle = 90.0;
        this.hrAngle = 270.0;

        this.paper = paper;

        paper.circle(x, y, CLOCK_SIZE);
        this.minHand = paper.path("M" + x + "," + y + "l0,-" + CLOCK_SIZE);
        this.hrHand = paper.path("M" + x + "," + y + "l0," + CLOCK_SIZE * HR_TO_MIN_RATIO);
    }

    Clock.prototype.turn = function(hand, angle, time) {
        function recur(rHand) {
            var length = CLOCK_SIZE;
            if(rHand == "hr"){
                length*=HR_TO_MIN_RATIO;
            }

            if (angle > ANGLE_STEP) {
                angle -= ANGLE_STEP;
                obj[rHand + "Angle"] = cirAngle(obj[rHand + "Angle"], -1 * ANGLE_STEP);
                obj[rHand + "Hand"].animate({"path": "M" + obj.x + "," + obj.y + "l" + length * Math.cos(rad(obj[rHand + "Angle"])) + "," + -1 * length * Math.sin(rad(obj[rHand + "Angle"]))},
                stepTime,
                        "linear",
                        function() {
                            recur(rHand)
                        });
            } else {
                obj[rHand + "Angle"] = cirAngle(obj[rHand + "Angle"], -1 * angle);
                obj[rHand + "Hand"].animate({"path": "M" + obj.x + "," + obj.y + "l" + length * Math.cos(rad(obj[rHand + "Angle"])) + "," + -1 * length * Math.sin(rad(obj[rHand + "Angle"]))},
                stepTime * (angle / ANGLE_STEP),
                        "linear");
            }

        }

        var stepTime = 1.0 * time / (angle / ANGLE_STEP);
        var obj = this;

        recur(hand);
    };

    Clock.prototype.turnTo = function(hand, posAngle, extraRounds ,time){
        var angle = posAngle - this[hand+"Angle"];

        angle = cirAngle(angle);
        angle += extraRounds*360;
        this.turn(hand, angle, time);
    }

    function Scheme(minData, hrData){
        this.minData = minData;
        this.hrData = hrData;
    }

    function rad(deg) {
        return deg / 180 * Math.PI;
    }

    function deg(rad) {
        return rad / Math.PI * 180;
    }

    function cirAngle(angle, step) {
        angle += step;

        if (angle < 0) {
            angle += 360;
        }
        angle %= 360;
        return angle;
    }

    env.AMillionTimes = function(width, height) {
        this.paper = Raphael(20, 20, width, height);

        var c = new Clock(50, 50, this.paper);
        c.turn("min", 360, 10000);
        c.turn("hr",360, 10000);
    }
})(this);<|endoftext|>


<commit_before>const bot = require('./../bot');
const influx = require('./../../influx');
const request = require('request-promise-native');
let ingame;
let guild;
const updateIngame = async function(){
  if(!guild && !ingame)return;
  /*
  let playing = await request('http://localhost/v0/discord/online');
  playing = JSON.parse(playing);
  */
  let playing = guild.members.filterArray(function (m) {
        if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                return m.user.id;
    });
  playing = playing.map(m => m.user.id);
  console.log(playing);
  let toRemove = ingame.members.filter(function (m){
      if(!playing.includes(m.user.id))
      {
        console.log("Not playing : "+ m.user.id)
        return m;
      }
    });
  await Promise.all(toRemove.map(async function(m){
      await m.removeRole(ingame);
   }));
   await Promise.all(playing.map(async function(m){
      const member = await guild.fetchMember(m);
      if(!member.roles.get(ingame.id))
        await member.addRole(ingame);
   }));
  influx.writePoints([
          {
            measurement: 'statistics',
            fields: { count: playing.length},
            tags: {type:'ingame'}
          }
        ]).catch(console.log);
};
bot.on('ready',()=>{
    guild =  bot.guilds.get("184536578654339072");
    ingame = guild.roles.get("322233107489226764");
});
setInterval(updateIngame,5000)
/**
bot.on('presenceUpdate',async function(om,m){
    if(m.guild.id != guild.id) return;
    if (om.presence.game && om.presence.game.name)
            if (om.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.removeRole(ingame);
    if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.addRole(ingame);
});
*/
<commit_msg>use full collection<commit_after>const bot = require('./../bot');
const influx = require('./../../influx');
const request = require('request-promise-native');
let ingame;
let guild;
const updateIngame = async function(){
  if(!guild && !ingame)return;
  /*
  let playing = await request('http://localhost/v0/discord/online');
  playing = JSON.parse(playing);
  */
  let members = await guild.fetchMembers();
  let playing = members.filterArray(function (m) {
        if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                return m.user.id;
    });
  playing = playing.map(m => m.user.id);
  console.log(playing);
  let toRemove = ingame.members.filter(function (m){
      if(!playing.includes(m.user.id))
      {
        console.log("Not playing : "+ m.user.id)
        return m;
      }
    });
  await Promise.all(toRemove.map(async function(m){
      await m.removeRole(ingame);
   }));
   await Promise.all(playing.map(async function(m){
      const member = await guild.fetchMember(m);
      if(!member.roles.get(ingame.id))
        await member.addRole(ingame);
   }));
  influx.writePoints([
          {
            measurement: 'statistics',
            fields: { count: playing.length},
            tags: {type:'ingame'}
          }
        ]).catch(console.log);
};
bot.on('ready',()=>{
    guild =  bot.guilds.get("184536578654339072");
    ingame = guild.roles.get("322233107489226764");
});
setInterval(updateIngame,5000)
/**
bot.on('presenceUpdate',async function(om,m){
    if(m.guild.id != guild.id) return;
    if (om.presence.game && om.presence.game.name)
            if (om.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.removeRole(ingame);
    if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.addRole(ingame);
});
*/
<|endoftext|>


<commit_before>/**
 * mw.MobilePlayerTimeline handles basic timelines of clips in the mobile
 * platform
 *
 * AdTimeline is targets VAST as the display representation and its
 * timelineTargets support the VAST display types. Future updates may handle
 * more ad types and timeline targets.
 *
 * in mobile html5 ( iOS ) to switch clips you have to do some trickery because
 * only one video tag can be active in the page:
 *
 * Player src changes work with the following timeline: issuing a "src change"
 * then issue the "load" wait a few seconds then issue the "play" once restoring
 * the source we need to seek to parent offset position
 *
 *
 * @param {Object}
 *            embedPlayer the embedPlayer target ( creates a mobileTimeline
 *            controller on the embedPlayer target if it does not already exist )
 * @param {Object}
 *            timeType Stores the target string can be 'preroll', 'bumper', 'overlay',
 *            'midroll', 'postroll'
 * @param {Object}
 *            adConf adConf object see
 *            mw.MobilePlayerTimeline.display
 *
 *
 *
 * AdConf object structure:
 * {
 * 		// Set of ads to chose from
 * 		'ads' : [
 * 			{
 * 				'id' : { Add id}
 * 				'companions' : [
 * 					{
 * 						'id' : {Number} index of companion target
 * 						'html' : {String} html text to set innerHTML of companion target
 * 					}
 * 				],
 * 				'duration' : {Number} duration of ad in seconds
 *
 * 				// Impression fired at start of ad display
 * 				'impressions': [
 * 					'beaconUrl' : {URL}
 * 				]
 *
 *				// Tracking events sent for video playback
 * 				'trackingEvents' : [
 * 					beaconUrl : {URL}
 * 					eventName : {String} Event name per VAST definition of video ad playback ( start, midpoint, etc. )
 * 				]
 *				// NonLinear list of overlays
 * 				'nonLinear' : [
 * 					{
 * 						'width': {Number} width
 * 						'height': {Number} height
 * 						'html': {String} html
 * 					}
 * 				],
 * 				'clickThrough' : {URL} url to open when video is "clicked"
 *
 * 				'videoFiles' : {Object} of type {'src':{url to asset}, 'type': {content type of asset} }
 * 			}
 * 		],
 *		// on screen helpers to display ad duration and skip add
 * 		'notice' : {
 * 			'text' : {String} "Ad countdown time, $1 is replaced with countdown time",
 * 			'css' : {Object} json object for css layout
 * 		}
 * 		'skipBtn' : {
 * 			'text' : {String} "Text of skip add link",
 * 			'css' : {Object} json object for css layout
 * 		}
 * 		// List of companion targets
 * 		'companionTargets' : [
 * 			{
 *	  			'elementid' : {String} id of element
 *	  			'height' : {Number} height of companion target
 *	  			'type' : {String} Companion target type ( html in mobile )
 *	  		}
 * 		]
 * }
 */
( function( mw, $ ) { "use strict";

mw.addAdTimeline = function( embedPlayer ){
	embedPlayer.adTimeline = new mw.AdTimeline( embedPlayer );
};
mw.AdTimeline = function(embedPlayer) {
	return this.init(embedPlayer);
};

mw.AdTimeline.prototype = {

	// Overlays are disabled during preroll, bumper and postroll
	adOverlaysEnabled: true,

	// Original source of embedPlayer
	originalSource: false,

	// Flag to store if its the first time play is being called:
	firstPlay: true,

	bindPostfix: '.AdTimeline',

	/**
	 * @constructor
	 * @param {Object}
	 *            embedPlayer The embedPlayer object
	 */
	init: function(embedPlayer) {
		this.embedPlayer = embedPlayer;
		// Bind to the "play" and "end"
		this.bindPlayer();
	},

	/**
	 * Update Sequence Proxy property
	 * @param {string}
	 * 			propName The name of the property
	 * @param {object}
	 * 			value The value for the supplied property
	 */
	updateSequenceProxy: function( propName, value ){
		this.embedPlayer.sequenceProxy[ propName ] = value;
	},
	bindPlayer: function() {
		var _this = this;
		var embedPlayer = this.embedPlayer;
		// Setup the original source
		_this.originalSource = embedPlayer.getSource();
		// Clear out any old bindings
		_this.destroy();
		// Create an empty sequence proxy object ( stores information about the current sequence )
		embedPlayer.sequenceProxy = {
			'isInSequence' : false,
			'timeRemaining' : 0,
			'duration' : 0
		};

		// On change media clear out any old adTimeline bindings
		embedPlayer.bindHelper( 'onChangeMedia' + _this.bindPostfix, function(){
			_this.destroy();
		});

		// Rest displayed slot count
		_this.displayedSlotCount = 0;

		// On play preSequence
		embedPlayer.bindHelper( 'preSequence' + _this.bindPostfix, function() {
			// Start of preSequence
			embedPlayer.triggerHelper( 'AdSupport_PreSequence');

			mw.log( "AdTimeline:: First Play Start / bind Ad timeline ( " );
			embedPlayer.pauseLoading();
			embedPlayer.sequenceProxy.isInSequence = true;
			// given an opportunity for ads to load for ads to load:
			embedPlayer.triggerQueueCallback( 'AdSupport_OnPlayAdLoad',function(){
				mw.log( "AdTimeline:: AdSupport_OnPlayAdLoad ");
				// Show prerolls:
				_this.displaySlots( 'preroll', function(){
					// Show bumpers:
					_this.displaySlots( 'bumper', function(){
						// restore the original source:
						embedPlayer.switchPlaySource( _this.originalSource, function(){
							// turn off preSequence
							embedPlayer.sequenceProxy.isInSequence = false;

							// trigger the preSequenceComplete event
							embedPlayer.triggerHelper( 'AdSupport_PreSequenceComplete' );

							// Avoid function stack
							setTimeout(function(){
								// trigger another onplay ( to match the kaltura kdp ) on play event
								// after the ad plays are complete
								if( _this.displayedSlotCount > 0 ){
									// reset displaySlotCount:
									 _this.displayedSlotCount=0;
									// Restore the player if we played an ad:
									_this.restorePlayer();
								}
								// Sync player size
								embedPlayer.controlBuilder.syncPlayerSize();
								// Trigger onplay ( even if there were no ads )
								embedPlayer.triggerHelper( 'onplay' );

								// Continue playback
								embedPlayer.play();
							},0);
						});

					});
				});
			});
		});

		// Bind the player "ended" event to play the postroll if present
		var displayedPostroll = false;
		// TODO We really need a "preend" event for thing like this.
		// So that playlist next clip or other end bindings don't get triggered.
		embedPlayer.bindHelper( 'ended' + _this.bindPostfix, function( event ){
			if( displayedPostroll ){
				return ;
			}
			var playedAnAdFlag = false;
			embedPlayer.bindHelper( 'AdSupport_StartAdPlayback' +  _this.bindPostfix, function(){
				playedAnAdFlag = true;
			});
			displayedPostroll = true;
			mw.log( 'AdTimeline:: AdSupport_StartAdPlayback set onDoneInterfaceFlag = false' );
			embedPlayer.onDoneInterfaceFlag = false;

			// Display post roll in setTimeout ( hack to work around end sequence issues )
			// should be refactored.
			setTimeout(function(){
				// Trigger the postSequenceStart event
				// start the postSequence:
				embedPlayer.triggerHelper( 'AdSupport_PostSequence' );
				embedPlayer.sequenceProxy.isInSequence = true;
				_this.displaySlots( 'postroll', function(){
					// Turn off preSequence
					embedPlayer.sequenceProxy.isInSequence = false;
					// Trigger the postSequenceComplete event
					embedPlayer.triggerHelper( 'AdSupport_PostSequenceComplete' );
					/** TODO support postroll bumper and leave behind */
					if( playedAnAdFlag ){
						embedPlayer.switchPlaySource( _this.originalSource, function( video ){
							// Make sure we pause the video
							video.pause();
							/* iPad iOS v4.3.1 ignore video pause (probably timing issue) */
							$( video ).bind('play.postSequenceComplete', function(){
								video.pause();
								$( video ).unbind( '.postSequenceComplete' );
							});
							// Restore interface
							_this.restorePlayer();
							// Restore ondone interface:
							embedPlayer.onDoneInterfaceFlag = true;
							// on clip done can't be invoked with a stop state ( TOOD clean up end sequence )
							embedPlayer.stopped = false;
							// Run the clipdone event:
							embedPlayer.onClipDone();
						});
					} else {
						_this.restorePlayer();
						// Restore ondone interface:
						embedPlayer.onDoneInterfaceFlag = true;
						// on clip done can't be invoked with a stop state ( TOOD clean up end sequence )
						embedPlayer.stopped = false;
						// run the clipdone event:
						embedPlayer.onClipDone();
					}
				});
			}, 0)
		});
	},
	destroy: function(){
		var _this = this;
		// Reset firstPlay flag
		_this.firstPlay = true;
		// Unbind all adTimeline events
		$( _this.embedPlayer ).unbind( _this.bindPostfix );
	},
	/**
	 * Displays all the slots of a given set
	 *
	 * @param slotSet
	 * 			{Object} slotSet Set of slots to be displayed.
	 * @param doneCallback
	 * 			{function} doneCallback Function called once done displaying slots
	 * @return
	 */
	displaySlots: function( slotType, doneCallback ){
		var _this = this;
		// Setup a sequence timeline set:
		var sequenceProxy = {};

		// Get the sequence ad set
		_this.embedPlayer.triggerHelper( 'AdSupport_' + slotType,  [ sequenceProxy ] );

		// Generate a sorted key list:
		var keyList = [];
		$.each( sequenceProxy, function(k, na){
			keyList.push( k );
		});

		mw.log( "AdTimeline:: displaySlots: " + slotType + ' found sequenceProxy length: ' + keyList.length );

		// if don't have any ads issue the callback directly:
		if( !keyList.length ){
			doneCallback();
			return ;
		}

		// Sort the sequence proxy key list:
		keyList.sort();
		var seqInx = 0;
		// Run each sequence key in order:
		var runSequeceProxyInx = function( seqInx ){
			// Update the "sequenceProxy" var
			_this.embedPlayer.sequenceProxy.isInSequence = true;
			var key = keyList[ seqInx ] ;
			if( !sequenceProxy[key] ){
				doneCallback();
				return ;
			}
			// Run the sequence proxy function:
			sequenceProxy[ key ]( function(){

				// Done with slot increment display slot count
				_this.displayedSlotCount++;

				// done with the current proxy call next
				seqInx++;
				// Trigger the EndAdPlayback between each ad in the sequence proxy
				// ( if we have more ads to go )
				if( sequenceProxy[ keyList[ seqInx ] ] ){
					_this.embedPlayer.triggerHelper( 'AdSupport_EndAdPlayback' );
				}
				// call with a timeout to avoid function stack
				setTimeout(function(){
					runSequeceProxyInx( seqInx );
				}, 0 );
			});
			// Update the interface for ads:
			_this.updateUiForAdPlayback( slotType );
		};
		runSequeceProxyInx( seqInx );
	},
	updateUiForAdPlayback: function( slotType ){
		mw.log( "AdTimeline:: updateUiForAdPlayback: slotType:" + slotType );
		var embedPlayer = this.embedPlayer;
		// Stop the native embedPlayer events so we can play the preroll and bumper
		embedPlayer.stopEventPropagation();
		// TODO read the add disable control bar to ad config and check that here.
		embedPlayer.disablePlayControls();
		// Update the interface to play state:
		embedPlayer.playInterfaceUpdate();
		// make sure to hide the spinner
		embedPlayer.hidePlayerSpinner();
		// Set inSequence property to "true"
		embedPlayer.sequenceProxy.isInSequence = true;
		// Trigger an ad start event once we enter an ad state
		embedPlayer.triggerHelper( 'AdSupport_StartAdPlayback', slotType );
	},
	/**
	 * Restore a player from ad state
	 * @return
	 */
	restorePlayer: function(  ){
		mw.log( "AdTimeline:: restorePlayer " );
		var embedPlayer = this.embedPlayer;
		embedPlayer.restoreEventPropagation();
		embedPlayer.enablePlayControls();
		embedPlayer.monitor();
		embedPlayer.seeking = false;
		// restore in sequence property;
		embedPlayer.sequenceProxy.isInSequence = false;
		// trigger an event so plugins can restore their content based actions
		embedPlayer.triggerHelper( 'AdSupport_EndAdPlayback');
	}
};

} )( window.mw, jQuery );<commit_msg>sync player size when content start playing<commit_after>/**
 * mw.MobilePlayerTimeline handles basic timelines of clips in the mobile
 * platform
 *
 * AdTimeline is targets VAST as the display representation and its
 * timelineTargets support the VAST display types. Future updates may handle
 * more ad types and timeline targets.
 *
 * in mobile html5 ( iOS ) to switch clips you have to do some trickery because
 * only one video tag can be active in the page:
 *
 * Player src changes work with the following timeline: issuing a "src change"
 * then issue the "load" wait a few seconds then issue the "play" once restoring
 * the source we need to seek to parent offset position
 *
 *
 * @param {Object}
 *            embedPlayer the embedPlayer target ( creates a mobileTimeline
 *            controller on the embedPlayer target if it does not already exist )
 * @param {Object}
 *            timeType Stores the target string can be 'preroll', 'bumper', 'overlay',
 *            'midroll', 'postroll'
 * @param {Object}
 *            adConf adConf object see
 *            mw.MobilePlayerTimeline.display
 *
 *
 *
 * AdConf object structure:
 * {
 * 		// Set of ads to chose from
 * 		'ads' : [
 * 			{
 * 				'id' : { Add id}
 * 				'companions' : [
 * 					{
 * 						'id' : {Number} index of companion target
 * 						'html' : {String} html text to set innerHTML of companion target
 * 					}
 * 				],
 * 				'duration' : {Number} duration of ad in seconds
 *
 * 				// Impression fired at start of ad display
 * 				'impressions': [
 * 					'beaconUrl' : {URL}
 * 				]
 *
 *				// Tracking events sent for video playback
 * 				'trackingEvents' : [
 * 					beaconUrl : {URL}
 * 					eventName : {String} Event name per VAST definition of video ad playback ( start, midpoint, etc. )
 * 				]
 *				// NonLinear list of overlays
 * 				'nonLinear' : [
 * 					{
 * 						'width': {Number} width
 * 						'height': {Number} height
 * 						'html': {String} html
 * 					}
 * 				],
 * 				'clickThrough' : {URL} url to open when video is "clicked"
 *
 * 				'videoFiles' : {Object} of type {'src':{url to asset}, 'type': {content type of asset} }
 * 			}
 * 		],
 *		// on screen helpers to display ad duration and skip add
 * 		'notice' : {
 * 			'text' : {String} "Ad countdown time, $1 is replaced with countdown time",
 * 			'css' : {Object} json object for css layout
 * 		}
 * 		'skipBtn' : {
 * 			'text' : {String} "Text of skip add link",
 * 			'css' : {Object} json object for css layout
 * 		}
 * 		// List of companion targets
 * 		'companionTargets' : [
 * 			{
 *	  			'elementid' : {String} id of element
 *	  			'height' : {Number} height of companion target
 *	  			'type' : {String} Companion target type ( html in mobile )
 *	  		}
 * 		]
 * }
 */
( function( mw, $ ) { "use strict";

mw.addAdTimeline = function( embedPlayer ){
	embedPlayer.adTimeline = new mw.AdTimeline( embedPlayer );
};
mw.AdTimeline = function(embedPlayer) {
	return this.init(embedPlayer);
};

mw.AdTimeline.prototype = {

	// Overlays are disabled during preroll, bumper and postroll
	adOverlaysEnabled: true,

	// Original source of embedPlayer
	originalSource: false,

	// Flag to store if its the first time play is being called:
	firstPlay: true,

	bindPostfix: '.AdTimeline',

	/**
	 * @constructor
	 * @param {Object}
	 *            embedPlayer The embedPlayer object
	 */
	init: function(embedPlayer) {
		this.embedPlayer = embedPlayer;
		// Bind to the "play" and "end"
		this.bindPlayer();
	},

	/**
	 * Update Sequence Proxy property
	 * @param {string}
	 * 			propName The name of the property
	 * @param {object}
	 * 			value The value for the supplied property
	 */
	updateSequenceProxy: function( propName, value ){
		this.embedPlayer.sequenceProxy[ propName ] = value;
	},
	bindPlayer: function() {
		var _this = this;
		var embedPlayer = this.embedPlayer;
		// Setup the original source
		_this.originalSource = embedPlayer.getSource();
		// Clear out any old bindings
		_this.destroy();
		// Create an empty sequence proxy object ( stores information about the current sequence )
		embedPlayer.sequenceProxy = {
			'isInSequence' : false,
			'timeRemaining' : 0,
			'duration' : 0
		};

		// On change media clear out any old adTimeline bindings
		embedPlayer.bindHelper( 'onChangeMedia' + _this.bindPostfix, function(){
			_this.destroy();
		});

		// Rest displayed slot count
		_this.displayedSlotCount = 0;

		// On play preSequence
		embedPlayer.bindHelper( 'preSequence' + _this.bindPostfix, function() {
			// Start of preSequence
			embedPlayer.triggerHelper( 'AdSupport_PreSequence');

			mw.log( "AdTimeline:: First Play Start / bind Ad timeline ( " );
			embedPlayer.pauseLoading();
			embedPlayer.sequenceProxy.isInSequence = true;
			// given an opportunity for ads to load for ads to load:
			embedPlayer.triggerQueueCallback( 'AdSupport_OnPlayAdLoad',function(){
				mw.log( "AdTimeline:: AdSupport_OnPlayAdLoad ");
				// Show prerolls:
				_this.displaySlots( 'preroll', function(){
					// Show bumpers:
					_this.displaySlots( 'bumper', function(){
						// restore the original source:
						embedPlayer.switchPlaySource( _this.originalSource, function(){
							// turn off preSequence
							embedPlayer.sequenceProxy.isInSequence = false;

							// trigger the preSequenceComplete event
							embedPlayer.triggerHelper( 'AdSupport_PreSequenceComplete' );

							// Avoid function stack
							setTimeout(function(){
								// trigger another onplay ( to match the kaltura kdp ) on play event
								// after the ad plays are complete
								if( _this.displayedSlotCount > 0 ){
									// reset displaySlotCount:
									 _this.displayedSlotCount=0;
									// Restore the player if we played an ad:
									_this.restorePlayer();
								}
								// Sync player size
								embedPlayer.bindHelper('playing', function() {
									embedPlayer.controlBuilder.syncPlayerSize();
								});
								// Trigger onplay ( even if there were no ads )
								embedPlayer.triggerHelper( 'onplay' );
								// Continue playback
								embedPlayer.play();
							},0);
						});

					});
				});
			});
		});

		// Bind the player "ended" event to play the postroll if present
		var displayedPostroll = false;
		// TODO We really need a "preend" event for thing like this.
		// So that playlist next clip or other end bindings don't get triggered.
		embedPlayer.bindHelper( 'ended' + _this.bindPostfix, function( event ){
			if( displayedPostroll ){
				return ;
			}
			var playedAnAdFlag = false;
			embedPlayer.bindHelper( 'AdSupport_StartAdPlayback' +  _this.bindPostfix, function(){
				playedAnAdFlag = true;
			});
			displayedPostroll = true;
			mw.log( 'AdTimeline:: AdSupport_StartAdPlayback set onDoneInterfaceFlag = false' );
			embedPlayer.onDoneInterfaceFlag = false;

			// Display post roll in setTimeout ( hack to work around end sequence issues )
			// should be refactored.
			setTimeout(function(){
				// Trigger the postSequenceStart event
				// start the postSequence:
				embedPlayer.triggerHelper( 'AdSupport_PostSequence' );
				embedPlayer.sequenceProxy.isInSequence = true;
				_this.displaySlots( 'postroll', function(){
					// Turn off preSequence
					embedPlayer.sequenceProxy.isInSequence = false;
					// Trigger the postSequenceComplete event
					embedPlayer.triggerHelper( 'AdSupport_PostSequenceComplete' );
					/** TODO support postroll bumper and leave behind */
					if( playedAnAdFlag ){
						embedPlayer.switchPlaySource( _this.originalSource, function( video ){
							// Make sure we pause the video
							video.pause();
							/* iPad iOS v4.3.1 ignore video pause (probably timing issue) */
							$( video ).bind('play.postSequenceComplete', function(){
								video.pause();
								$( video ).unbind( '.postSequenceComplete' );
							});
							// Restore interface
							_this.restorePlayer();
							// Restore ondone interface:
							embedPlayer.onDoneInterfaceFlag = true;
							// on clip done can't be invoked with a stop state ( TOOD clean up end sequence )
							embedPlayer.stopped = false;
							// Run the clipdone event:
							embedPlayer.onClipDone();
						});
					} else {
						_this.restorePlayer();
						// Restore ondone interface:
						embedPlayer.onDoneInterfaceFlag = true;
						// on clip done can't be invoked with a stop state ( TOOD clean up end sequence )
						embedPlayer.stopped = false;
						// run the clipdone event:
						embedPlayer.onClipDone();
					}
				});
			}, 0)
		});
	},
	destroy: function(){
		var _this = this;
		// Reset firstPlay flag
		_this.firstPlay = true;
		// Unbind all adTimeline events
		$( _this.embedPlayer ).unbind( _this.bindPostfix );
	},
	/**
	 * Displays all the slots of a given set
	 *
	 * @param slotSet
	 * 			{Object} slotSet Set of slots to be displayed.
	 * @param doneCallback
	 * 			{function} doneCallback Function called once done displaying slots
	 * @return
	 */
	displaySlots: function( slotType, doneCallback ){
		var _this = this;
		// Setup a sequence timeline set:
		var sequenceProxy = {};

		// Get the sequence ad set
		_this.embedPlayer.triggerHelper( 'AdSupport_' + slotType,  [ sequenceProxy ] );

		// Generate a sorted key list:
		var keyList = [];
		$.each( sequenceProxy, function(k, na){
			keyList.push( k );
		});

		mw.log( "AdTimeline:: displaySlots: " + slotType + ' found sequenceProxy length: ' + keyList.length );

		// if don't have any ads issue the callback directly:
		if( !keyList.length ){
			doneCallback();
			return ;
		}

		// Sort the sequence proxy key list:
		keyList.sort();
		var seqInx = 0;
		// Run each sequence key in order:
		var runSequeceProxyInx = function( seqInx ){
			// Update the "sequenceProxy" var
			_this.embedPlayer.sequenceProxy.isInSequence = true;
			var key = keyList[ seqInx ] ;
			if( !sequenceProxy[key] ){
				doneCallback();
				return ;
			}
			// Run the sequence proxy function:
			sequenceProxy[ key ]( function(){

				// Done with slot increment display slot count
				_this.displayedSlotCount++;

				// done with the current proxy call next
				seqInx++;
				// Trigger the EndAdPlayback between each ad in the sequence proxy
				// ( if we have more ads to go )
				if( sequenceProxy[ keyList[ seqInx ] ] ){
					_this.embedPlayer.triggerHelper( 'AdSupport_EndAdPlayback' );
				}
				// call with a timeout to avoid function stack
				setTimeout(function(){
					runSequeceProxyInx( seqInx );
				}, 0 );
			});
			// Update the interface for ads:
			_this.updateUiForAdPlayback( slotType );
		};
		runSequeceProxyInx( seqInx );
	},
	updateUiForAdPlayback: function( slotType ){
		mw.log( "AdTimeline:: updateUiForAdPlayback: slotType:" + slotType );
		var embedPlayer = this.embedPlayer;
		// Stop the native embedPlayer events so we can play the preroll and bumper
		embedPlayer.stopEventPropagation();
		// TODO read the add disable control bar to ad config and check that here.
		embedPlayer.disablePlayControls();
		// Update the interface to play state:
		embedPlayer.playInterfaceUpdate();
		// make sure to hide the spinner
		embedPlayer.hidePlayerSpinner();
		// Set inSequence property to "true"
		embedPlayer.sequenceProxy.isInSequence = true;
		// Trigger an ad start event once we enter an ad state
		embedPlayer.triggerHelper( 'AdSupport_StartAdPlayback', slotType );
	},
	/**
	 * Restore a player from ad state
	 * @return
	 */
	restorePlayer: function(  ){
		mw.log( "AdTimeline:: restorePlayer " );
		var embedPlayer = this.embedPlayer;
		embedPlayer.restoreEventPropagation();
		embedPlayer.enablePlayControls();
		embedPlayer.monitor();
		embedPlayer.seeking = false;
		// restore in sequence property;
		embedPlayer.sequenceProxy.isInSequence = false;
		// trigger an event so plugins can restore their content based actions
		embedPlayer.triggerHelper( 'AdSupport_EndAdPlayback');
	}
};

} )( window.mw, jQuery );<|endoftext|>


<commit_before>'use strict';

// Declare app level module which depends on views, and components
angular.module('schedulerApp', [
  'ngRoute',
  'ngResource'
])
.factory('db', [ '$resource', '$q', '$rootScope', function($resource, $q, $rootScope) {

	var
		Things = $resource("http://10.0.1.168:8000/rest/v1/things", {}),
		Rooms = $resource("http://10.0.1.168:8000/rest/v1/rooms", {}),
		Tasks = $resource("http://10.0.1.168:8100/rest/v1/tasks", {}),
		Task = $resource("http://10.0.1.168:8100/rest/v1/tasks/:id", {}),
		refreshThings = function() {
			return Things.get({}).$promise.then(
				function(things) {
					service.things = {}
					angular.forEach(things.data,
						function(thing) {
							var found = false
							if (!thing.promoted || !thing.name || !thing.location) {
								console.debug("skipping thing because not promoted, described or assigned to room", thing)
								return
							}
							angular.forEach(thing.device.channels, function(channel) {
								if (channel.supportedMethods && channel.supportedMethods.indexOf("turnOff") >= 0) {
									found = true
								}
							})
							if (found) {
								service.things[thing["id"]] = thing
							}
						}
					)
					return service
				}
			)
		},
		refreshRooms = function() {
			return Rooms.get({}).$promise.then(
				function(rooms) {
					service.rooms = {}
					angular.forEach(rooms.data, function(room) {
						service.rooms[room["id"]] = room
					})
					return service
				}
			)
		},
		refreshTasks = function() {
			return Tasks.get({}).$promise.then(
				function(tasks) {
					service.tasks = {}
					angular.forEach(tasks.schedule, function(task) {
						if (task.description && task.description != '') {
							service.tasks[task["id"]] = task
						}
					})
					return service
				}
			)
		},
		service = {
			things: { } ,
			rooms: { } ,
			tasks: { } ,
			save: function(task) {
				var deferred = $q.defer()
				Tasks.save(
					{},
					task,
					function(r) {
						refreshTasks().then(
							function() { deferred.resolve(r) },
							deferred.reject
						)},
					deferred.reject)
				return deferred.promise
			},
			delete: function(id) {
				var deferred = $q.defer()
				Task.delete({"id": id},
					function(r) {
						refreshTasks().then(function() { deferred.resolve(r)}, deferred.reject)
					},
					deferred.reject
				)
				return deferred.promise
			},
			refresh: function() {
				return $q.all([ refreshRooms(),	refreshThings(), refreshTasks() ]).then(
					function() {
						return service
					}
				)
			}
		}
	return service
}])
.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/list', {templateUrl: 'task-list.html', controller: 'TaskList'});
  $routeProvider.when('/edit/:id', {templateUrl: 'task-edit.html', controller: 'TaskEdit'});
  $routeProvider.when('/create', {templateUrl: 'task-edit.html', controller: 'TaskEdit'});
  $routeProvider.otherwise({redirectTo: '/list'});
}])
.controller('ModelRefresh', ['$scope', 'db', function($scope, db) {
	db.refresh().then(
		function(things) {
			return things
		},
		function(err) {
			$scope.message = err
		}
	)
}])
.controller('TaskEdit', ['$scope', '$location', 'db', '$routeParams', function($scope, $location, db, $routeParams) {

	$scope.thingToModel = function(thing) {
		var result = {}
		result.id = thing.id
		result.description = thing.name
		var room = db.rooms[thing.location]
		if (!room) {
			return null
		}
		result.room = room.name
		result.on = "true"
		return result
	}

	$scope.actionToModel = function(action) {
	    // {
        //    "action" : "turnOn",
        //    "thingID" : "94dc7d1a-aa67-11e4-803a-7c669d02a706",
        //     "type" : "thing-action"
        // }
        //
        // ==>
        //
	    // {
	    //	  "id": thing-id
        //    "description" : "thing description",
        //	  "room": "room description"
        //	  "on": true
        // }
        //

		var result = {}
		switch (action["action"]) {
		case "turnOn":
			result.on = "true"
			break
		case "turnOff":
			result.on = "false"
			break
		default:
			console.debug("bad action ", action)
			return null
		}

		if (action.type != "thing-action") {
			console.debug("bad type ", action.type)
			return null
		}

		if (!action.thingID) {
			console.debug("missing thing id")
			return null
		}

		result.id = action.thingID
		var thing = db.things[result.id]
		if (!thing) {
			console.debug("invalid thing id", result.id)
			return null
		}
		result.description = thing.name
		var room = db.rooms[thing.location]
		if (!room) {
			console.debug("invalid room id", thing.location)
			return null
		}
		result.room = room.name

		return result
	}

	$scope.selectedThings = {}
	$scope.availableThings = {}

	$scope.task = function() {
		return db.tasks[$routeParams["id"]]
	}

	$scope.$watch('task()', function(task) {
		$scope.availableThings = {}
		angular.forEach(db.things, function(t) {
			var m = $scope.thingToModel(t)
			if (m) {
				$scope.availableThings[t["id"]] = m
				$scope.selected = t["id"]
			}
		})
		if (!task) {
			return
		}
		$scope.description = task.description
		$scope.timeOfDay = task.window.after.param
		angular.forEach(task.open, function(action) {
			var thing = $scope.actionToModel(action)
			if (thing) {
				$scope.selectedThings[thing.id] = thing
				delete $scope.availableThings[thing.id]
			} else {
				console.debug(action)
			}
		})
		$scope.updateSelected()
	})

	$scope.selected = null

	$scope.save = function() {
		$scope.message = ""

		var task = {
			"id": $routeParams["id"],
			"description": $scope.description,
			"open":
				(function() {
					var results = []
					angular.forEach($scope.selectedThings, function(m) {
						results.push(
							{
								"type": "thing-action",
								"action": (m.on == "true" ? "turnOn" : "turnOff"),
								"thingID": m.id
							}
						)
					})
					return results
				}()),
			"close": [],
			"window": {
				"after": {
					"rule": "time-of-day",
					"param": $scope.timeOfDay
				},
				"before": {
					"rule": "delay",
					"param": "00:01:00"
				}
			}
		}

		db.save(task).then(
			function() {
				$location.path('/list')
			}, function(m) {
				if (m && m.data) {
					$scope.message = m.data
				} else {
					$scope.message = "An error occurred."
				}
				console.debug(m)
			})
	}

	$scope.delete = function() {
		db.delete($routeParams["id"]).then(
			function() {
				$location.path('/list')
			}, function(m) {
				if (m && m.data) {
					$scope.message = m.data
				} else {
					$scope.message = "An error occurred."
				}
				console.debug(m)
			})
	}

	$scope.updateSelected = function() {
		$scope.selected = null
		angular.forEach($scope.availableThings, function(m) {
			$scope.selected = m.id
		})
	}
	$scope.add = function() {
		if ($scope.selected) {
			$scope.selectedThings[$scope.selected] = $scope.availableThings[$scope.selected]
			delete $scope.availableThings[$scope.selected]
			$scope.updateSelected()
		}

	}

	$scope.remove = function() {
		var tmp = []
		angular.forEach($scope.selectedThings, function (m) {
			if (m.selected) {
				tmp.push(m.id)
			}
		})
		angular.forEach(tmp, function(id) {
			var m = $scope.selectedThings[id]
			delete $scope.selectedThings[id]
			$scope.availableThings[id] = m
		})
		$scope.updateSelected()
	}

	$scope.cancel = function() {
		$location.path('/list')
	}
}])
.controller('TaskList', ['$scope', 'db', '$rootScope', function($scope, db, $rootScope) {
	$scope.tasks = {}
	$scope.db = db
	$scope.$watch("db.tasks", function(tasks) {
		$scope.tasks = db.tasks
	})
}])

<commit_msg>Generalise the connection address.<commit_after>'use strict';

// Declare app level module which depends on views, and components
angular.module('schedulerApp', [
  'ngRoute',
  'ngResource'
])
.factory('db', [ '$resource', '$q', '$rootScope', '$location', function($resource, $q, $rootScope, $location) {

	var
		Things = $resource("http://"+$location.host()+":8000/rest/v1/things", {}),
		Rooms = $resource("http://"+$location.host()+":8000/rest/v1/rooms", {}),
		Tasks = $resource("http://"+$location.host()+":"+$location.port()+"/rest/v1/tasks", {}),
		Task = $resource("http://"+$location.host()+":"+$location.port()+"/rest/v1/tasks/:id", {}),
		refreshThings = function() {
			return Things.get({}).$promise.then(
				function(things) {
					service.things = {}
					angular.forEach(things.data,
						function(thing) {
							var found = false
							if (!thing.promoted || !thing.name || !thing.location) {
								console.debug("skipping thing because not promoted, described or assigned to room", thing)
								return
							}
							angular.forEach(thing.device.channels, function(channel) {
								if (channel.supportedMethods && channel.supportedMethods.indexOf("turnOff") >= 0) {
									found = true
								}
							})
							if (found) {
								service.things[thing["id"]] = thing
							}
						}
					)
					return service
				}
			)
		},
		refreshRooms = function() {
			return Rooms.get({}).$promise.then(
				function(rooms) {
					service.rooms = {}
					angular.forEach(rooms.data, function(room) {
						service.rooms[room["id"]] = room
					})
					return service
				}
			)
		},
		refreshTasks = function() {
			return Tasks.get({}).$promise.then(
				function(tasks) {
					service.tasks = {}
					angular.forEach(tasks.schedule, function(task) {
						if (task.description && task.description != '') {
							service.tasks[task["id"]] = task
						}
					})
					return service
				}
			)
		},
		service = {
			things: { } ,
			rooms: { } ,
			tasks: { } ,
			save: function(task) {
				var deferred = $q.defer()
				Tasks.save(
					{},
					task,
					function(r) {
						refreshTasks().then(
							function() { deferred.resolve(r) },
							deferred.reject
						)},
					deferred.reject)
				return deferred.promise
			},
			delete: function(id) {
				var deferred = $q.defer()
				Task.delete({"id": id},
					function(r) {
						refreshTasks().then(function() { deferred.resolve(r)}, deferred.reject)
					},
					deferred.reject
				)
				return deferred.promise
			},
			refresh: function() {
				return $q.all([ refreshRooms(),	refreshThings(), refreshTasks() ]).then(
					function() {
						return service
					}
				)
			}
		}
	return service
}])
.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/list', {templateUrl: 'task-list.html', controller: 'TaskList'});
  $routeProvider.when('/edit/:id', {templateUrl: 'task-edit.html', controller: 'TaskEdit'});
  $routeProvider.when('/create', {templateUrl: 'task-edit.html', controller: 'TaskEdit'});
  $routeProvider.otherwise({redirectTo: '/list'});
}])
.controller('ModelRefresh', ['$scope', 'db', function($scope, db) {
	db.refresh().then(
		function(things) {
			return things
		},
		function(err) {
			$scope.message = err
		}
	)
}])
.controller('TaskEdit', ['$scope', '$location', 'db', '$routeParams', function($scope, $location, db, $routeParams) {

	$scope.thingToModel = function(thing) {
		var result = {}
		result.id = thing.id
		result.description = thing.name
		var room = db.rooms[thing.location]
		if (!room) {
			return null
		}
		result.room = room.name
		result.on = "true"
		return result
	}

	$scope.actionToModel = function(action) {
	    // {
        //    "action" : "turnOn",
        //    "thingID" : "94dc7d1a-aa67-11e4-803a-7c669d02a706",
        //     "type" : "thing-action"
        // }
        //
        // ==>
        //
	    // {
	    //	  "id": thing-id
        //    "description" : "thing description",
        //	  "room": "room description"
        //	  "on": true
        // }
        //

		var result = {}
		switch (action["action"]) {
		case "turnOn":
			result.on = "true"
			break
		case "turnOff":
			result.on = "false"
			break
		default:
			console.debug("bad action ", action)
			return null
		}

		if (action.type != "thing-action") {
			console.debug("bad type ", action.type)
			return null
		}

		if (!action.thingID) {
			console.debug("missing thing id")
			return null
		}

		result.id = action.thingID
		var thing = db.things[result.id]
		if (!thing) {
			console.debug("invalid thing id", result.id)
			return null
		}
		result.description = thing.name
		var room = db.rooms[thing.location]
		if (!room) {
			console.debug("invalid room id", thing.location)
			return null
		}
		result.room = room.name

		return result
	}

	$scope.selectedThings = {}
	$scope.availableThings = {}

	$scope.task = function() {
		return db.tasks[$routeParams["id"]]
	}

	$scope.$watch('task()', function(task) {
		$scope.availableThings = {}
		angular.forEach(db.things, function(t) {
			var m = $scope.thingToModel(t)
			if (m) {
				$scope.availableThings[t["id"]] = m
				$scope.selected = t["id"]
			}
		})
		if (!task) {
			return
		}
		$scope.description = task.description
		$scope.timeOfDay = task.window.after.param
		angular.forEach(task.open, function(action) {
			var thing = $scope.actionToModel(action)
			if (thing) {
				$scope.selectedThings[thing.id] = thing
				delete $scope.availableThings[thing.id]
			} else {
				console.debug(action)
			}
		})
		$scope.updateSelected()
	})

	$scope.selected = null

	$scope.save = function() {
		$scope.message = ""

		var task = {
			"id": $routeParams["id"],
			"description": $scope.description,
			"open":
				(function() {
					var results = []
					angular.forEach($scope.selectedThings, function(m) {
						results.push(
							{
								"type": "thing-action",
								"action": (m.on == "true" ? "turnOn" : "turnOff"),
								"thingID": m.id
							}
						)
					})
					return results
				}()),
			"close": [],
			"window": {
				"after": {
					"rule": "time-of-day",
					"param": $scope.timeOfDay
				},
				"before": {
					"rule": "delay",
					"param": "00:01:00"
				}
			}
		}

		db.save(task).then(
			function() {
				$location.path('/list')
			}, function(m) {
				if (m && m.data) {
					$scope.message = m.data
				} else {
					$scope.message = "An error occurred."
				}
				console.debug(m)
			})
	}

	$scope.delete = function() {
		db.delete($routeParams["id"]).then(
			function() {
				$location.path('/list')
			}, function(m) {
				if (m && m.data) {
					$scope.message = m.data
				} else {
					$scope.message = "An error occurred."
				}
				console.debug(m)
			})
	}

	$scope.updateSelected = function() {
		$scope.selected = null
		angular.forEach($scope.availableThings, function(m) {
			$scope.selected = m.id
		})
	}
	$scope.add = function() {
		if ($scope.selected) {
			$scope.selectedThings[$scope.selected] = $scope.availableThings[$scope.selected]
			delete $scope.availableThings[$scope.selected]
			$scope.updateSelected()
		}

	}

	$scope.remove = function() {
		var tmp = []
		angular.forEach($scope.selectedThings, function (m) {
			if (m.selected) {
				tmp.push(m.id)
			}
		})
		angular.forEach(tmp, function(id) {
			var m = $scope.selectedThings[id]
			delete $scope.selectedThings[id]
			$scope.availableThings[id] = m
		})
		$scope.updateSelected()
	}

	$scope.cancel = function() {
		$location.path('/list')
	}
}])
.controller('TaskList', ['$scope', 'db', '$rootScope', function($scope, db, $rootScope) {
	$scope.tasks = {}
	$scope.db = db
	$scope.$watch("db.tasks", function(tasks) {
		$scope.tasks = db.tasks
	})
}])

<|endoftext|>