<commit_before>

// for debug only
var __kb;
var __scope;

/**
* The main app
*/
var App = angular.module('Nutrition', [
  'ngAudio',
  'lumx'
]);

App.config(function($locationProvider) {
  $locationProvider
  .html5Mode({ enabled: true, requireBase: false });
});

App.controller('Main', function($scope, $http, $location, $timeout, ngAudio, LxNotificationService, LxProgressService, LxDialogService) {
  // Namespaces
  var CHAT  = $rdf.Namespace("https://ns.rww.io/chat#");
  var CURR  = $rdf.Namespace("https://w3id.org/cc#");
  var DCT   = $rdf.Namespace("http://purl.org/dc/terms/");
  var FACE  = $rdf.Namespace("https://graph.facebook.com/schema/~/");
  var FOAF  = $rdf.Namespace("http://xmlns.com/foaf/0.1/");
  var LIKE  = $rdf.Namespace("http://ontologi.es/like#");
  var LDP   = $rdf.Namespace("http://www.w3.org/ns/ldp#");
  var MBLOG = $rdf.Namespace("http://www.w3.org/ns/mblog#");
  var NUT   = $rdf.Namespace("https://melvincarvalho.github.io/nutrition/ns/nutrition.ttl#");
  var OWL   = $rdf.Namespace("http://www.w3.org/2002/07/owl#");
  var PIM   = $rdf.Namespace("http://www.w3.org/ns/pim/space#");
  var RDF   = $rdf.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
  var RDFS  = $rdf.Namespace("http://www.w3.org/2000/01/rdf-schema#");
  var SIOC  = $rdf.Namespace("http://rdfs.org/sioc/ns#");
  var SOLID = $rdf.Namespace("http://www.w3.org/ns/solid/app#");
  var TMP   = $rdf.Namespace("urn:tmp:");

  var f,g;

  var defaultStorageURI = 'https://nutrition.databox.me/Public/nutrition/test';
  var doap = 'https://melvincarvalho.github.io/nutrition/doap.ttl#this';
  var defaultInbox = 'https://melvin.databox.me/Public/inbox';

  // INIT
  /**
  * Init app
  */
  $scope.initApp = function() {
    $scope.init();
  };

  /**
  * Set Initial variables
  */
  $scope.init = function() {

    $scope.initRDF();
    $scope.initUI();

    /*
    $scope.initRDF();
    $scope.initQueryString();
    $scope.initLocalStorage();
    */

    __kb = g;
    __scope = $scope;
  };

  /**
  * Init UI
  */
  $scope.initUI = function() {
    $scope.initialized = true;
    $scope.loggedIn = false;
    $scope.loginTLSButtonText = "Login";
    $scope.audio = ngAudio.load('audio/button-3.mp3');
    $scope.inbox = defaultInbox;

    $scope.foods = [
      { name: 'Glass of water',      uri: 'urn:tmp:water',      calories: 10 },
      { name: 'Sushi - como',      uri: 'urn:tmp:sushi-como',      calories: 200 },
    ];

    $scope.selects = {
      selectedFood: undefined,
    };

  };

  /**
  * Get values from localStorage
  */
  $scope.initLocalStorage = function() {
    if (localStorage.getItem('user')) {
      var user = JSON.parse(localStorage.getItem('user'));
      $scope.loginSuccess(user);
    }
  };

  /**
  * init RDF knowledge base
  */
  $scope.initRDF = function() {
    var PROXY = "https://rww.io/proxy.php?uri={uri}";
    var AUTH_PROXY = "https://rww.io/auth-proxy?uri=";
    var TIMEOUT = 90000;
    $rdf.Fetcher.crossSiteProxyTemplate=PROXY;

    g = $rdf.graph();
    f = $rdf.fetcher(g, TIMEOUT);
  };

  /**
  * init from query string
  */
  $scope.initQueryString = function() {
    $scope.storageURI = defaultStorageURI;
    if ($location.search().storageURI) {
      $scope.storageURI = $location.search().storageURI;
    }
    $scope.setStorageURI($scope.storageURI);
  };

  /**
  * setStorageURI set the storage URI for words
  * @param  {String} the storage URI for words
  */
  $scope.setStorageURI = function(storageURI) {
    $scope.storageURI = storageURI;
    $location.search('storageURI', $scope.storageURI);
  };

  // AUTH
  /**
  * TLS Login with WebID
  */
  $scope.TLSlogin = function() {
    var AUTHENDPOINT = "https://databox.me/";
    $scope.loginTLSButtonText = 'Logging in...';
    $http({
      method: 'HEAD',
      url: AUTHENDPOINT,
      withCredentials: true
    }).success(function(data, status, headers) {
      var header = 'User';
      var scheme = 'http';
      var user = headers(header);
      if (user && user.length > 0 && user.slice(0,scheme.length) === scheme) {
        $scope.loginSuccess(user);
      } else {
        $scope.notify('WebID-TLS authentication failed.', 'error');
      }
      $scope.loginTLSButtonText = 'Login';
    }).error(function(data, status, headers) {
      $scope.notify('Could not connect to auth server: HTTP '+status);
      $scope.loginTLSButtonText = 'Login';
    });
  };

  /**
  * loginSuccess called after successful login
  * @param  {String} user the logged in user
  */
  $scope.loginSuccess = function(user) {
    $scope.notify('Login Successful!');
    $scope.loggedIn = true;
    $scope.user = user;
    $scope.fetchAll();
    localStorage.setItem('user', JSON.stringify(user));
  };

  /**
  * Logout
  */
  $scope.logout = function() {
    $scope.init();
    $scope.notify('Logout Successful!');
    localStorage.removeItem('user');
  };

  // FETCH functions
  //
  //
  $scope.fetchAll = function() {
  };

  /**
  * Invalidate a cached URI
  * @param  {String} uri The URI to invalidate
  */
  $scope.invalidate = function(uri) {
    console.log('invalidate : ' + uri);
    f.unload(uri);
    f.refresh($rdf.sym(uri));
  };

  /**
  * fetchSeeAlso fetches the see also
  */
  $scope.fetchSeeAlso = function() {
    var seeAlso = 'https://melvincarvalho.github.io/nutrition/data/seeAlso.ttl';
    if ($location.search().seeAlso) {
      seeAlso = $location.search().seeAlso;
    }
    f.nowOrWhenFetched(seeAlso, undefined, function(ok, body) {
      console.log('seeAlso fetched from : ' + seeAlso);
    });

  };

  /**
  * Save the nutrtion
  */
  $scope.save = function() {
    var nutrition = $scope.nutrition || $scope.selects.food.name;
    if (!nutrition) {
      LxNotificationService.error('nutrition is empty');
      return;
    }
    console.log(nutrition);

    var message = "#nutrition: you consumed "+ nutrition +".";
    var img = 'https://melvincarvalho.github.io/nutrition/images/icon.png';
    var post = createPost($scope.user, message, doap, img);

    console.log('writing to : ' + $scope.inbox);
    console.log(post);
    $http({
      method: 'POST',
      url: $scope.inbox,
      withCredentials: true,
      headers: {
        "Content-Type": "text/turtle"
      },
      data: post,
    }).
    success(function(data, status, headers) {
      $scope.notify('Post saved');
      $scope.render();
    }).
    error(function(data, status, headers) {
      $scope.notify('could not save nutrition', 'error');
    });

  };

  // HELPER
  /**
  * Notify
  * @param  {String} message the message to display
  * @param  {String} type the type of notification, error or success
  */
  $scope.notify = function(message, type) {
    console.log(message);
    if (type === 'error') {
      LxNotificationService.error(message);
    } else {
      LxNotificationService.success(message);
    }
  };

  /**
  * create a post in turtle
  * @param  {string} webid       the creator
  * @param  {string} message     the message to send
  * @param  {string} application application that created it
  * @param  {string} img         img for that post
  * @return {string}             the message in turtle
  */
  function createPost(webid, message, application, img) {
    var turtle;
    turtle = '<#this> ';
    turtle += '    <http://purl.org/dc/terms/created> "'+ new Date().toISOString() +'"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;\n';
    turtle += '    <http://purl.org/dc/terms/creator> <' + webid + '> ;\n';
    turtle += '    <http://rdfs.org/sioc/ns#content> "'+ message.trim() +'" ;\n';
    turtle += '    a <http://rdfs.org/sioc/ns#Post> ;\n';

    if (application) {
      turtle += '    <http://www.w3.org/ns/solid/app#application> <' + application + '> ;\n';
    }

    if (img) {
      turtle += '    <http://xmlns.com/foaf/0.1/img> <' + img + '> ;\n';
    }

    turtle += '    <http://www.w3.org/ns/mblog#author> <'+ webid +'> .\n';
    return turtle;
  }

  // RENDER
  /**
  * render screen
  */
  $scope.render = function() {
  };

  /**
  * Refresh
  */
  $scope.refresh = function() {
    $scope.render();
  };

  /**
  * openDialog opens a dialog box
  * @param  {String} elem  The element to display
  */
  $scope.openDialog = function(elem) {
    LxDialogService.open(elem);
    $(document).keyup(function(e) {
      if (e.keyCode===27) {
        LxDialogService.close(elem);
      }
    });
  };

  // SOCKETS
  //
  //
  /**
  * Get wss from URI
  * @param  {String} uri The URI to use
  */
  function getWss(uri) {
    return 'wss://' + uri.split('/')[2];
  }

  /**
  * Connect to a web socket
  * @param  {String}  sub Where to subscribe to
  * @param  {boolean} quiet dont ping server
  */
  function connectToSocket(sub, quiet) {
    // Some servers time out after 5 minutes inactive
    var INTERVAL  = 240 * 1000;
    var RECONNECT = 60 * 1000;

    if ($scope.socket) return;

    var socket;

    var wss = getWss(sub);
    console.log('connecting to : ' + wss);

    socket = new WebSocket(wss);

    socket.onopen = function(){
      console.log(sub);
      $scope.socket = socket;
      socket.send('sub ' + sub, socket);

      if (!quiet) {
        setInterval(function() { socket.send('ping'); }, INTERVAL);
      }

    };

    socket.onerror = function(){
      console.log('socket error');
      setTimeout(connect, RECONNECT);
    };

    socket.onclose = function(){
      console.log('socket closed');
      setTimeout(connect, RECONNECT);
    };

    socket.onmessage = function(msg) {
      var a = msg.data.split(' ');
      if (a[0] !== 'pub') return;
      processSocket(a[1]);
    };

  }

  /**
  * Process message from socket
  * @param  {String} uri uri that has changed
  */
  function processSocket(uri) {
    console.log(uri);

    $scope.invalidate(uri);
    $scope.audio.play();
  }

  $scope.initApp();

});

/**
* Escape URIs filter
*/
App.filter('escape', function() {
  return window.encodeURIComponent;
});
<commit_msg>Add list of foods<commit_after>

// for debug only
var __kb;
var __scope;

/**
* The main app
*/
var App = angular.module('Nutrition', [
  'ngAudio',
  'lumx'
]);

App.config(function($locationProvider) {
  $locationProvider
  .html5Mode({ enabled: true, requireBase: false });
});

App.controller('Main', function($scope, $http, $location, $timeout, ngAudio, LxNotificationService, LxProgressService, LxDialogService) {
  // Namespaces
  var CHAT  = $rdf.Namespace("https://ns.rww.io/chat#");
  var CURR  = $rdf.Namespace("https://w3id.org/cc#");
  var DCT   = $rdf.Namespace("http://purl.org/dc/terms/");
  var FACE  = $rdf.Namespace("https://graph.facebook.com/schema/~/");
  var FOAF  = $rdf.Namespace("http://xmlns.com/foaf/0.1/");
  var LIKE  = $rdf.Namespace("http://ontologi.es/like#");
  var LDP   = $rdf.Namespace("http://www.w3.org/ns/ldp#");
  var MBLOG = $rdf.Namespace("http://www.w3.org/ns/mblog#");
  var NUT   = $rdf.Namespace("https://melvincarvalho.github.io/nutrition/ns/nutrition.ttl#");
  var OWL   = $rdf.Namespace("http://www.w3.org/2002/07/owl#");
  var PIM   = $rdf.Namespace("http://www.w3.org/ns/pim/space#");
  var RDF   = $rdf.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
  var RDFS  = $rdf.Namespace("http://www.w3.org/2000/01/rdf-schema#");
  var SIOC  = $rdf.Namespace("http://rdfs.org/sioc/ns#");
  var SOLID = $rdf.Namespace("http://www.w3.org/ns/solid/app#");
  var TMP   = $rdf.Namespace("urn:tmp:");

  var f,g;

  var defaultStorageURI = 'https://nutrition.databox.me/Public/nutrition/test';
  var doap = 'https://melvincarvalho.github.io/nutrition/doap.ttl#this';
  var defaultInbox = 'https://melvin.databox.me/Public/inbox';

  // INIT
  /**
  * Init app
  */
  $scope.initApp = function() {
    $scope.init();
  };

  /**
  * Set Initial variables
  */
  $scope.init = function() {

    $scope.initRDF();
    $scope.initUI();

    /*
    $scope.initRDF();
    $scope.initQueryString();
    $scope.initLocalStorage();
    */

    __kb = g;
    __scope = $scope;
  };

  /**
  * Init UI
  */
  $scope.initUI = function() {
    $scope.initialized = true;
    $scope.loggedIn = false;
    $scope.loginTLSButtonText = "Login";
    $scope.audio = ngAudio.load('audio/button-3.mp3');
    $scope.inbox = defaultInbox;

    $scope.foods = [
      { "name" : "BIO jogurt selský: Bílý Hollandia", "uri" : "urn:tmp:0"},
      { "name" : "Bio Olmíci jogurt bílý 110 g Olma", "uri" : "urn:tmp:1"},
      { "name" : "Caesar s kuřetem a krutony titbit", "uri" : "urn:tmp:2"},
      { "name" : "Count on Us Beef Lasagne Marks & Spencer", "uri" : "urn:tmp:3"},
      { "name" : "Count on Us Chicken Jalfrezi With Spiced Basmati Rice Marks and Spencer", "uri" : "urn:tmp:4"},
      { "name" : "Count on Us Strawberry Trifle Marks and Spencer", "uri" : "urn:tmp:5"},
      { "name" : "Count on Us Thai Green Curry Marks and Spencer", "uri" : "urn:tmp:6"},
      { "name" : "countrylife Zapečené těstoviny s listovým špenátem a žampiony (1, 6, 9) Královská zelenina v kešu krému (8, 9) Bramborová kaše (6) Zelňačka s tempehem (6, 9)", "uri" : "urn:tmp:7"},
      { "name" : "Cous-Cous s grilovaným kuřetem a zeleninou Titbit", "uri" : "urn:tmp:8"},
      { "name" : "Freekeh se zeleninou a opraženou slunečnicí (1, 9) Ďobáčky s dýní (6, 9, 10) Bramborová kaše (6) Polévka čočková (9)", "uri" : "urn:tmp:9"},
      { "name" : "Glass of water", "uri" : "urn:tmp:10"},
      { "name" : "Guláš se seitanem, hlívou ústřičnou a polentou (1, 6, 9) Rýžový nákyp s ovocem a ořechy (6, 8) Polévka brokolicová (6, 9)", "uri" : "urn:tmp:11"},
      { "name" : "HONEY ROAST HAM & MATURE CHEDDAR CHEESE Marks and Spencer", "uri" : "urn:tmp:12"},
      { "name" : "NAŠE BIO DEZERT Z TVAROHU A JOGURTU VANILKOVÝ", "uri" : "urn:tmp:13"},
      { "name" : "Naše BIO jogurt bílý", "uri" : "urn:tmp:14"},
      { "name" : "Naše BIO jogurt borůvkový", "uri" : "urn:tmp:15"},
      { "name" : "Naše Bio Jogurt jablko se skořicí", "uri" : "urn:tmp:16"},
      { "name" : "NAŠE BIO JOGURT JABLKO SKOŘICE.", "uri" : "urn:tmp:17"},
      { "name" : "NAŠE BIO JOGURT JABLKO SKOŘICE", "uri" : "urn:tmp:18"},
      { "name" : "Naše BIO jogurt jahodový", "uri" : "urn:tmp:19"},
      { "name" : "Naše BIO jogurt malinový", "uri" : "urn:tmp:20"},
      { "name" : "NAŠE BIO JOGURT S MARCIPÁNEM A MÁKEM", "uri" : "urn:tmp:21"},
      { "name" : "Naše Bio Vanilkový dezert", "uri" : "urn:tmp:22"},
      { "name" : "Pohankovy salat s grilovanou zeleninou a uzenym tempehem veganz cz", "uri" : "urn:tmp:23"},
      { "name" : "Slanina & vejce s hořčičným dresinkem titbit", "uri" : "urn:tmp:24"},
      { "name" : "Slanina & vejce s hořčičným dresinkem Titbit", "uri" : "urn:tmp:25"},
      { "name" : "Sprinton BOLOGNESE", "uri" : "urn:tmp:26"},
      { "name" : "Sprinton MASOVÝ", "uri" : "urn:tmp:27"},
      { "name" : "Sprinton MEXICANA", "uri" : "urn:tmp:28"},
      { "name" : "Sprinton PIKANTNÍ SEKANÁ", "uri" : "urn:tmp:29"},
      { "name" : "Sprinton SELSKÝ", "uri" : "urn:tmp:30"},
      { "name" : "Sprinton ŠUNKOVÝ", "uri" : "urn:tmp:31"},
      { "name" : "Sušená rajčata & prosciutto salát s hořčičným dresinkem Titbit", "uri" : "urn:tmp:32"},
      { "name" : "TVAROHOVÝ DEZERT S JOGURTEM BRUSINKOVÝ", "uri" : "urn:tmp:33"},
      { "name" : "TVAROHOVÝ DEZERT S JOGURTEM JAHODOVÝ NAŠE BIO", "uri" : "urn:tmp:34"},
      { "name" : "Vietnamese Style Marinated Pork Salad Bites Marks and Spencer", "uri" : "urn:tmp:35"},
      { "name" : "Wrap s quinoou a tempehem", "uri" : "urn:tmp:36"},
    ];

    $scope.selects = {
      selectedFood: undefined,
    };

  };

  /**
  * Get values from localStorage
  */
  $scope.initLocalStorage = function() {
    if (localStorage.getItem('user')) {
      var user = JSON.parse(localStorage.getItem('user'));
      $scope.loginSuccess(user);
    }
  };

  /**
  * init RDF knowledge base
  */
  $scope.initRDF = function() {
    var PROXY = "https://rww.io/proxy.php?uri={uri}";
    var AUTH_PROXY = "https://rww.io/auth-proxy?uri=";
    var TIMEOUT = 90000;
    $rdf.Fetcher.crossSiteProxyTemplate=PROXY;

    g = $rdf.graph();
    f = $rdf.fetcher(g, TIMEOUT);
  };

  /**
  * init from query string
  */
  $scope.initQueryString = function() {
    $scope.storageURI = defaultStorageURI;
    if ($location.search().storageURI) {
      $scope.storageURI = $location.search().storageURI;
    }
    $scope.setStorageURI($scope.storageURI);
  };

  /**
  * setStorageURI set the storage URI for words
  * @param  {String} the storage URI for words
  */
  $scope.setStorageURI = function(storageURI) {
    $scope.storageURI = storageURI;
    $location.search('storageURI', $scope.storageURI);
  };

  // AUTH
  /**
  * TLS Login with WebID
  */
  $scope.TLSlogin = function() {
    var AUTHENDPOINT = "https://databox.me/";
    $scope.loginTLSButtonText = 'Logging in...';
    $http({
      method: 'HEAD',
      url: AUTHENDPOINT,
      withCredentials: true
    }).success(function(data, status, headers) {
      var header = 'User';
      var scheme = 'http';
      var user = headers(header);
      if (user && user.length > 0 && user.slice(0,scheme.length) === scheme) {
        $scope.loginSuccess(user);
      } else {
        $scope.notify('WebID-TLS authentication failed.', 'error');
      }
      $scope.loginTLSButtonText = 'Login';
    }).error(function(data, status, headers) {
      $scope.notify('Could not connect to auth server: HTTP '+status);
      $scope.loginTLSButtonText = 'Login';
    });
  };

  /**
  * loginSuccess called after successful login
  * @param  {String} user the logged in user
  */
  $scope.loginSuccess = function(user) {
    $scope.notify('Login Successful!');
    $scope.loggedIn = true;
    $scope.user = user;
    $scope.fetchAll();
    localStorage.setItem('user', JSON.stringify(user));
  };

  /**
  * Logout
  */
  $scope.logout = function() {
    $scope.init();
    $scope.notify('Logout Successful!');
    localStorage.removeItem('user');
  };

  // FETCH functions
  //
  //
  $scope.fetchAll = function() {
  };

  /**
  * Invalidate a cached URI
  * @param  {String} uri The URI to invalidate
  */
  $scope.invalidate = function(uri) {
    console.log('invalidate : ' + uri);
    f.unload(uri);
    f.refresh($rdf.sym(uri));
  };

  /**
  * fetchSeeAlso fetches the see also
  */
  $scope.fetchSeeAlso = function() {
    var seeAlso = 'https://melvincarvalho.github.io/nutrition/data/seeAlso.ttl';
    if ($location.search().seeAlso) {
      seeAlso = $location.search().seeAlso;
    }
    f.nowOrWhenFetched(seeAlso, undefined, function(ok, body) {
      console.log('seeAlso fetched from : ' + seeAlso);
    });

  };

  /**
  * Save the nutrtion
  */
  $scope.save = function() {
    var nutrition = $scope.nutrition || $scope.selects.food.name;
    if (!nutrition) {
      LxNotificationService.error('nutrition is empty');
      return;
    }
    console.log(nutrition);

    var message = "#nutrition: you consumed "+ nutrition +".";
    var img = 'https://melvincarvalho.github.io/nutrition/images/icon.png';
    var post = createPost($scope.user, message, doap, img);

    console.log('writing to : ' + $scope.inbox);
    console.log(post);
    $http({
      method: 'POST',
      url: $scope.inbox,
      withCredentials: true,
      headers: {
        "Content-Type": "text/turtle"
      },
      data: post,
    }).
    success(function(data, status, headers) {
      $scope.notify('Post saved');
      $scope.render();
    }).
    error(function(data, status, headers) {
      $scope.notify('could not save nutrition', 'error');
    });

  };

  // HELPER
  /**
  * Notify
  * @param  {String} message the message to display
  * @param  {String} type the type of notification, error or success
  */
  $scope.notify = function(message, type) {
    console.log(message);
    if (type === 'error') {
      LxNotificationService.error(message);
    } else {
      LxNotificationService.success(message);
    }
  };

  /**
  * create a post in turtle
  * @param  {string} webid       the creator
  * @param  {string} message     the message to send
  * @param  {string} application application that created it
  * @param  {string} img         img for that post
  * @return {string}             the message in turtle
  */
  function createPost(webid, message, application, img) {
    var turtle;
    turtle = '<#this> ';
    turtle += '    <http://purl.org/dc/terms/created> "'+ new Date().toISOString() +'"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;\n';
    turtle += '    <http://purl.org/dc/terms/creator> <' + webid + '> ;\n';
    turtle += '    <http://rdfs.org/sioc/ns#content> "'+ message.trim() +'" ;\n';
    turtle += '    a <http://rdfs.org/sioc/ns#Post> ;\n';

    if (application) {
      turtle += '    <http://www.w3.org/ns/solid/app#application> <' + application + '> ;\n';
    }

    if (img) {
      turtle += '    <http://xmlns.com/foaf/0.1/img> <' + img + '> ;\n';
    }

    turtle += '    <http://www.w3.org/ns/mblog#author> <'+ webid +'> .\n';
    return turtle;
  }

  // RENDER
  /**
  * render screen
  */
  $scope.render = function() {
  };

  /**
  * Refresh
  */
  $scope.refresh = function() {
    $scope.render();
  };

  /**
  * openDialog opens a dialog box
  * @param  {String} elem  The element to display
  */
  $scope.openDialog = function(elem) {
    LxDialogService.open(elem);
    $(document).keyup(function(e) {
      if (e.keyCode===27) {
        LxDialogService.close(elem);
      }
    });
  };

  // SOCKETS
  //
  //
  /**
  * Get wss from URI
  * @param  {String} uri The URI to use
  */
  function getWss(uri) {
    return 'wss://' + uri.split('/')[2];
  }

  /**
  * Connect to a web socket
  * @param  {String}  sub Where to subscribe to
  * @param  {boolean} quiet dont ping server
  */
  function connectToSocket(sub, quiet) {
    // Some servers time out after 5 minutes inactive
    var INTERVAL  = 240 * 1000;
    var RECONNECT = 60 * 1000;

    if ($scope.socket) return;

    var socket;

    var wss = getWss(sub);
    console.log('connecting to : ' + wss);

    socket = new WebSocket(wss);

    socket.onopen = function(){
      console.log(sub);
      $scope.socket = socket;
      socket.send('sub ' + sub, socket);

      if (!quiet) {
        setInterval(function() { socket.send('ping'); }, INTERVAL);
      }

    };

    socket.onerror = function(){
      console.log('socket error');
      setTimeout(connect, RECONNECT);
    };

    socket.onclose = function(){
      console.log('socket closed');
      setTimeout(connect, RECONNECT);
    };

    socket.onmessage = function(msg) {
      var a = msg.data.split(' ');
      if (a[0] !== 'pub') return;
      processSocket(a[1]);
    };

  }

  /**
  * Process message from socket
  * @param  {String} uri uri that has changed
  */
  function processSocket(uri) {
    console.log(uri);

    $scope.invalidate(uri);
    $scope.audio.play();
  }

  $scope.initApp();

});

/**
* Escape URIs filter
*/
App.filter('escape', function() {
  return window.encodeURIComponent;
});
<|endoftext|>


<commit_before>(function (angular) {
    'use strict';

    angular.module('djangularRestFramework', [
        'drf-config',
        'drf-provider'
    ]);

}(window.angular));
<commit_msg>Add the filter to the init file.<commit_after>(function (angular) {
    'use strict';

    angular.module('djangularRestFramework', [
        'drf-config',
        'drf-provider',
        'drf-display-name-filter'
    ]);

}(window.angular));
<|endoftext|>


<commit_before>"use babel";

import React from 'react';
import * as Path from 'path';
import LineCount from './LineCount';
var _ = require('lodash');

const defaultLoc = {
    start: {line:0, column:0},
    end: {line:0, column:0},
};

export class Entity extends React.Component {
    render() {
        const props = this.props;
        const entity = props.entity;
        const type = entity.type;
        const C = components.hasOwnProperty(type)? components[type] : EntityName;

        return
                <C {...props} onMouseOver={null}/>
        ;
    }
}

export function CssClass({entity}) {
    return
        .<EntityName entity={entity} style={{color: '#5a4'}} />

}

class Class extends React.Component {
    render() {
        const entity = this.props.entity;
        const icons = ;
        return
            <EntityName entity={entity} icons={icons}/>
            {
                !this.props.short &&

                {
                    entity.functions.map(meth =>
<Function entity={meth} />
)
                }

            }
        ;
    }
}

function Import({entity}) {
    return

        {entity.name} from
         {entity.originalSource}

;
}
function Lines({entity}) {
    const loc = entity.data[0];
    return <LineCount lines={loc} />
}

var components = {
    'class': Class,
    'import': Import,
    'function': Function,
    lines: Lines,
    label: Ignored,
    rnd: Ignored,
    cssClass: CssClass,
    providesModule: Ignored,
    'imported by': ImportedBy,
    'preview': Preview,
    'module.exports': ModuleExports,
    todo: Todo,

    angularModule: AngularModule,
    angularModuleDependency: AngularModuleDependency,
    directives: Directives,
    controllers: Controllers,
    services: Services,
    exports: Exports,
    objectLiteral: ObjectLiteral,
    jsxCustomElement: JsxCustomElement,
};

function JsxCustomElement({entity}) {
    return <EntityName
        style={{color: '#61dafb'}}
        entity={entity}
        name={'<' + entity.name + ' />'} />;

}

function trimArray(arr) {
    if (arr.length > 4) {
        return arr.slice(0, 3).concat('...');
    }
    return arr;
}

function ObjectLiteral({entity}) {
    let props = trimArray(Object.keys(entity.props));
    const displayName = [
        //{'{..}'},
        //,
        '🍏',
        entity.name || '[object]',
         ({props.join(', ')})
    ];
    return
        <EntityName
            entity={entity}
            name={displayName}
        />

}

function Exports({entity}) {
    return

    {
        entity.data.map(item =>
{item}
)
    }

;
}

function Directives({entity}) {
    const icons = ;
    return

    {
        entity.data.map(
            e => <EntityName entity={{name: e}} icons={icons}/>
        )
    }

;
}

function Controllers({entity}) {
    const icons =
    return

    {
        entity.data.map(
            e => <EntityName entity={{name: e}} icons={icons}/>
        )
    }

;
}

function Services({entity}) {
    const icons =
    return

    {
        entity.data.map(
            e => <EntityName entity={{name: e}} icons={icons}/>
        )
    }

;
}

function AngularModuleDependency({entity}) {
    const icons =
    return <EntityName entity={entity} icons={icons} />;
}

function AngularModule({entity}) {
    const icons = ;
    return <EntityName entity={entity} icons={icons} />;
}

function Todo({entity}) {
    const icons = ;
    return <EntityName entity={entity} icons={icons} />

}

function ModuleExports({entity}) {
    return
{entity.data.join(', ')}

}

function Function({entity, short}) {
    let icons = [];
    let lineCount = '?';
    if (entity.loc) {
        lineCount = entity.loc.end.line - entity.loc.start.line + 1;
    }
    let locStyle = {};
    let isLong = true;
    if (lineCount >= 100) {
        locStyle = {color: '#a60'}
    } else if (lineCount >= 50) {
        locStyle = {color: '#a93'}
    } else if (lineCount >= 25) {
        locStyle = {};
    } else
        isLong = false;
    locStyle.paddingTop = 8;
    locStyle.display = 'inline-block';

    if (entity.isMethod) {
        icons.push(M)
    }

    if (entity.jsx) {
        //icons += ' <JSX />';
        icons.push({'<JSX />'});
    }

    const params = trimArray(entity.params).map(p => p.name || p).join(', ');
    // const name =
    //     {entity.name}({params})
    //
    const name = ['λ ', entity.name, '(' , {params} , ')'];
    return
        {
            !short && isLong &&
                {lineCount} lines
        }
        <EntityName entity={entity} name={name} icons={icons}/>

}

function Log({entity}) {
    return
{JSON.stringify(entity)}
;
}

function Preview({entity}) {
    if (entity.html)
        return

    return entity.preview;
}

function ImportedBy({entity}) {
    return

        {
            entity.data.map(file =>

                    {Path.basename(file.path)}

            )
        }

}
function Ignored() {
    return
}

function Label({entity}) {
    return
        {entity.data} ;

}

export function EntityName({name, entity, icons, style}) {
    const loc = entity.loc || defaultLoc;
    const finalName = name || entity.name || entity.data || '(no name)';
        return
            {icons? {icons}  : ''}
            {finalName}
}

function split(filter, arr) {
    var yes = [], no = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        const item = arr[i];
        filter(item)? yes.push(item) : no.push(item);
    }
    return [yes, no];
}
var ignored = ['rnd', 'providesModule'];
export class Structure extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            phrase: ''
        };
    }
    renderEntity(entity) {
            const onClick = this.props.onClickEntity;
            return

{entity.type}

             <Entity entity={entity}/>

;

    }
    componentDidMount() {
        this.refs.search.focus();
    }
    componentDidUpdate() {

    }
    render() {
        const arrays = split(item => item.type == 'label', this.props.metadata);
        const labels = arrays[0];
        function filterByPhrase(item) {
            const phrase = this.state.phrase;
            if (!phrase) {
                // no filter phrase, so show everything
                return true;
            }
            //const indexOfColon =
            const indexOfColon = phrase.indexOf(':');
            if (indexOfColon != -1) {
                const propValue = phrase.substr(indexOfColon + 1).toLowerCase();

                const propNames = phrase.substr(0, indexOfColon).split('.');
                if (propNames[0] == 't') {
                    propNames[0] = 'type';
                }
                const q = propNames.join('.');

                const foundValue = _.get(item, q);

                if (foundValue) {
                    if (!isNaN(propValue)) {
                        return (foundValue + '') == propValue;
                    } else
                        return (foundValue + '').toLowerCase().indexOf(propValue) != -1;
                }
                return false;

            }
            if (item.name) {
                const nameToCompare = item.name.toLowerCase();
                const phraseToCompare = this.state.phrase.toLowerCase();
                return nameToCompare.indexOf(phraseToCompare) != -1;
            }
            return false;
        }
        const metadata = arrays[1]
            .filter(item => ignored.indexOf(item.type) == -1)
            .filter(filterByPhrase.bind(this));

        return

            {
                labels.map(label => )
            }

                <input
                    type="text"
                    style={{
                        color: 'black',
                        border: '1px solid grey',
                        margin: '4px',
                        width: '100%',
                    }}
                    placeholder="filter (e.g. foo, or type:function)"
                    value={this.state.phrase}
                    ref="search"
                    className="lupa-search"
                    onChange={e => this.setState({phrase: e.target.value})}
                />

            {
                metadata.map(this.renderEntity.bind(this))
            }

;
    }
}
<commit_msg>correct searching<commit_after>"use babel";

import React from 'react';
import * as Path from 'path';
import LineCount from './LineCount';
var _ = require('lodash');

const defaultLoc = {
    start: {line:0, column:0},
    end: {line:0, column:0},
};

export class Entity extends React.Component {
    render() {
        const props = this.props;
        const entity = props.entity;
        const type = entity.type;
        const C = components.hasOwnProperty(type)? components[type] : EntityName;

        return
                <C {...props} onMouseOver={null}/>
        ;
    }
}

export function CssClass({entity}) {
    return
        .<EntityName entity={entity} style={{color: '#5a4'}} />

}

class Class extends React.Component {
    render() {
        const entity = this.props.entity;
        const icons = ;
        return
            <EntityName entity={entity} icons={icons}/>
            {
                !this.props.short &&

                {
                    entity.functions.map(meth =>
<Function entity={meth} />
)
                }

            }
        ;
    }
}

function Import({entity}) {
    return

        {entity.name} from
         {entity.originalSource}

;
}
function Lines({entity}) {
    const loc = entity.data[0];
    return <LineCount lines={loc} />
}

var components = {
    'class': Class,
    'import': Import,
    'function': Function,
    lines: Lines,
    label: Ignored,
    rnd: Ignored,
    cssClass: CssClass,
    providesModule: Ignored,
    'imported by': ImportedBy,
    'preview': Preview,
    'module.exports': ModuleExports,
    todo: Todo,

    angularModule: AngularModule,
    angularModuleDependency: AngularModuleDependency,
    directives: Directives,
    controllers: Controllers,
    services: Services,
    exports: Exports,
    objectLiteral: ObjectLiteral,
    jsxCustomElement: JsxCustomElement,
};

function JsxCustomElement({entity}) {
    return <EntityName
        style={{color: '#61dafb'}}
        entity={entity}
        name={'<' + entity.name + ' />'} />;

}

function trimArray(arr) {
    if (arr.length > 4) {
        return arr.slice(0, 3).concat('...');
    }
    return arr;
}

function ObjectLiteral({entity}) {
    let props = trimArray(Object.keys(entity.props));
    const displayName = [
        //{'{..}'},
        //,
        '🍏',
        entity.name || '[object]',
         ({props.join(', ')})
    ];
    return
        <EntityName
            entity={entity}
            name={displayName}
        />

}

function Exports({entity}) {
    return

    {
        entity.data.map(item =>
{item}
)
    }

;
}

function Directives({entity}) {
    const icons = ;
    return

    {
        entity.data.map(
            e => <EntityName entity={{name: e}} icons={icons}/>
        )
    }

;
}

function Controllers({entity}) {
    const icons =
    return

    {
        entity.data.map(
            e => <EntityName entity={{name: e}} icons={icons}/>
        )
    }

;
}

function Services({entity}) {
    const icons =
    return

    {
        entity.data.map(
            e => <EntityName entity={{name: e}} icons={icons}/>
        )
    }

;
}

function AngularModuleDependency({entity}) {
    const icons =
    return <EntityName entity={entity} icons={icons} />;
}

function AngularModule({entity}) {
    const icons = ;
    return <EntityName entity={entity} icons={icons} />;
}

function Todo({entity}) {
    const icons = ;
    return <EntityName entity={entity} icons={icons} />

}

function ModuleExports({entity}) {
    return
{entity.data.join(', ')}

}

function Function({entity, short}) {
    let icons = [];
    let lineCount = '?';
    if (entity.loc) {
        lineCount = entity.loc.end.line - entity.loc.start.line + 1;
    }
    let locStyle = {};
    let isLong = true;
    if (lineCount >= 100) {
        locStyle = {color: '#a60'}
    } else if (lineCount >= 50) {
        locStyle = {color: '#a93'}
    } else if (lineCount >= 25) {
        locStyle = {};
    } else
        isLong = false;
    locStyle.paddingTop = 8;
    locStyle.display = 'inline-block';

    if (entity.isMethod) {
        icons.push(M)
    }

    if (entity.jsx) {
        //icons += ' <JSX />';
        icons.push({'<JSX />'});
    }

    const params = trimArray(entity.params).map(p => p.name || p).join(', ');
    // const name =
    //     {entity.name}({params})
    //
    const name = ['λ ', entity.name, '(' , {params} , ')'];
    return
        {
            !short && isLong &&
                {lineCount} lines
        }
        <EntityName entity={entity} name={name} icons={icons}/>

}

function Log({entity}) {
    return
{JSON.stringify(entity)}
;
}

function Preview({entity}) {
    if (entity.html)
        return

    return entity.preview;
}

function ImportedBy({entity}) {
    return

        {
            entity.data.map(file =>

                    {Path.basename(file.path)}

            )
        }

}
function Ignored() {
    return
}

function Label({entity}) {
    return
        {entity.data} ;

}

export function EntityName({name, entity, icons, style}) {
    const loc = entity.loc || defaultLoc;
    const finalName = name || entity.name || entity.data || '(no name)';
        return
            {icons? {icons}  : ''}
            {finalName}
}

function split(filter, arr) {
    var yes = [], no = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        const item = arr[i];
        filter(item)? yes.push(item) : no.push(item);
    }
    return [yes, no];
}
var ignored = ['rnd', 'providesModule'];
export class Structure extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            phrase: ''
        };
    }
    renderEntity(entity) {
            const onClick = this.props.onClickEntity;
            return

{entity.type}

             <Entity entity={entity}/>

;

    }
    componentDidMount() {
        this.refs.search.focus();
    }
    componentDidUpdate() {

    }
    render() {
        const arrays = split(item => item.type == 'label', this.props.metadata);
        const labels = arrays[0];
        function filterByPhrase(item) {
            const phrase = this.state.phrase;
            if (!phrase) {
                // no filter phrase, so show everything
                return true;
            }
            //const indexOfColon =
            const indexOfColon = phrase.indexOf(':');
            if (indexOfColon != -1) {
                const propValue = phrase.substr(indexOfColon + 1).toLowerCase();

                const propNames = phrase.substr(0, indexOfColon).split('.');
                if (propNames[0] == 't') {
                    propNames[0] = 'type';
                }
                const q = propNames.join('.');

                const foundValue = _.get(item, q);

                // there is defined property in object
                if (foundValue !== undefined) {
                    if (!propValue) { // if user entered only property name
                        return true;
                    }
                    if (!isNaN(propValue)) {
                        return (foundValue + '') == propValue;
                    } else
                        return (foundValue + '').toLowerCase().indexOf(propValue) != -1;
                }
                return false;

            }
            if (item.name) {
                const nameToCompare = item.name.toLowerCase();
                const phraseToCompare = this.state.phrase.toLowerCase();
                return nameToCompare.indexOf(phraseToCompare) != -1;
            }
            return false;
        }
        const metadata = arrays[1]
            .filter(item => ignored.indexOf(item.type) == -1)
            .filter(filterByPhrase.bind(this));

        return

            {
                labels.map(label => )
            }

                <input
                    type="text"
                    style={{
                        color: 'black',
                        border: '1px solid grey',
                        margin: '4px',
                        width: '100%',
                    }}
                    placeholder="filter (e.g. foo, or type:function)"
                    value={this.state.phrase}
                    ref="search"
                    className="lupa-search"
                    onChange={e => this.setState({phrase: e.target.value})}
                />

            {
                metadata.map(this.renderEntity.bind(this))
            }

;
    }
}
<|endoftext|>


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

const minimumLength = 1;
const Console = console;

function longestPathRanking (graph) {
  const visited = {};

  function dfs (nodeName) {
    const node = graph.getNode(nodeName);
    if (_.has(visited, nodeName)) {
      return node.rank;
    }
    visited[nodeName] = true;

    let rank = _.min(_.map(graph.outgoingEdges(nodeName), edge => dfs(edge.target) - minimumLength));
    if (rank === undefined) {
      rank = 0;
    }
    return (node.rank = rank);
  }

  _.each(graph.entryNodes(), dfs);
}

function normalizeRanks (graph) {
  let i;
  let lowestRank = Infinity;
  // First make the ranks positive
  for (i = 0; i < graph.nodes.length; i++) {
    if (graph.nodes[i].rank < lowestRank) {
      lowestRank = graph.nodes[i].rank;
    }
  }
  for (i = 0; i < graph.nodes.length; i++) {
    graph.nodes[i].rank = graph.nodes[i].rank - lowestRank;
  }
}

function forceSecondaryRankPromotions (graph, entryNodeName) {
  let entryNodes = graph.entryNodes();
  if (entryNodeName) {
    if (entryNodes.includes(entryNodeName)) {
      entryNodes = [entryNodeName];
    } else {
      Console.warn(`Attempted to force secondary rank promotions for entry node, ${entryNodeName},  which does not exist. Using all entry nodes.`);
    }
  }
  for (let i = 0; i < entryNodes.length; i++) {
    const outgoingNodes = graph.outgoingNodes(entryNodes[i]);
    for (let j = 0; j < outgoingNodes.length; j++) {
      const node = graph.getNode(outgoingNodes[j]);
      node.rank = 1;
    }
  }
}

module.exports = {
  longestPathRanking: longestPathRanking,
  normalizeRanks: normalizeRanks,
  forceSecondaryRankPromotions: forceSecondaryRankPromotions
};
<commit_msg>Bug fix / clean up layout worker.<commit_after>/**
 *
 *  Copyright 2016 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
import _ from 'lodash';

const minimumLength = 1;
const Console = console;

function longestPathRanking (graph) {
  const visited = {};

  function dfs (nodeName) {
    const node = graph.getNode(nodeName);
    if (!node) { return; }
    if (!_.has(visited, nodeName)) {
      visited[nodeName] = true;

      let rank = _.min(_.map(graph.outgoingEdges(nodeName), edge => dfs(edge.target) - minimumLength));
      if (rank === undefined) {
        rank = 0;
      }
      node.rank = rank;
    }
    return node.rank;
  }

  _.each(graph.entryNodes(), dfs);
}

function normalizeRanks (graph) {
  let i;
  let lowestRank = Infinity;
  // First make the ranks positive
  for (i = 0; i < graph.nodes.length; i++) {
    if (graph.nodes[i].rank < lowestRank) {
      lowestRank = graph.nodes[i].rank;
    }
  }
  for (i = 0; i < graph.nodes.length; i++) {
    graph.nodes[i].rank = graph.nodes[i].rank - lowestRank;
  }
}

function forceSecondaryRankPromotions (graph, entryNodeName) {
  let entryNodes = graph.entryNodes();
  if (entryNodeName) {
    if (entryNodes.includes(entryNodeName)) {
      entryNodes = [entryNodeName];
    } else {
      Console.warn(`Attempted to force secondary rank promotions for entry node, ${entryNodeName},  which does not exist. Using all entry nodes.`);
    }
  }
  for (let i = 0; i < entryNodes.length; i++) {
    const outgoingNodes = graph.outgoingNodes(entryNodes[i]);
    for (let j = 0; j < outgoingNodes.length; j++) {
      const node = graph.getNode(outgoingNodes[j]);
      node.rank = 1;
    }
  }
}

module.exports = {
  longestPathRanking: longestPathRanking,
  normalizeRanks: normalizeRanks,
  forceSecondaryRankPromotions: forceSecondaryRankPromotions
};
<|endoftext|>


<commit_before>'use strict'

const Trailpack = require('trailpack')

module.exports = class SmokesignalsTrailpack extends Trailpack {
  constructor(app, config) {
    super(app, {
      pkg: {
        name: 'trailpack-smokesignals'
      },
      config: config || { }
    })
  }

  /**
   * Wait for some stuff so that the process does not exit.
   */
  configure() {
    this.interval = setInterval(function () { }, Math.POSITIVE_INFINITY)
  }

  unload() {
    clearInterval(this.interval)
  }
}
<commit_msg>[api] add "name" arg to trailpack constructor<commit_after>'use strict'

const Trailpack = require('trailpack')

module.exports = class SmokesignalsTrailpack extends Trailpack {
  constructor(app, config, name) {
    super(app, {
      pkg: {
        name: name || 'trailpack-smokesignals'
      },
      config: config || { }
    })
  }

  /**
   * Wait for some stuff so that the process does not exit.
   */
  configure() {
    this.interval = setInterval(function () { }, Math.POSITIVE_INFINITY)
  }

  unload() {
    clearInterval(this.interval)
  }
}
<|endoftext|>


<commit_before>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var util = require('./util');
var through = require('@nuintun/through');
var gutil = require('@nuintun/gulp-util');

var join = path.join;
var relative = path.relative;

/**
 * include
 *
 * @param options
 * @returns {Stream}
 */
module.exports = function(options) {
  var initialized = false;
  var configure = util.initOptions(options);

  // stream
  return through({ objectMode: true }, function(vinyl, encoding, next) {
    // hack old vinyl
    vinyl._isVinyl = true;
    // normalize vinyl base
    vinyl.base = relative(vinyl.cwd, vinyl.base);

    // return empty vinyl
    if (vinyl.isNull()) {
      return next(null, vinyl);
    }

    // throw error if stream vinyl
    if (vinyl.isStream()) {
      return next(gutil.throwError('streaming not supported.'));
    }

    // when not initialized
    if (!initialized) {
      // debug
      util.debug('cwd: %s', gutil.colors.magenta(gutil.normalize(gutil.cwd)));

      var ignore = {};
      var base = join(vinyl.cwd, vinyl.base);

      // base out of bound of wwwroot
      if (gutil.isOutBound(base, configure.wwwroot)) {
        gutil.throwError(
          'base: %s is out of bound of wwwroot: %s.',
          gutil.normalize(base),
          gutil.normalize(configure.wwwroot)
        );
      }

      // format ignore
      configure.ignore.forEach(function(id) {
        var path;
        var alias = configure.alias;
        var paths = configure.paths;
        var vars = configure.vars;

        // parse id form alias, paths, vars
        id = util.parseAlias(id, alias);
        id = util.parsePaths(id, paths);
        id = util.parseAlias(id, alias);
        id = util.parseVars(id, vars);
        id = util.parseAlias(id, alias);

        // local id add ignore
        if (gutil.isLocal(id)) {
          if (gutil.isAbsolute(id)) {
            path = join(configure.wwwroot, id.substring(1));
          } else if (!gutil.isRelative(id)) {
            path = join(vinyl.cwd, vinyl.base, id);
          }

          if (path) {
            ignore[util.addExt(path)] = true;
          }
        }
      });

      // rewrite ignore
      configure.ignore = ignore;
      // initialized
      initialized = true;
    }

    // catch error
    try {
      // stream
      var stream = this;

      // clone options
      options = gutil.extend({}, configure);

      // lock wwwroot
      gutil.readonlyProperty(options, 'wwwroot');
      // lock plugins
      gutil.readonlyProperty(options, 'plugins');

      // transport
      util.transport(vinyl, options, function(vinyl, options) {
        var pool = {};
        var pkg = vinyl.package;
        var start = vinyl.clone();
        var end = vinyl.clone();
        var path = gutil.pathFromCwd(vinyl.path);

        // set start and end file status
        start.contents = gutil.BLANK_BUFFER;
        start.concat = gutil.CONCAT_STATUS.START;
        end.contents = gutil.BLANK_BUFFER;
        end.concat = gutil.CONCAT_STATUS.END;

        // clean vinyl
        delete start.package;
        delete end.package;

        // compute include
        options.include = gutil.isFunction(options.include)
          ? options.include(pkg.id || null, vinyl.path)
          : options.include;

        // debug
        util.debug('concat: %p start', path);
        // push start blank vinyl
        stream.push(start);
        // include dependencies files
        includeDeps.call(stream, vinyl, pool, options, function() {
          // push end blank vinyl
          stream.push(end);

          // free memory
          pool = null;

          // debug
          util.debug('concat: %p ...ok', path);
          next();
        });
      });
    } catch (error) {
      // show error message
      util.print(gutil.colors.red.bold(error.stack) + '\x07');
      next();
    }
  });
}

/**
 * create a new vinyl
 *
 * @param path
 * @param cwd
 * @param base
 * @param done
 * @returns {void}
 */
function vinylFile(path, cwd, base, done) {
  if (!gutil.isString(path)
    || !gutil.isString(cwd)
    || !gutil.isString(base)) {
    return done(null);
  }

  // cache path
  var src = path;

  // print error
  function printError(error) {
    util.print(
      'file: %s is %s',
      gutil.colors.yellow(gutil.pathFromCwd(src)),
      error.code
    );
  }

  // read file
  function readFile(path, stat) {
    fs.readFile(path, function(error, data) {
      if (error) {
        done(null);

        return printError(error);
      }

      done(new gutil.Vinyl({
        path: path,
        cwd: cwd,
        base: base,
        stat: stat,
        contents: data
      }));
    });
  }

  // read file use origin path
  fs.stat(path, function(error, stat) {
    if (error) {
      path = util.hideExt(path, true);

      // read file use hide extname path
      fs.stat(path, function(error, stat) {
        if (error) {
          done(null);

          return printError(error);
        }

        readFile(path, stat);
      });
    } else {
      readFile(path, stat);
    }
  });
}

/**
 * walk file
 *
 * @param vinyl
 * @param pool
 * @param options
 * @param done
 * @returns {void}
 */
function walk(vinyl, pool, options, done) {
  var stream = this;
  var status = pool[vinyl.path];

  /**
   * transport dependence file
   * @param module
   * @param next
   */
  function transform(module, next) {
    var path = module.path;

    if (options.ignore[path]
      || pool[path]
      || (options.include === 'relative' && !gutil.isRelative(module.id))) {
      return next();
    }
    // create a vinyl file
    vinylFile(path, vinyl.cwd, vinyl.base, function(child) {
      // read file success
      if (child === null) return next();

      // debug
      util.debug('include: %r', child.path);
      // transport file
      util.transport(child, options, function(child, options) {
        // cache next
        status.next = next;
        // add cache status
        pool[child.path] = {
          next: null,
          parent: status,
          included: false
        };

        // walk
        walk.call(stream, child, pool, options, done);
      });
    });
  }

  /**
   * include current file and flush status
   *
   * @returns {void}
   */
  function flush() {
    // push file to stream
    if (!status.included) {
      stream.push(vinyl);

      // change cache status
      status.next = null;
      status.included = true;
    }

    var parent = status.parent;

    // all file include
    if (parent === null || parent.next === null) {
      done();
    } else {
      // run parent next dependencies
      parent.next();

      // clean parent
      delete status.parent;
    }
  }

  var pkg = vinyl.package;

  // bootstrap
  if (status.included || !pkg) {
    flush();
  } else {
    gutil.async.series(pkg.include, transform, flush);
  }
}

/**
 * include dependencies file
 *
 * @param vinyl
 * @param pool
 * @param options
 * @param done
 * @returns {void}
 */
function includeDeps(vinyl, pool, options, done) {
  // return if include not equal 'all' and 'relative'
  if (options.include !== 'all' && options.include !== 'relative') {
    // push file to stream
    this.push(vinyl);

    // free memory
    pool = null;

    return done();
  }

  // set pool cache
  pool[vinyl.path] = {
    next: null,
    parent: null,
    included: false
  };

  // bootstrap
  walk.call(this, vinyl, pool, options, function() {
    // free memory
    pool = null;

    // callback
    done();
  });
}
<commit_msg>update files<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var util = require('./util');
var through = require('@nuintun/through');
var gutil = require('@nuintun/gulp-util');

var join = path.join;
var relative = path.relative;

/**
 * include
 *
 * @param options
 * @returns {Stream}
 */
module.exports = function(options) {
  var initialized = false;
  var configure = util.initOptions(options);

  // stream
  return through({ objectMode: true }, function(vinyl, encoding, next) {
    // hack old vinyl
    vinyl._isVinyl = true;
    // normalize vinyl base
    vinyl.base = relative(vinyl.cwd, vinyl.base);

    // return empty vinyl
    if (vinyl.isNull()) {
      return next(null, vinyl);
    }

    // throw error if stream vinyl
    if (vinyl.isStream()) {
      return next(gutil.throwError('streaming not supported.'));
    }

    // when not initialized
    if (!initialized) {
      // debug
      util.debug('cwd: %s', gutil.colors.magenta(gutil.normalize(gutil.cwd)));

      var ignore = {};
      var base = join(vinyl.cwd, vinyl.base);

      // base out of bound of wwwroot
      if (gutil.isOutBound(base, configure.wwwroot)) {
        gutil.throwError(
          'base: %s is out of bound of wwwroot: %s.',
          gutil.normalize(base),
          gutil.normalize(configure.wwwroot)
        );
      }

      // format ignore
      configure.ignore.forEach(function(id) {
        var path;
        var alias = configure.alias;
        var paths = configure.paths;
        var vars = configure.vars;

        // parse id form alias, paths, vars
        id = util.parseAlias(id, alias);
        id = util.parsePaths(id, paths);
        id = util.parseAlias(id, alias);
        id = util.parseVars(id, vars);
        id = util.parseAlias(id, alias);

        // local id add ignore
        if (gutil.isLocal(id)) {
          if (gutil.isAbsolute(id)) {
            path = join(configure.wwwroot, id.substring(1));
          } else if (!gutil.isRelative(id)) {
            path = join(vinyl.cwd, vinyl.base, id);
          }

          if (path) {
            ignore[util.addExt(path)] = true;
          }
        }
      });

      // rewrite ignore
      configure.ignore = ignore;
      // initialized
      initialized = true;
    }

    // catch error
    try {
      // stream
      var stream = this;

      // clone options
      options = gutil.extend({}, configure);

      // lock wwwroot
      gutil.readonlyProperty(options, 'wwwroot');
      // lock plugins
      gutil.readonlyProperty(options, 'plugins');

      // transport
      util.transport(vinyl, options, function(vinyl, options) {
        var pool = {};
        var pkg = vinyl.package;
        var start = vinyl.clone();
        var end = vinyl.clone();
        var path = gutil.pathFromCwd(vinyl.path);

        // set start and end file status
        start.contents = gutil.BLANK_BUFFER;
        start.concat = gutil.CONCAT_STATUS.START;
        end.contents = gutil.BLANK_BUFFER;
        end.concat = gutil.CONCAT_STATUS.END;

        // clean vinyl
        delete start.package;
        delete end.package;

        // compute include
        options.include = gutil.isFunction(options.include)
          ? options.include(pkg.id || null, vinyl.path)
          : options.include;

        // debug
        util.debug('concat: %p start', path);
        // push start blank vinyl
        stream.push(start);
        // include dependencies files
        includeDeps.call(stream, vinyl, pool, options, function() {
          // push end blank vinyl
          stream.push(end);

          // free memory
          pool = null;

          // debug
          util.debug('concat: %p ...ok', path);
          next();
        });
      });
    } catch (error) {
      // show error message
      util.print(gutil.colors.red.bold(error.stack) + '\x07');
      next();
    }
  });
}

/**
 * create a new vinyl
 *
 * @param path
 * @param cwd
 * @param base
 * @param done
 * @returns {void}
 */
function vinylFile(path, cwd, base, done) {
  if (!gutil.isString(path)
    || !gutil.isString(cwd)
    || !gutil.isString(base)) {
    return done(null);
  }

  // cache path
  var src = path;

  // print error
  function printError(error) {
    util.print(
      'file: %s is %s',
      gutil.colors.yellow(gutil.pathFromCwd(src)),
      error.code
    );

    done(null);
  }

  // read file
  function readFile(path, stat) {
    fs.readFile(path, function(error, data) {
      if (error) return printError(error);

      done(new gutil.Vinyl({
        path: path,
        cwd: cwd,
        base: base,
        stat: stat,
        contents: data
      }));
    });
  }

  // read file use origin path
  fs.stat(path, function(error, stat) {
    if (error) {
      path = util.hideExt(path, true);

      // read file use hide extname path
      fs.stat(path, function(error, stat) {
        if (error) return printError(error);

        readFile(path, stat);
      });
    } else {
      readFile(path, stat);
    }
  });
}

/**
 * walk file
 *
 * @param vinyl
 * @param pool
 * @param options
 * @param done
 * @returns {void}
 */
function walk(vinyl, pool, options, done) {
  var stream = this;
  var status = pool[vinyl.path];

  /**
   * transport dependence file
   * @param module
   * @param next
   */
  function transform(module, next) {
    var path = module.path;

    if (options.ignore[path]
      || pool[path]
      || (options.include === 'relative' && !gutil.isRelative(module.id))) {
      return next();
    }
    // create a vinyl file
    vinylFile(path, vinyl.cwd, vinyl.base, function(child) {
      // read file success
      if (child === null) return next();

      // debug
      util.debug('include: %r', child.path);
      // transport file
      util.transport(child, options, function(child, options) {
        // cache next
        status.next = next;
        // add cache status
        pool[child.path] = {
          next: null,
          parent: status,
          included: false
        };

        // walk
        walk.call(stream, child, pool, options, done);
      });
    });
  }

  /**
   * include current file and flush status
   *
   * @returns {void}
   */
  function flush() {
    // push file to stream
    if (!status.included) {
      stream.push(vinyl);

      // change cache status
      status.next = null;
      status.included = true;
    }

    var parent = status.parent;

    // all file include
    if (parent === null || parent.next === null) {
      done();
    } else {
      // run parent next dependencies
      parent.next();

      // clean parent
      delete status.parent;
    }
  }

  var pkg = vinyl.package;

  // bootstrap
  if (status.included || !pkg) {
    flush();
  } else {
    gutil.async.series(pkg.include, transform, flush);
  }
}

/**
 * include dependencies file
 *
 * @param vinyl
 * @param pool
 * @param options
 * @param done
 * @returns {void}
 */
function includeDeps(vinyl, pool, options, done) {
  // return if include not equal 'all' and 'relative'
  if (options.include !== 'all' && options.include !== 'relative') {
    // push file to stream
    this.push(vinyl);

    // free memory
    pool = null;

    return done();
  }

  // set pool cache
  pool[vinyl.path] = {
    next: null,
    parent: null,
    included: false
  };

  // bootstrap
  walk.call(this, vinyl, pool, options, function() {
    // free memory
    pool = null;

    // callback
    done();
  });
}
<|endoftext|>


<commit_before>import React from "react";
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {Card, CardHeader, CardTitle, CardText} from "material-ui/Card";
import {List, ListItem} from "material-ui/List";
import Divider from "material-ui/Divider";
import YQL from "./yql";

const styles = {
    column: {
        float: "left",
        width: 400,
        margin: 20
    }
}

YQL('select * from rss where url="https://news.ycombinator.com/rss"', function(data) {
    console.log(data.query.results.item);
});

const App = () => (
    <MuiThemeProvider>

                <Card>
                    <CardHeader title="Test 1" />
                    <List>
                        <ListItem primaryText="Item 1" />
                        <Divider />
                        <ListItem primaryText="Item 2" />
                        <Divider />
                        <ListItem primaryText="Item 3" />
                    </List>
                </Card>

                <Card>
                    <CardHeader title="Test 2" />
                    <List>
                        <ListItem primaryText="Item 1" />
                        <Divider />
                        <ListItem primaryText="Item 2" />
                        <Divider />
                        <ListItem primaryText="Item 3" />
                    </List>
                </Card>

    </MuiThemeProvider>
);

export default App;<commit_msg>Remove file that should have been deleted<commit_after><|endoftext|>


<commit_before>/* global cockpit, QUnit */

var root_user = {
    name: "weird-root",
    id: 0,
    groups: null
};

var priv_user = {
    name: "user",
    id: 1000,
    groups: ["user", "agroup"]
};

QUnit.module("Permission tests", {
    setup: function() {
        this.old_dbus = cockpit.dbus;
        this.old_is_superuser = cockpit._is_superuser;
        cockpit._is_superuser = false;
    },
    teardown: function() {
        cockpit.dbus = this.old_dbus;
        cockpit._is_superuser = this.old_is_superuser;
    }
});

QUnit.test("root-all-permissions", function (assert) {
    assert.expect(2);

    var p1 = cockpit.permission({ user: priv_user });
    assert.equal(p1.allowed, false, "not root, not allowed");

    var p2 = cockpit.permission({ user: root_user });
    assert.equal(p2.allowed, true, "is root, allowed");
});

QUnit.test("group-permissions", function (assert) {
    assert.expect(4);

    var p1 = cockpit.permission({ user: priv_user, group: "badgroup" });
    assert.equal(p1.allowed, false, "no group, not allowed");

    var p2 = cockpit.permission({ user: priv_user, group: "agroup" });
    assert.equal(p2.allowed, true, "has group, allowed");

    var p3 = cockpit.permission({ user: root_user, group: "agroup" });
    assert.equal(p3.allowed, true, "no group but root, allowed");

    var p4 = cockpit.permission({ user: { id: 0, groups: ["other"] }, group: "agroup" });
    assert.equal(p4.allowed, true, "no group match but root, allowed");
});

QUnit.test("admin-permissions", function (assert) {
    assert.expect(2);

    var p1 = cockpit.permission({ user: priv_user, _is_superuser: false, admin: true });
    assert.equal(p1.allowed, false, "no superuser, admin not allowed");

    var p2 = cockpit.permission({ user: priv_user, _is_superuser: true, admin: true });
    assert.equal(p2.allowed, true, "superuser, admin allowed");
});

QUnit.start();
<commit_msg>base1: Fix test setup in test-permissions.js<commit_after>/* global cockpit, QUnit */

var root_user = {
    name: "weird-root",
    id: 0,
    groups: null
};

var priv_user = {
    name: "user",
    id: 1000,
    groups: ["user", "agroup"]
};

QUnit.module("Permission tests", {
    before: () => {
        this.old_dbus = cockpit.dbus;
        this.old_is_superuser = cockpit._is_superuser;
        cockpit._is_superuser = false;
    },
    after: () => {
        cockpit.dbus = this.old_dbus;
        cockpit._is_superuser = this.old_is_superuser;
    }
});

QUnit.test("root-all-permissions", function (assert) {
    assert.expect(2);

    var p1 = cockpit.permission({ user: priv_user });
    assert.equal(p1.allowed, false, "not root, not allowed");

    var p2 = cockpit.permission({ user: root_user });
    assert.equal(p2.allowed, true, "is root, allowed");
});

QUnit.test("group-permissions", function (assert) {
    assert.expect(4);

    var p1 = cockpit.permission({ user: priv_user, group: "badgroup" });
    assert.equal(p1.allowed, false, "no group, not allowed");

    var p2 = cockpit.permission({ user: priv_user, group: "agroup" });
    assert.equal(p2.allowed, true, "has group, allowed");

    var p3 = cockpit.permission({ user: root_user, group: "agroup" });
    assert.equal(p3.allowed, true, "no group but root, allowed");

    var p4 = cockpit.permission({ user: { id: 0, groups: ["other"] }, group: "agroup" });
    assert.equal(p4.allowed, true, "no group match but root, allowed");
});

QUnit.test("admin-permissions", function (assert) {
    assert.expect(2);

    var p1 = cockpit.permission({ user: priv_user, _is_superuser: false, admin: true });
    assert.equal(p1.allowed, false, "no superuser, admin not allowed");

    var p2 = cockpit.permission({ user: priv_user, _is_superuser: true, admin: true });
    assert.equal(p2.allowed, true, "superuser, admin allowed");
});

QUnit.start();
<|endoftext|>


<commit_before>// @flow

const keycloakClient = require('./clients/keycloakClient');
const waitAndInitKeycloak = require('./util/waitAndInitKeycloak');
const logger = require('./logger');
const createServer = require('./server');

(async () => {
  const {
    JWTSECRET,
    JWTAUDIENCE,
    KEYCLOAK_ADMIN_PASSWORD,
  } = process.env;

  await waitAndInitKeycloak(keycloakClient, {
    username: 'admin',
    password: `${KEYCLOAK_ADMIN_PASSWORD || '<password not set>'}`,
    grantType: 'password',
    clientId: 'admin-cli',
  });

  logger.debug('Starting to boot the application.');

  try {
    if (JWTSECRET == null) {
      throw new Error(
        'Required environment variable JWTSECRET is undefined or null!',
      );
    }

    if (JWTAUDIENCE == null) {
      throw new Error(
        'Required environment variable JWTAUDIENCE is undefined or null!',
      );
    }

    await createServer({
      jwtSecret: JWTSECRET,
      jwtAudience: JWTAUDIENCE,
    });

    logger.debug('Finished booting the application.');
  } catch (e) {
    logger.error('Error occurred while starting the application');
    logger.error(e.stack);
  }
})();
<commit_msg>Format<commit_after>// @flow

const keycloakClient = require('./clients/keycloakClient');
const waitAndInitKeycloak = require('./util/waitAndInitKeycloak');
const logger = require('./logger');
const createServer = require('./server');

(async () => {
  const { JWTSECRET, JWTAUDIENCE, KEYCLOAK_ADMIN_PASSWORD } = process.env;

  await waitAndInitKeycloak(keycloakClient, {
    username: 'admin',
    password: `${KEYCLOAK_ADMIN_PASSWORD || '<password not set>'}`,
    grantType: 'password',
    clientId: 'admin-cli',
  });

  logger.debug('Starting to boot the application.');

  try {
    if (JWTSECRET == null) {
      throw new Error(
        'Required environment variable JWTSECRET is undefined or null!',
      );
    }

    if (JWTAUDIENCE == null) {
      throw new Error(
        'Required environment variable JWTAUDIENCE is undefined or null!',
      );
    }

    await createServer({
      jwtSecret: JWTSECRET,
      jwtAudience: JWTAUDIENCE,
    });

    logger.debug('Finished booting the application.');
  } catch (e) {
    logger.error('Error occurred while starting the application');
    logger.error(e.stack);
  }
})();
<|endoftext|>


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

	var calculateBoardLevels = function(board){
			levels = [];
			for(var i = 0; i < board.questions.length; i++) {
				if (levels.indexOf(board.questions[i].level) == -1 && board.questions[i].level != 0) {
					levels.push(board.questions[i].level);
				}
			}

			levels.sort(function (a, b) {
   				return a > b ? 1 : a < b ? -1 : 0;
			});

			return levels;
	}

	var SetAssignmentsPageController = ['$scope', 'auth', 'api', 'gameBoardTitles', '$rootScope', '$window', '$timeout', function($scope, auth, api, gameBoardTitles, $rootScope, $window, $timeout) {
		$rootScope.pageTitle = "Assign Boards";

		$scope.generateGameBoardTitle = gameBoardTitles.generate;

		$scope.myGroups = api.groupManagementEndpoint.get(); // get a list of all known groups for this user.

		$scope.openedAssignPanels = []; // shows those panels currently opened
		$scope.pendingAssignment = {}; // boardId to group id mapping - allows us to know which group is being assigned which board.

		$scope.groupAssignmentInfo = {}; // map of boardId to group list - shows groups currently assigned.

		// allows the view to change which panels are open.
		$scope.toggleAssignPanel = function(board) {
			var indexOfBoard = $scope.openedAssignPanels.indexOf(board.id);
			if ($scope.openedAssignPanels.indexOf(board.id) == -1) {
				$scope.openedAssignPanels.push(board.id);
			} else {
				$scope.openedAssignPanels.splice(indexOfBoard, 1);
			}

			if($scope.myGroups.length == 0)
           		$scope.modals.groupsWarning.show();
		}

		$scope.filterOptions = [
			{label: "All Boards", val: null},
			{label: "Not Started", val: "not_attempted"},
			{label: "In Progress", val: "in_progress"},
			{label: "Completed", val: "completed"}
		];

		$scope.sortOptions = [
			{label: "Date Created", val: "created"},
			{label: "Date Visited", val: "visited"}
		];

		$scope.filterOption = $scope.filterOptions[0];
		$scope.sortOption = $scope.sortOptions[1];

		var updateBoards = function(limit) {
			$scope.setLoading(true);
			api.userGameBoards($scope.filterOption.val, $scope.sortOption.val, 0, limit).$promise.then(function(boards) {
				$scope.boards = boards;

				updateGroupAssignmentMap($scope.boards.results)

				$scope.setLoading(false);
			})
		};

		// update boards when filters have been selected
		$scope.$watch("filterOption", function(newVal, oldVal) {
			// TODO: For some reason these watch functions are being fired for no reason
			if (newVal === oldVal) {
				return;
			}
			updateBoards();
		});

		$scope.$watch("sortOption", function(newVal, oldVal) {
			if (newVal === oldVal) {
				return;
			}
			updateBoards();
		});

		// update tooltips when this changes.
		$scope.$watch("boards.results", function(newVal, oldVal){
			$timeout(function(){
				Opentip.findElements();
			}, 0);

		}, true);

		// Perform initial load
		updateBoards();

		var mergeInProgress = false;
		$scope.loadMore = function() {
			if (mergeInProgress) return;
			mergeInProgress = true;
			$scope.setLoading(true);
			api.userGameBoards($scope.filterOption.val, $scope.sortOption.val, $scope.boards.results.length).$promise.then(function(newBoards){
				// Merge new boards into results
				updateGroupAssignmentMap(newBoards.results)

				$.merge($scope.boards.results, newBoards.results);
				$scope.setLoading(false);
				mergeInProgress = false;
			});
		};

		$scope.deleteBoard = function(board){
			lookupAssignedGroups(board).$promise.then(function(groupsAssigned) {
				if (groupsAssigned != null && groupsAssigned.length != 0){
					alert("Warning: You currently have groups assigned to this board. If you delete this your groups will still be assigned but you won't be able to see the board in your Assigned Boards or My boards page.")
				}

				var boardTitle = board.title ? board.title : $scope.generateGameBoardTitle(board);
				// Warn user before deleting
				var confirmation = confirm("You are about to delete "+ boardTitle + " board?");
				if (confirmation){
	       			// TODO: This needs to be reviewed
	       			// Currently reloading boards after delete
					$scope.setLoading(true);
	       			api.deleteGameBoard(board.id).$promise.then(function(){
				        updateBoards($scope.boards.results.length);
				        $scope.setLoading(false);
				        $scope.showToast($scope.toastTypes.Success, "Board Deleted", "You have successfully deleted the board: " + boardTitle);
	       			}).catch(function(e){
						$scope.showToast($scope.toastTypes.Failure, "Board Deletion Failed", "With error message: (" + e.status + ") "+ e.status + ") "+ e.data.errorMessage != undefined ? e.data.errorMessage : "");
	       			});
				}
			})
		}

		$scope.calculateBoardLevels = calculateBoardLevels;

		var lookupAssignedGroups = function(board) {
			var groups = api.assignments.getAssignedGroups({gameId: board.id});
			return groups;
		}

		var updateGroupAssignmentMap = function(boardsToChange) {
			angular.forEach(boardsToChange, function(board, key){
				$scope.groupAssignmentInfo[board.id] = lookupAssignedGroups(board);
			});
		}

		$scope.getListOfGroups = function(listOfGroups) {
			if (listOfGroups.length == 0) {
				return "No groups have been assigned."
			}

			var listOfGroupsString = "Board assigned to: ";

			angular.forEach(listOfGroups, function(group, key){
				listOfGroupsString = listOfGroupsString + group.groupName + ", ";
			});

			listOfGroupsString = listOfGroupsString.replace(/,\s*$/, "");

			return listOfGroupsString;
		}

		$scope.assignBoard = function(board) {
			if ($scope.pendingAssignment[board.id]) {
				var groupToAssign = $scope.pendingAssignment[board.id]._id;

				api.assignments.assignBoard({gameId: board.id, groupId: groupToAssign}).$promise.then(function(){
					updateGroupAssignmentMap([board]);
					delete $scope.pendingAssignment[board.id]; // remove from pending list.
					$scope.showToast($scope.toastTypes.Success, "Assignment Saved", "This assignment has been saved successfully.");
					$scope.groupAssignmentInfo[board.id].$promise.then(function() {
						$timeout(Opentip.findElements, 0);
					});
				}).catch(function(e){
	        		$scope.showToast($scope.toastTypes.Failure, "Board Assignment Failed", e.data.errorMessage || ("Error " + e.status));
				})
			} else {
	        	$scope.showToast($scope.toastTypes.Failure, "Board Assignment Failed", "Error: Please choose a group.");
	        }
		}

		$scope.unassignBoard = function(group, board) {
			var unassignGroup = $window.confirm('Are you sure you want to unassign this board from this group?');

			if (unassignGroup){
				api.assignments.unassignBoard({gameId: board.id, groupId: group._id}).$promise.then(function(){
					updateGroupAssignmentMap([board]);
					$scope.showToast($scope.toastTypes.Success, "Assignment Deleted", "This assignment has been unset successfully.");
					$scope.groupAssignmentInfo[board.id].$promise.then(function() {
						$timeout(Opentip.findElements, 0);
					});
				}).catch(function(e){
        			$scope.showToast($scope.toastTypes.Failure, "Board Unassignment Failed", e.data.errorMessage || ("Error " + e.status));
				});
			}
		}
	}];

	var MyAssignmentsPageController = ['$scope', 'auth', 'api', 'gameBoardTitles', '$rootScope', '$timeout', function($scope, auth, api, gameBoardTitles, $rootScope, $timeout) {

		$scope.setLoading(true);

		$rootScope.pageTitle = "My Assignments";

		$scope.generateGameBoardTitle = gameBoardTitles.generate;

		$scope.myAssignments = {};

		$scope.myAssignments.completed = [];
		$scope.myAssignments.inProgress = [];

		$scope.assignmentsVisible = $scope.myAssignments.inProgress;

		api.assignments.getMyAssignments().$promise.then(function(results) {
			angular.forEach(results, function(assignment, index) {
				if (assignment.gameboard.percentageCompleted < 100) {
					$scope.myAssignments.inProgress.push(assignment);
				} else {
					$scope.myAssignments.completed.push(assignment);
				}
			})
			$scope.setLoading(false);
		});

		$scope.toggleVisibleBoards = function(){
			if ($scope.assignmentsVisible == $scope.myAssignments.inProgress) {
				$scope.assignmentsVisible = $scope.myAssignments.completed;
			} else {
				$scope.assignmentsVisible = $scope.myAssignments.inProgress;
			}
		}

		$scope.calculateBoardLevels = calculateBoardLevels;
	}];

	return {
		SetAssignmentsPageController: SetAssignmentsPageController,
		MyAssignmentsPageController: MyAssignmentsPageController
	};
})<commit_msg>Log "VIEW_MY_ASSIGNMENTS" in the front end to avoid a log event being recorded erroneously when the global nav showed a count of assignments set.<commit_after>/**
 * Copyright 2014 Ian Davies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
define([], function() {

	var calculateBoardLevels = function(board){
			levels = [];
			for(var i = 0; i < board.questions.length; i++) {
				if (levels.indexOf(board.questions[i].level) == -1 && board.questions[i].level != 0) {
					levels.push(board.questions[i].level);
				}
			}

			levels.sort(function (a, b) {
   				return a > b ? 1 : a < b ? -1 : 0;
			});

			return levels;
	}

	var SetAssignmentsPageController = ['$scope', 'auth', 'api', 'gameBoardTitles', '$rootScope', '$window', '$timeout', function($scope, auth, api, gameBoardTitles, $rootScope, $window, $timeout) {
		$rootScope.pageTitle = "Assign Boards";

		$scope.generateGameBoardTitle = gameBoardTitles.generate;

		$scope.myGroups = api.groupManagementEndpoint.get(); // get a list of all known groups for this user.

		$scope.openedAssignPanels = []; // shows those panels currently opened
		$scope.pendingAssignment = {}; // boardId to group id mapping - allows us to know which group is being assigned which board.

		$scope.groupAssignmentInfo = {}; // map of boardId to group list - shows groups currently assigned.

		// allows the view to change which panels are open.
		$scope.toggleAssignPanel = function(board) {
			var indexOfBoard = $scope.openedAssignPanels.indexOf(board.id);
			if ($scope.openedAssignPanels.indexOf(board.id) == -1) {
				$scope.openedAssignPanels.push(board.id);
			} else {
				$scope.openedAssignPanels.splice(indexOfBoard, 1);
			}

			if($scope.myGroups.length == 0)
           		$scope.modals.groupsWarning.show();
		}

		$scope.filterOptions = [
			{label: "All Boards", val: null},
			{label: "Not Started", val: "not_attempted"},
			{label: "In Progress", val: "in_progress"},
			{label: "Completed", val: "completed"}
		];

		$scope.sortOptions = [
			{label: "Date Created", val: "created"},
			{label: "Date Visited", val: "visited"}
		];

		$scope.filterOption = $scope.filterOptions[0];
		$scope.sortOption = $scope.sortOptions[1];

		var updateBoards = function(limit) {
			$scope.setLoading(true);
			api.userGameBoards($scope.filterOption.val, $scope.sortOption.val, 0, limit).$promise.then(function(boards) {
				$scope.boards = boards;

				updateGroupAssignmentMap($scope.boards.results)

				$scope.setLoading(false);
			})
		};

		// update boards when filters have been selected
		$scope.$watch("filterOption", function(newVal, oldVal) {
			// TODO: For some reason these watch functions are being fired for no reason
			if (newVal === oldVal) {
				return;
			}
			updateBoards();
		});

		$scope.$watch("sortOption", function(newVal, oldVal) {
			if (newVal === oldVal) {
				return;
			}
			updateBoards();
		});

		// update tooltips when this changes.
		$scope.$watch("boards.results", function(newVal, oldVal){
			$timeout(function(){
				Opentip.findElements();
			}, 0);

		}, true);

		// Perform initial load
		updateBoards();

		var mergeInProgress = false;
		$scope.loadMore = function() {
			if (mergeInProgress) return;
			mergeInProgress = true;
			$scope.setLoading(true);
			api.userGameBoards($scope.filterOption.val, $scope.sortOption.val, $scope.boards.results.length).$promise.then(function(newBoards){
				// Merge new boards into results
				updateGroupAssignmentMap(newBoards.results)

				$.merge($scope.boards.results, newBoards.results);
				$scope.setLoading(false);
				mergeInProgress = false;
			});
		};

		$scope.deleteBoard = function(board){
			lookupAssignedGroups(board).$promise.then(function(groupsAssigned) {
				if (groupsAssigned != null && groupsAssigned.length != 0){
					alert("Warning: You currently have groups assigned to this board. If you delete this your groups will still be assigned but you won't be able to see the board in your Assigned Boards or My boards page.")
				}

				var boardTitle = board.title ? board.title : $scope.generateGameBoardTitle(board);
				// Warn user before deleting
				var confirmation = confirm("You are about to delete "+ boardTitle + " board?");
				if (confirmation){
	       			// TODO: This needs to be reviewed
	       			// Currently reloading boards after delete
					$scope.setLoading(true);
	       			api.deleteGameBoard(board.id).$promise.then(function(){
				        updateBoards($scope.boards.results.length);
				        $scope.setLoading(false);
				        $scope.showToast($scope.toastTypes.Success, "Board Deleted", "You have successfully deleted the board: " + boardTitle);
	       			}).catch(function(e){
						$scope.showToast($scope.toastTypes.Failure, "Board Deletion Failed", "With error message: (" + e.status + ") "+ e.status + ") "+ e.data.errorMessage != undefined ? e.data.errorMessage : "");
	       			});
				}
			})
		}

		$scope.calculateBoardLevels = calculateBoardLevels;

		var lookupAssignedGroups = function(board) {
			var groups = api.assignments.getAssignedGroups({gameId: board.id});
			return groups;
		}

		var updateGroupAssignmentMap = function(boardsToChange) {
			angular.forEach(boardsToChange, function(board, key){
				$scope.groupAssignmentInfo[board.id] = lookupAssignedGroups(board);
			});
		}

		$scope.getListOfGroups = function(listOfGroups) {
			if (listOfGroups.length == 0) {
				return "No groups have been assigned."
			}

			var listOfGroupsString = "Board assigned to: ";

			angular.forEach(listOfGroups, function(group, key){
				listOfGroupsString = listOfGroupsString + group.groupName + ", ";
			});

			listOfGroupsString = listOfGroupsString.replace(/,\s*$/, "");

			return listOfGroupsString;
		}

		$scope.assignBoard = function(board) {
			if ($scope.pendingAssignment[board.id]) {
				var groupToAssign = $scope.pendingAssignment[board.id]._id;

				api.assignments.assignBoard({gameId: board.id, groupId: groupToAssign}).$promise.then(function(){
					updateGroupAssignmentMap([board]);
					delete $scope.pendingAssignment[board.id]; // remove from pending list.
					$scope.showToast($scope.toastTypes.Success, "Assignment Saved", "This assignment has been saved successfully.");
					$scope.groupAssignmentInfo[board.id].$promise.then(function() {
						$timeout(Opentip.findElements, 0);
					});
				}).catch(function(e){
	        		$scope.showToast($scope.toastTypes.Failure, "Board Assignment Failed", e.data.errorMessage || ("Error " + e.status));
				})
			} else {
	        	$scope.showToast($scope.toastTypes.Failure, "Board Assignment Failed", "Error: Please choose a group.");
	        }
		}

		$scope.unassignBoard = function(group, board) {
			var unassignGroup = $window.confirm('Are you sure you want to unassign this board from this group?');

			if (unassignGroup){
				api.assignments.unassignBoard({gameId: board.id, groupId: group._id}).$promise.then(function(){
					updateGroupAssignmentMap([board]);
					$scope.showToast($scope.toastTypes.Success, "Assignment Deleted", "This assignment has been unset successfully.");
					$scope.groupAssignmentInfo[board.id].$promise.then(function() {
						$timeout(Opentip.findElements, 0);
					});
				}).catch(function(e){
        			$scope.showToast($scope.toastTypes.Failure, "Board Unassignment Failed", e.data.errorMessage || ("Error " + e.status));
				});
			}
		}
	}];

	var MyAssignmentsPageController = ['$scope', 'auth', 'api', 'gameBoardTitles', '$rootScope', '$timeout', function($scope, auth, api, gameBoardTitles, $rootScope, $timeout) {

		$scope.setLoading(true);

		$rootScope.pageTitle = "My Assignments";

		$scope.generateGameBoardTitle = gameBoardTitles.generate;

		$scope.myAssignments = {};

		$scope.myAssignments.completed = [];
		$scope.myAssignments.inProgress = [];

		$scope.assignmentsVisible = $scope.myAssignments.inProgress;

		api.assignments.getMyAssignments().$promise.then(function(results) {
			angular.forEach(results, function(assignment, index) {
				if (assignment.gameboard.percentageCompleted < 100) {
					$scope.myAssignments.inProgress.push(assignment);
				} else {
					$scope.myAssignments.completed.push(assignment);
				}
			})
			$scope.setLoading(false);
			// Log this in the front end because the count is used in the gloabl nav, which incorrectly caused a log event.
            api.logger.log({
                type : "VIEW_MY_ASSIGNMENTS"
            });
		});

		$scope.toggleVisibleBoards = function(){
			if ($scope.assignmentsVisible == $scope.myAssignments.inProgress) {
				$scope.assignmentsVisible = $scope.myAssignments.completed;
			} else {
				$scope.assignmentsVisible = $scope.myAssignments.inProgress;
			}
		}

		$scope.calculateBoardLevels = calculateBoardLevels;
	}];

	return {
		SetAssignmentsPageController: SetAssignmentsPageController,
		MyAssignmentsPageController: MyAssignmentsPageController
	};
})<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React from 'react';
import { Field, reduxForm } from 'redux-form';
import { injectIntl } from 'react-intl';
import { Row, Col } from 'react-flexbox-grid/lib';
import composeIntlForm from '../../common/IntlForm';
import MetadataPickerContainer from '../../common/MetadataPickerContainer';
import AppButton from '../../common/AppButton';
import { TAG_SET_PUBLICATION_COUNTRY, TAG_SET_PUBLICATION_STATE, TAG_SET_PRIMARY_LANGUAGE, TAG_SET_COUNTRY_OF_FOCUS } from '../../../lib/tagUtil';

const localMessages = {
  searchSuggestion: { id: 'search.advanced.searchTip', defaultMessage: 'match these words' },
  pubCountrySuggestion: { id: 'search.advanced.pubCountryTip', defaultMessage: 'published in' },
  pubStateSuggestion: { id: 'search.advanced.pubStateTip', defaultMessage: 'state published in' },
  pLanguageSuggestion: { id: 'search.advanced.pLanguageTip', defaultMessage: 'primary language' },
  pCountryOfFocusSuggestion: { id: 'search.advanced.pCountryOfFocusTip', defaultMessage: 'country of focus' },
};
const AdvancedSearchForm = (props) => {
  const { initialValues, renderTextField, handleSubmit, buttonLabel, pristine, submitting, onSearch } = props;
  const { formatMessage } = props.intl;
  return (
    <form className="advanced-search-form" onSubmit={handleSubmit(onSearch.bind(this))}>
      <Row>
        <Col lg={10}>
          <Field
            name="advancedSearchQueryString"
            value={initialValues}
            component={renderTextField}
            floatingLabelText={formatMessage(localMessages.searchSuggestion)}
            fullWidth
          />
        </Col>
      </Row>
      <Row>
        <Col lg={6}>
          <MetadataPickerContainer
            id={TAG_SET_PUBLICATION_COUNTRY}
            name={'publicationCountry'}
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pubCountrySuggestion)}
            autocomplete
          />
        </Col>
        <Col lg={6}>
          <MetadataPickerContainer
            id={TAG_SET_PUBLICATION_STATE}
            name={'publicationState'}
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pubStateSuggestion)}
            autocomplete
          />
        </Col>
        <Col lg={6}>
          <MetadataPickerContainer
            id={TAG_SET_PRIMARY_LANGUAGE}
            name={'primaryLanguage'}
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pLanguageSuggestion)}
            autocomplete
          />
        </Col>
        <Col lg={6}>
          <MetadataPickerContainer
            id={TAG_SET_COUNTRY_OF_FOCUS}
            name={'countryOfFocus'}
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pCountryOfFocusSuggestion)}
            autocomplete
          />
        </Col>
      </Row>
      <Row>
        <Col lg={12}>
          <AppButton
            style={{ marginTop: 30 }}
            type="submit"
            label={buttonLabel}
            disabled={pristine || submitting}
            primary
          />
        </Col>
      </Row>
    </form>
  );
};

AdvancedSearchForm.propTypes = {
  // from compositional chain
  intl: PropTypes.object.isRequired,
  // from form healper
  initialValues: PropTypes.object,
  buttonLabel: PropTypes.string.isRequired,
  handleSubmit: PropTypes.func,
  pristine: PropTypes.bool.isRequired,
  submitting: PropTypes.bool.isRequired,
  renderTextField: PropTypes.func.isRequired,
  // from parent
  onSearch: PropTypes.func.isRequired,
  searchString: PropTypes.string,
};

const reduxFormConfig = {
  form: 'advancedQueryForm',
};

export default
  injectIntl(
    composeIntlForm(
      reduxForm(reduxFormConfig)(
        AdvancedSearchForm
      )
    )
  );
<commit_msg>#630 proper text<commit_after>import PropTypes from 'prop-types';
import React from 'react';
import { Field, reduxForm } from 'redux-form';
import { injectIntl } from 'react-intl';
import { Row, Col } from 'react-flexbox-grid/lib';
import composeIntlForm from '../../common/IntlForm';
import MetadataPickerContainer from '../../common/MetadataPickerContainer';
import AppButton from '../../common/AppButton';
import { TAG_SET_PUBLICATION_COUNTRY, TAG_SET_PUBLICATION_STATE, TAG_SET_PRIMARY_LANGUAGE, TAG_SET_COUNTRY_OF_FOCUS, TAG_SET_MEDIA_TYPE } from '../../../lib/tagUtil';

const localMessages = {
  searchSuggestion: { id: 'search.advanced.searchTip', defaultMessage: 'match these words' },
  pubCountrySuggestion: { id: 'search.advanced.pubCountryTip', defaultMessage: 'published in' },
  pubStateSuggestion: { id: 'search.advanced.pubStateTip', defaultMessage: 'state published in' },
  pLanguageSuggestion: { id: 'search.advanced.pLanguageTip', defaultMessage: 'primary language' },
  pCountryOfFocusSuggestion: { id: 'search.advanced.pCountryOfFocusTip', defaultMessage: 'country of focus' },
  pMediaType: { id: 'search.advanced.pMediaType', defaultMessage: 'media type' },
};
const AdvancedSearchForm = (props) => {
  const { initialValues, renderTextField, handleSubmit, buttonLabel, pristine, submitting, onSearch } = props;
  const { formatMessage } = props.intl;
  return (
    <form className="advanced-search-form" onSubmit={handleSubmit(onSearch.bind(this))}>
      <Row>
        <Col lg={10}>
          <Field
            name="advancedSearchQueryString"
            value={initialValues}
            component={renderTextField}
            floatingLabelText={formatMessage(localMessages.searchSuggestion)}
            fullWidth
          />
        </Col>
      </Row>
      <Row>
        <Col lg={6}>
          <MetadataPickerContainer
            id={TAG_SET_PUBLICATION_COUNTRY}
            name="publicationCountry"
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pubCountrySuggestion)}
            autocomplete
          />
        </Col>
        <Col lg={6}>
          <MetadataPickerContainer
            id={TAG_SET_PUBLICATION_STATE}
            name="publicationState"
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pubStateSuggestion)}
            autocomplete
          />
        </Col>
        <Col lg={6}>
          <MetadataPickerContainer
            value={initialValues}
            id={TAG_SET_PRIMARY_LANGUAGE}
            name="primaryLanguage"
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pLanguageSuggestion)}
            autocomplete
          />
        </Col>
        <Col lg={6}>
          <MetadataPickerContainer
            value={initialValues}
            id={TAG_SET_COUNTRY_OF_FOCUS}
            name={'countryOfFocus'}
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pCountryOfFocusSuggestion)}
            autocomplete
          />
        </Col>
        <Col lg={6}>
          <MetadataPickerContainer
            id={TAG_SET_MEDIA_TYPE}
            showDescription
            name="mediaType"
            form="advancedQueryForm"
            floatingLabelText={formatMessage(localMessages.pMediaType)}
          />
        </Col>
      </Row>
      <Row>
        <Col lg={12}>
          <AppButton
            style={{ marginTop: 30 }}
            type="submit"
            label={buttonLabel}
            disabled={pristine || submitting}
            primary
          />
        </Col>
      </Row>
    </form>
  );
};

AdvancedSearchForm.propTypes = {
  // from compositional chain
  intl: PropTypes.object.isRequired,
  // from form healper
  initialValues: PropTypes.object,
  buttonLabel: PropTypes.string.isRequired,
  handleSubmit: PropTypes.func,
  pristine: PropTypes.bool.isRequired,
  submitting: PropTypes.bool.isRequired,
  renderTextField: PropTypes.func.isRequired,
  // from parent
  onSearch: PropTypes.func.isRequired,
  searchString: PropTypes.string,
};

const reduxFormConfig = {
  form: 'advancedQueryForm',
};

export default
  injectIntl(
    composeIntlForm(
      reduxForm(reduxFormConfig)(
        AdvancedSearchForm
      )
    )
  );
<|endoftext|>