<commit_before>const {spawn} = require('child_process')
const {cranRoot, lib} = require('./config')
const {isBinaryPackage} = require('./filesystem')
const log = require('sepal/log').getLogger('R')

const runScript = (script, args) =>
    new Promise((resolve, reject) => {
        log.trace(`Running script ${script} with args:`, args)
        const cmd = spawn(script, args)

        let stdout = ''
        let stderr = ''

        cmd.stdout.on('data', data =>
            stdout += data.toString('utf8')
        )

        cmd.stderr.on('data', data =>
            stderr += data.toString('utf8')
        )

        cmd.on('close', code =>
            code
                ? reject({code, stderr})
                : resolve(stdout)
        )
    })

const installPackage = async (name, version, repo) => {
    try {
        log.debug(`Installing ${name}/${version} from ${repo}`)
        await runScript('src/R/install_package.r', [name, version, repo])
        log.debug(`Installed ${name}/${version} from ${repo}`)
        return true
    } catch (error) {
        log.warn(`Could not install ${name}/${version}`, error)
        return false
    }
}

const bundlePackage = async (name, version) => {
    try {
        log.debug(`Bundling ${name}/${version}`, {lib, cranRoot})
        log.debug(await runScript('src/R/bundle_package.sh', [name, version, lib, cranRoot]))
        log.debug(`Bundled ${name}/${version}`)
        return true
    } catch (error) {
        log.warn(`Could not bundle ${name}/${version}`, error)
        return false
    }
}

const makeBinaryPackage = async (requestPath, name, version, repo) =>
    await isBinaryPackage(requestPath) || await installPackage(name, version, repo) && await bundlePackage(name, version)

module.exports = {
    makeBinaryPackage
}
<commit_msg>Cleanup.<commit_after>const {spawn} = require('child_process')
const {cranRoot, lib} = require('./config')
const {isBinaryPackage} = require('./filesystem')
const log = require('sepal/log').getLogger('R')

const runScript = (script, args) =>
    new Promise((resolve, reject) => {
        log.trace(`Running script ${script} with args:`, args)
        const cmd = spawn(script, args)

        let stdout = ''
        let stderr = ''

        cmd.stdout.on('data', data =>
            stdout += data.toString('utf8')
        )

        cmd.stderr.on('data', data =>
            stderr += data.toString('utf8')
        )

        cmd.on('close', code =>
            code
                ? reject({code, stderr})
                : resolve(stdout)
        )
    })

const installPackage = async (name, version, repo) => {
    try {
        log.debug(`Installing ${name}/${version} from ${repo}`)
        await runScript('src/R/install_package.r', [name, version, repo])
        log.debug(`Installed ${name}/${version} from ${repo}`)
        return true
    } catch (error) {
        log.warn(`Could not install ${name}/${version}`, error)
        return false
    }
}

const bundlePackage = async (name, version) => {
    try {
        log.debug(`Bundling ${name}/${version}`, {lib, cranRoot})
        await runScript('src/R/bundle_package.sh', [name, version, lib, cranRoot])
        log.debug(`Bundled ${name}/${version}`)
        return true
    } catch (error) {
        log.warn(`Could not bundle ${name}/${version}`, error)
        return false
    }
}

const makeBinaryPackage = async (requestPath, name, version, repo) =>
    await isBinaryPackage(requestPath) || await installPackage(name, version, repo) && await bundlePackage(name, version)

module.exports = {
    makeBinaryPackage
}
<|endoftext|>


<commit_before>app.controller('StudentController', function ($scope, $http, $routeParams) {

  $scope.student = {};

  $http.get('/api/student/'+$routeParams.id).success(function(data){
    $scope.student = data['body'];

    $http.get('api/skills').success(function(data){
      $scope.all_skills = data['body'];

      $scope.skills = {
        learnTemplate: 'Learn {n} to unlock.',
        portraitUrl: 'img/portraits/portrait-1.jpg',
        numPortraits: 22,
        myName: $scope.student.name,
        emailAddress: $scope.student.email,
        hash: '_abc',
        defaultStats: {
          'Charisma': 9
          , 'Dexterity': 9
          , 'Fortitude': 9
          , 'Intellect': 9
          , 'Strength': 9
          , 'Wisdom': 9
        },
        skills: $scope.all_skills
      };

      //konami code plugin
      (function ($) {

        $.fn.konami = function (callback, code) {
          if (code == undefined) code = "38,38,40,40,37,39,37,39,66,65"; //Super secret!

          return this.each(function () {
            var kkeys = [];
            $(this).keydown(function (e) {
              kkeys.push(e.keyCode);
              if (kkeys.toString().indexOf(code) >= 0) {
                $(this).unbind('keydown', arguments.callee);
                callback(e);
              }
            });
          });
        }

      })(jQuery);

      //Custom closure
      (function($, ko, data){

        //On page load
        $(function(){

          //Create and bind the viewmodel
          var vm = new tft.skilltree.Calculator(data);
          ko.applyBindings(vm);

          //apply konami code plugin
          // $(window).konami(function () { vm.open(); vm.godMode(); });

        });
        console.log($scope.skills)
      })(window.jQuery, window.ko, $scope.skills);
    });

  });

});
<commit_msg>use '/api/dungeon' in StudentController<commit_after>app.controller('StudentController', function ($scope, $http, $routeParams) {

  $scope.student = {};

  $http.get('/api/student/'+$routeParams.id).success(function(data){
    $scope.student = data['body'];

    $http.get('api/dungeons/1').success(function(data){
      $scope.dungeon = data['body']

      $scope.skills = {
        learnTemplate: 'Learn {n} to unlock.',
        portraitUrl: 'img/portraits/portrait-1.jpg',
        numPortraits: 22,
        myName: $scope.student.name,
        emailAddress: $scope.student.email,
        hash: '_abc',
        defaultStats: {
          'Charisma': 9
          , 'Dexterity': 9
          , 'Fortitude': 9
          , 'Intellect': 9
          , 'Strength': 9
          , 'Wisdom': 9
        },
        skills: $scope.dungeon.skills
      };

      //konami code plugin
      (function ($) {

        $.fn.konami = function (callback, code) {
          if (code == undefined) code = "38,38,40,40,37,39,37,39,66,65"; //Super secret!

          return this.each(function () {
            var kkeys = [];
            $(this).keydown(function (e) {
              kkeys.push(e.keyCode);
              if (kkeys.toString().indexOf(code) >= 0) {
                $(this).unbind('keydown', arguments.callee);
                callback(e);
              }
            });
          });
        }

      })(jQuery);

      //Custom closure
      (function($, ko, data){

        //On page load
        $(function(){

          //Create and bind the viewmodel
          var vm = new tft.skilltree.Calculator(data);
          ko.applyBindings(vm);

          //apply konami code plugin
          // $(window).konami(function () { vm.open(); vm.godMode(); });

        });
        console.log($scope.skills)
      })(window.jQuery, window.ko, $scope.skills);
    });

  });

});
<|endoftext|>


<commit_before>if (! window.console) {
  window.console = {
    log: function log (msg) {}
  };
}

if (! htracr) {
  var htracr = {};
}

// An item of interest that will be rendered.
htracr.item = function (data) {

  // render the item
  data.draw = function (di, cursor) {
    var self = this;
    if (self.element) {
      delete self.element;
    }
    self.cursor = cursor;
    self.element = self._draw(di);
    self.element.orig_width = self.element.attr('stroke-width');
    self.element.orig_opacity = self.element.attr('opacity');
		self.element.click(function(event) {
			self.inspect();
			htracr.ui.selected = self;
		});
  };

  data.inspect = function () {
    var self = this;
    var msg = "";
    if (typeof self.element.html_msg === 'function') {
      msg = self.element.html_msg();
    } else if (self.element.html_msg) {
      msg = self.element.html_msg;
    }
    if (htracr.ui.selected) {
      htracr.ui.selected.uninspect();
    }
    htracr.ui.selected = self;
    htracr.ui.set_message(msg);
    self.element.attr({'opacity': "1"});
    self.element.animate({
      'stroke-width': self.element.orig_width + 3
      }, 50,
      function () {
        self.element.animate({
          'stroke-width': self.element.orig_width
        }, 50);
      }
    );
  };

  data.uninspect = function () {
    var self = this;
    htracr.ui.set_message("");
    self.element.attr({'opacity': self.element.orig_opacity});
    htracr.ui.selected = undefined;
  };

  // make sure start and end are set.
  if (! data.start) {
    data.start = htracr.ui.capture_idx.start;
  }
  if (! data.end) {
    data.end = htracr.ui.capture_idx.end;
  }

  data.getEndPoint = function (which) {
    var self = this;
    var offset;
    switch (which) {
      case -1: // start
        offset = 1;
        break;
      case 0:
        offset = (self.element.getTotalLength() - 1) / 2;
        break;
      case 1: // end
        offset = self.element.getTotalLength() - 1;
        break;
      default:
        console.log("unknown end " + which);
        offset = 1;
        break;
    }
    if (offset < 1) {
      offset = 1;
    }
    return this.element.getPointAtLength(offset);
  };

	return data;
};

htracr.connection = function(data) {
	var conn = htracr.item(data);

  conn._draw = function (di) {
    var self = this;
    var conn_e = di.h_line(self.start, self.end, 0, {
      "stroke": "#777",
      "stroke-width": htracr.ui.conn_size,
      "opacity": "0.6"
    });
    conn_e.html_msg = "
Connection to " + di.server_name(conn.server)
    if (di.server_name != conn.server) {
      conn_e.html_msg += " (" + conn.server + ")";
    }
    conn_e.html_msg += "
" +
      "
" +
      "
Local port: " + conn.local_port + "
" +
      "
Duration: " +
      ((self.end - self.start) / 1000).toFixed(3) +
      " seconds
" +
      "
HTTP Requests: " + self.http_reqs.length + "
" +
      "
";
      return conn_e;
  };
	return conn;
};

htracr.packet = function(data) {
	var packet = htracr.item(data);

	packet._draw = function (di) {
    var self = this;

    // what kind of packet am I?
    var len;
    var direction;
    switch (self.dir) {
      case "in":
        len = htracr.ui.conn_size / 2;
        direction = "<";
        break;
      case "out":
        len = - (htracr.ui.conn_size / 2);
        direction = ">";
        break;
      default:
        console.log("Unrecognised packet dir: " + self.dir);
        break;
    }

    // determine the packet colour
    var pcolour = '#bbb';
    if (self.data_sz > 0)
      pcolour = '#ccc';
    if (self.flags.psh)
      pcolour = 'green';
    if (self.flags.syn)
      pcolour = 'yellow';
    if (self.flags.rst)
      pcolour = 'blue';
    if (self.flags.fin)
      pcolour = 'purple';

    var pkt_e = di.v_line(self.time, len, {
      "stroke-width":  htracr.ui.pix_per_sec <= 2500 ? "1" : "2",
      "stroke": pcolour,
      "shape-rendering": "crispEdges"
    });

    if (self.ack_only) {
      htracr.ui.ack_elements.push(pkt_e);
      if (! htracr.ui.show_ack_elements) {
        pkt_e.hide();
      }
    }

    pkt_e.html_msg = function () {
      var packet_data;
      if (self.data_sz) {
        packet_data = htracr.comm.get_packet(self.packet_id);
      }
      return "
" +
      "
" +
      " SYN 	" +
      " ACK 	" +
      " RST 	" +
      " FIN 	" +
      " PSH 	" +
      " " + direction + " 	" +
      "
" +
      "
" +
      "
" +
      "
window size: " + self.ws + "
" +
      "
data bytes: " + self.data_sz + "
" +
      "
" +
      "
" + (packet_data || "") + "
";
    };

    return pkt_e;
  };

	return packet;
};

htracr.http_msg = function(data) {
	var msg = htracr.item(data);

	msg._draw = function (di) {
    var self = this;
    var a = {
      'fill': 'white',
      'opacity': '0.4',
      'font-size': '11'
    };

    var adj_y;
    switch (self.kind) {
      case "req":
        adj_y = - (htracr.ui.conn_size / 2) - (htracr.ui.msg_size / 2);
        di.save('referer', self.data.headers.Referer, self);
        var url = "http://" + self.data.headers.Host + self.data.url;
        di.save('request_uri', url, self, true);
        break;
      case "res":
        adj_y = (htracr.ui.conn_size / 2) + (htracr.ui.msg_size / 2);
        di.save('location', self.data.headers.Location, self, true);
        break;
      default:
        console.log("Unknown message type: " + this.kind);
        break;
    }

    var msg_e = di.h_line(self.start, self.end, adj_y, {
      "stroke": "red",
      "stroke-linecap": "round",
      "stroke-width": "" + htracr.ui.msg_size,
      "opacity": ".6"
    });

    var packet_count = 0;
    var byte_count = 0;
    var target_dir = self.kind === 'req' ? 'out' : 'in';

    var desc = "
HTTP " + (self.kind === 'req' ? "Request" : "Response") +
           "
" +
           "
" +
           "
Data packets: " + self.data_packet_count + "
" +
           "
Data size: " + self.packet_byte_count + " bytes
" +
           "
Duration: " + (self.end - self.start).toFixed(1) + "ms
" +
           "

";

    if (self.kind === 'req') {
      desc += self.data.method + " " +
              self.data.url +
              " HTTP/" + self.data.http_version + "\n";
//      if (msg.data.method !== 'GET') {
//        self.paper.text(start_x + 20, msg_y - 10, msg.data.method).attr(a);
//      }
    } else {
      desc += "HTTP/" + msg.data.http_version + " " +
              msg.data.status_code + "\n";
//      if (msg.data.status_code !== 200) {
//        self.paper.text(
//          start_x + 16, msg_y + 10, msg.data.status_code
//        ).attr(a);
//      }
    }
    for (var hdr in msg.data.headers) {
      if (msg.data.headers.hasOwnProperty(hdr)) {
        var val = msg.data.headers[hdr];
        desc += hdr + ": " + val + "\n";
      }
    }
    desc += "
";
    msg_e.html_msg = desc;
    return msg_e;
	};

	return msg;
};
<commit_msg>start colouring responses<commit_after>if (! window.console) {
  window.console = {
    log: function log (msg) {}
  };
}

if (! htracr) {
  var htracr = {};
}

htracr.res_colours = {
  'text/html': "green",
  'text/css': "purple",
  'image/gif': "blue",
  'image/jpeg': "blue",
  'image/png': "blue",
  'application/json': "yellow",
  'application/xml': "yellow",
  'application/x-javascript': "yellow"
}

// An item of interest that will be rendered.
htracr.item = function (data) {

  // render the item
  data.draw = function (di, cursor) {
    var self = this;
    if (self.element) {
      delete self.element;
    }
    self.cursor = cursor;
    self.element = self._draw(di);
    self.element.orig_width = self.element.attr('stroke-width');
    self.element.orig_opacity = self.element.attr('opacity');
		self.element.click(function(event) {
			self.inspect();
			htracr.ui.selected = self;
		});
  };

  data.inspect = function () {
    var self = this;
    var msg = "";
    if (typeof self.element.html_msg === 'function') {
      msg = self.element.html_msg();
    } else if (self.element.html_msg) {
      msg = self.element.html_msg;
    }
    if (htracr.ui.selected) {
      htracr.ui.selected.uninspect();
    }
    htracr.ui.selected = self;
    htracr.ui.set_message(msg);
    self.element.attr({'opacity': "1"});
    self.element.animate({
      'stroke-width': self.element.orig_width + 3
      }, 50,
      function () {
        self.element.animate({
          'stroke-width': self.element.orig_width
        }, 50);
      }
    );
  };

  data.uninspect = function () {
    var self = this;
    htracr.ui.set_message("");
    self.element.attr({'opacity': self.element.orig_opacity});
    htracr.ui.selected = undefined;
  };

  // make sure start and end are set.
  if (! data.start) {
    data.start = htracr.ui.capture_idx.start;
  }
  if (! data.end) {
    data.end = htracr.ui.capture_idx.end;
  }

  data.getEndPoint = function (which) {
    var self = this;
    var offset;
    switch (which) {
      case -1: // start
        offset = 1;
        break;
      case 0:
        offset = (self.element.getTotalLength() - 1) / 2;
        break;
      case 1: // end
        offset = self.element.getTotalLength() - 1;
        break;
      default:
        console.log("unknown end " + which);
        offset = 1;
        break;
    }
    if (offset < 1) {
      offset = 1;
    }
    return this.element.getPointAtLength(offset);
  };

	return data;
};

htracr.connection = function(data) {
	var conn = htracr.item(data);

  conn._draw = function (di) {
    var self = this;
    var conn_e = di.h_line(self.start, self.end, 0, {
      "stroke": "#777",
      "stroke-width": htracr.ui.conn_size,
      "opacity": "0.6"
    });
    conn_e.html_msg = "
Connection to " + di.server_name(conn.server)
    if (di.server_name != conn.server) {
      conn_e.html_msg += " (" + conn.server + ")";
    }
    conn_e.html_msg += "
" +
      "
" +
      "
Local port: " + conn.local_port + "
" +
      "
Duration: " +
      ((self.end - self.start) / 1000).toFixed(3) +
      " seconds
" +
      "
HTTP Requests: " + self.http_reqs.length + "
" +
      "
";
      return conn_e;
  };
	return conn;
};

htracr.packet = function(data) {
	var packet = htracr.item(data);

	packet._draw = function (di) {
    var self = this;

    // what kind of packet am I?
    var len;
    var direction;
    switch (self.dir) {
      case "in":
        len = htracr.ui.conn_size / 2;
        direction = "<";
        break;
      case "out":
        len = - (htracr.ui.conn_size / 2);
        direction = ">";
        break;
      default:
        console.log("Unrecognised packet dir: " + self.dir);
        break;
    }

    // determine the packet colour
    var pcolour = '#bbb';
    if (self.data_sz > 0)
      pcolour = '#ccc';
    if (self.flags.psh)
      pcolour = 'green';
    if (self.flags.syn)
      pcolour = 'yellow';
    if (self.flags.rst)
      pcolour = 'blue';
    if (self.flags.fin)
      pcolour = 'purple';

    var pkt_e = di.v_line(self.time, len, {
      "stroke-width":  htracr.ui.pix_per_sec <= 2500 ? "1" : "2",
      "stroke": pcolour,
      "shape-rendering": "crispEdges"
    });

    if (self.ack_only) {
      htracr.ui.ack_elements.push(pkt_e);
      if (! htracr.ui.show_ack_elements) {
        pkt_e.hide();
      }
    }

    pkt_e.html_msg = function () {
      var packet_data;
      if (self.data_sz) {
        packet_data = htracr.comm.get_packet(self.packet_id);
      }
      return "
" +
      "
" +
      " SYN 	" +
      " ACK 	" +
      " RST 	" +
      " FIN 	" +
      " PSH 	" +
      " " + direction + " 	" +
      "
" +
      "
" +
      "
" +
      "
window size: " + self.ws + "
" +
      "
data bytes: " + self.data_sz + "
" +
      "
" +
      "
" + (packet_data || "") + "
";
    };

    return pkt_e;
  };

	return packet;
};

htracr.http_msg = function(data) {
	var msg = htracr.item(data);

	msg._draw = function (di) {
    var self = this;
    var a = {
      'fill': 'white',
      'opacity': '0.4',
      'font-size': '11'
    };

    var adj_y;
    var colour;
    switch (self.kind) {
      case "req":
        adj_y = - (htracr.ui.conn_size / 2) - (htracr.ui.msg_size / 2);
        di.save('referer', self.data.headers.Referer, self);
        var url = "http://" + self.data.headers.Host + self.data.url;
        di.save('request_uri', url, self, true);
        colour = "red";
        break;
      case "res":
        adj_y = (htracr.ui.conn_size / 2) + (htracr.ui.msg_size / 2);
        di.save('location', self.data.headers.Location, self, true);
        var ct = (self.data.headers['Content-Type'] || "").split(";", 1)[0];
        colour = htracr.res_colours[ct] || 'red';
        break;
      default:
        console.log("Unknown message type: " + this.kind);
        break;
    }

    var msg_e = di.h_line(self.start, self.end, adj_y, {
      "stroke": colour,
      "stroke-linecap": "round",
      "stroke-width": "" + htracr.ui.msg_size,
      "opacity": ".6"
    });

    var packet_count = 0;
    var byte_count = 0;
    var target_dir = self.kind === 'req' ? 'out' : 'in';

    var desc = "
HTTP " + (self.kind === 'req' ? "Request" : "Response") +
           "
" +
           "
" +
           "
Data packets: " + self.data_packet_count + "
" +
           "
Data size: " + self.packet_byte_count + " bytes
" +
           "
Duration: " + (self.end - self.start).toFixed(1) + "ms
" +
           "

";

    if (self.kind === 'req') {
      desc += self.data.method + " " +
              self.data.url +
              " HTTP/" + self.data.http_version + "\n";
//      if (msg.data.method !== 'GET') {
//        self.paper.text(start_x + 20, msg_y - 10, msg.data.method).attr(a);
//      }
    } else {
      desc += "HTTP/" + msg.data.http_version + " " +
              msg.data.status_code + "\n";
//      if (msg.data.status_code !== 200) {
//        self.paper.text(
//          start_x + 16, msg_y + 10, msg.data.status_code
//        ).attr(a);
//      }
    }
    for (var hdr in msg.data.headers) {
      if (msg.data.headers.hasOwnProperty(hdr)) {
        var val = msg.data.headers[hdr];
        desc += hdr + ": " + val + "\n";
      }
    }
    desc += "
";
    msg_e.html_msg = desc;
    return msg_e;
	};

	return msg;
};
<|endoftext|>


<commit_before>/*!
 * angular-masonry <%= pkg.version %>
 * Pascal Hartig, weluse GmbH, http://weluse.de/
 * License: MIT
 */
(function () {
  'use strict';

  angular.module('wu.masonry', [])
    .controller('MasonryCtrl', function controller($scope, $element, $timeout) {
      var bricks = {};
      var schedule = [];
      var destroyed = false;
      var self = this;
      var timeout = null;

      this.preserveOrder = false;

      this.scheduleMasonryOnce = function scheduleMasonryOnce() {
        var args = arguments;
        var found = schedule.filter(function filterFn(item) {
          return item[0] === args[0];
        }).length > 0;

        if (!found) {
          this.scheduleMasonry.apply(null, arguments);
        }
      };

      // Make sure it's only executed once within a reasonable time-frame in
      // case multiple elements are removed or added at once.
      this.scheduleMasonry = function scheduleMasonry() {
        if (timeout) {
          $timeout.cancel(timeout);
        }

        schedule.push([].slice.call(arguments));

        timeout = $timeout(function runMasonry() {
          if (destroyed) {
            return;
          }
          schedule.forEach(function scheduleForEach(args) {
            $element.masonry.apply($element, args);
          });
          schedule = [];
        }, 30);
      };

      function defaultLoaded($element) {
        $element.addClass('loaded');
      }

      this.appendBrick = function appendBrick(element, id) {
        if (destroyed) {
          return;
        }

        function _append() {
          if (Object.keys(bricks).length === 0) {
            $element.masonry('resize');
          }
          if (bricks[id] === undefined) {
            // Keep track of added elements.
            bricks[id] = true;
            defaultLoaded(element);
            $element.masonry('appended', element, true);
          }
        }

        function _layout() {
          // I wanted to make this dynamic but ran into huuuge memory leaks
          // that I couldn't fix. If you know how to dynamically add a
          // callback so one could say <masonry loaded="callback($element)">
          // please submit a pull request!
          self.scheduleMasonryOnce('layout');
        }

        if (self.preserveOrder) {
          _append();
          element.imagesLoaded(_layout);
        } else {
          element.imagesLoaded(function imagesLoaded() {
            _append();
            _layout();
          });
        }
      };

      this.removeBrick = function removeBrick(id, element) {
        if (destroyed) {
          return;
        }

        delete bricks[id];
        $element.masonry('remove', element);
        this.scheduleMasonryOnce('layout');
      };

      this.destroy = function destroy() {
        destroyed = true;

        if ($element.data('masonry')) {
          // Gently uninitialize if still present
          $element.masonry('destroy');
        }
        $scope.$emit('masonry.destroyed');

        bricks = [];
      };

      this.reload = function reload() {
        $element.masonry();
        $scope.$emit('masonry.reloaded');
      };

    }).directive('masonry', function masonryDirective() {
      return {
        restrict: 'AE',
        controller: 'MasonryCtrl',
        link: {
          pre: function preLink(scope, element, attrs, ctrl) {
            var attrOptions = scope.$eval(attrs.masonry || attrs.masonryOptions);
            var options = angular.extend({
              itemSelector: attrs.itemSelector || '.masonry-brick',
              columnWidth: parseInt(attrs.columnWidth, 10)
            }, attrOptions || {});
            element.masonry(options);
            var preserveOrder = scope.$eval(attrs.preserveOrder);
            ctrl.preserveOrder = (preserveOrder !== false && attrs.preserveOrder !== undefined);

            scope.$emit('masonry.created', element);
            scope.$on('$destroy', ctrl.destroy);
          }
        }
      };
    }).directive('masonryBrick', function masonryBrickDirective() {
      return {
        restrict: 'AC',
        require: '^masonry',
        scope: true,
        link: {
          pre: function preLink(scope, element, attrs, ctrl) {
            var id = scope.$id, index;

            ctrl.appendBrick(element, id);
            element.on('$destroy', function () {
              ctrl.removeBrick(id, element);
            });

            scope.$on('masonry.reload', function () {
              ctrl.reload();
            });

            scope.$watch('$index', function () {
              if (index !== undefined && index !== scope.$index) {
                ctrl.scheduleMasonryOnce('reloadItems');
                ctrl.scheduleMasonryOnce('layout');
              }
              index = scope.$index;
            });
          }
        }
      };
    });
}());
<commit_msg>fix(directive): re-layout on masonry.reload<commit_after>/*!
 * angular-masonry <%= pkg.version %>
 * Pascal Hartig, weluse GmbH, http://weluse.de/
 * License: MIT
 */
(function () {
  'use strict';

  angular.module('wu.masonry', [])
    .controller('MasonryCtrl', function controller($scope, $element, $timeout) {
      var bricks = {};
      var schedule = [];
      var destroyed = false;
      var self = this;
      var timeout = null;

      this.preserveOrder = false;

      this.scheduleMasonryOnce = function scheduleMasonryOnce() {
        var args = arguments;
        var found = schedule.filter(function filterFn(item) {
          return item[0] === args[0];
        }).length > 0;

        if (!found) {
          this.scheduleMasonry.apply(null, arguments);
        }
      };

      // Make sure it's only executed once within a reasonable time-frame in
      // case multiple elements are removed or added at once.
      this.scheduleMasonry = function scheduleMasonry() {
        if (timeout) {
          $timeout.cancel(timeout);
        }

        schedule.push([].slice.call(arguments));

        timeout = $timeout(function runMasonry() {
          if (destroyed) {
            return;
          }
          schedule.forEach(function scheduleForEach(args) {
            $element.masonry.apply($element, args);
          });
          schedule = [];
        }, 30);
      };

      function defaultLoaded($element) {
        $element.addClass('loaded');
      }

      this.appendBrick = function appendBrick(element, id) {
        if (destroyed) {
          return;
        }

        function _append() {
          if (Object.keys(bricks).length === 0) {
            $element.masonry('resize');
          }
          if (bricks[id] === undefined) {
            // Keep track of added elements.
            bricks[id] = true;
            defaultLoaded(element);
            $element.masonry('appended', element, true);
          }
        }

        function _layout() {
          // I wanted to make this dynamic but ran into huuuge memory leaks
          // that I couldn't fix. If you know how to dynamically add a
          // callback so one could say <masonry loaded="callback($element)">
          // please submit a pull request!
          self.scheduleMasonryOnce('layout');
        }

        if (self.preserveOrder) {
          _append();
          element.imagesLoaded(_layout);
        } else {
          element.imagesLoaded(function imagesLoaded() {
            _append();
            _layout();
          });
        }
      };

      this.removeBrick = function removeBrick(id, element) {
        if (destroyed) {
          return;
        }

        delete bricks[id];
        $element.masonry('remove', element);
        this.scheduleMasonryOnce('layout');
      };

      this.destroy = function destroy() {
        destroyed = true;

        if ($element.data('masonry')) {
          // Gently uninitialize if still present
          $element.masonry('destroy');
        }
        $scope.$emit('masonry.destroyed');

        bricks = [];
      };

      this.reload = function reload() {
        $element.masonry();
        $scope.$emit('masonry.reloaded');
      };

    }).directive('masonry', function masonryDirective() {
      return {
        restrict: 'AE',
        controller: 'MasonryCtrl',
        link: {
          pre: function preLink(scope, element, attrs, ctrl) {
            var attrOptions = scope.$eval(attrs.masonry || attrs.masonryOptions);
            var options = angular.extend({
              itemSelector: attrs.itemSelector || '.masonry-brick',
              columnWidth: parseInt(attrs.columnWidth, 10)
            }, attrOptions || {});
            element.masonry(options);
            var preserveOrder = scope.$eval(attrs.preserveOrder);
            ctrl.preserveOrder = (preserveOrder !== false && attrs.preserveOrder !== undefined);

            scope.$emit('masonry.created', element);
            scope.$on('$destroy', ctrl.destroy);
          }
        }
      };
    }).directive('masonryBrick', function masonryBrickDirective() {
      return {
        restrict: 'AC',
        require: '^masonry',
        scope: true,
        link: {
          pre: function preLink(scope, element, attrs, ctrl) {
            var id = scope.$id, index;

            ctrl.appendBrick(element, id);
            element.on('$destroy', function () {
              ctrl.removeBrick(id, element);
            });

            scope.$on('masonry.reload', function () {
              ctrl.scheduleMasonryOnce('reloadItems');
              ctrl.scheduleMasonryOnce('layout');
            });

            scope.$watch('$index', function () {
              if (index !== undefined && index !== scope.$index) {
                ctrl.scheduleMasonryOnce('reloadItems');
                ctrl.scheduleMasonryOnce('layout');
              }
              index = scope.$index;
            });
          }
        }
      };
    });
}());
<|endoftext|>


<commit_before>// as of 2014-08-14, Niantic have returned to minifying the javascript. This means we no longer get the nemesis object
// and it's various member objects, functions, etc.
// so we need to extract some essential parameters from the code for IITC to use

window.extractFromStock = function() {
  window.niantic_params = {}

  // extract the former nemesis.dashboard.config.CURRENT_VERSION from the code
  var reVersion = new RegExp('[a-z]=[a-z].getData\\(\\);[a-z].v="([a-f0-9]{40})";');

  // we also extract all top-level arrays of strings, for botguard
  var arrays = [];

  var minified = new RegExp('^[a-zA-Z][a-zA-Z0-9]$');

  for (var topLevel in window) {
    if (minified.test(topLevel)) {
      // a minified object - check for minified prototype entries

      if (window[topLevel] && window[topLevel].prototype) {
        // the object has a prototype - iterate through the properties of that
        for (var secLevel in window[topLevel].prototype) {
          if (minified.test(secLevel)) {

            // looks like we've found an object of the format "XX.prototype.YY"...

            var item = window[topLevel].prototype[secLevel];

            if (item && typeof(item) == "function") {
              // a function - test it against the relevant regular expressions
              var funcStr = item.toString();

              var match = reVersion.exec(funcStr);
              if (match) {
                console.log('Found former CURRENT_VERSION in '+topLevel+'.prototype.'+secLevel);
                niantic_params.CURRENT_VERSION = match[1];
              }

            }

          }
        }

      }

      // finding the required method names for the botguard interface code
      if (window[topLevel] && Object.prototype.toString.call(window[topLevel]) == "[object Array]") {
        // look for all arrays in the top-level namespace

        var arr = window[topLevel];
        var onlyStrings = true;
        if (arr.length > 0) {
          for (var i in arr) {
            if (Object.prototype.toString.call(arr[i]) != "[object String]") {
              onlyStrings = false;
              break;
            }
          }
          if (onlyStrings) {
            arrays.push(arr);
          }
        }

      }

    }
  }

  // we extracted a list of string arrays. now, we need to find which ones we want to use
  // there are two. both contain a list of method names - one is the list of methods protected by either
  // botguard group-a or group-b, while the others is just a list of those in one group

  window.niantic_params.botguard_protected_methods = [];
  window.niantic_params.botguard_group_a_methods = [];

  var countMethods = function(arr) {
    var methods = ['artifacts', 'getGameScore', 'getPlexts', 'getPortalDetails', 'redeemReward', 'sendInviteEmail', 'sendPlext'];
    var count = 0;
    for (var j in arr) {
      if (methods.indexOf(arr[j]) != -1) {
        count++;
      }
    }
    return count;
  }

  var protectedMethodsCount = 0;
  var groupMethodsCount = 0;

  for (var i in arrays) {
    var arr = arrays[i];
    var arrCount = countMethods(arr);

    // now store the longest in niantic_params.botguard_protected_methods, and 2nd longest in .niantic_params.botguard_group_a_methods

    if (arrCount > protectedMethodsCount) {
      // longest found - copy any existing longest to the 2nd longest

      window.niantic_params.botguard_group_a_methods = window.niantic_params.botguard_protected_methods;
      groupMethodsCount = protectedMethodsCount;

      //... and set the longest
      window.niantic_params.botguard_protected_methods = arr;
      protectedMethodsCount = arrCount;

    } else if (arrCount > groupMethodsCount) {
      // 2nd longest - store
      window.niantic_params.botguard_group_a_methods = arr;
      groupMethodsCount = arrCount;
    }

  }

  if (niantic_params.CURRENT_VERSION === undefined || window.niantic_params.botguard_protected_methods.length == 0 || window.niantic_params.botguard_group_a_methods == 0) {
    dialog({
      title: 'IITC Broken',
      html: '
IITC failed to extract the required parameters from the intel site
'
           +'
This can happen after Niantic update the standard intel site. A fix will be needed from the IITC developers.
',
    });

    console.log('Discovered parameters');
    console.log(JSON.stringify(window.niantic_params,null,2));

    throw('Error: IITC failed to extract CURRENT_VERSION string - cannot continue');
  }

}

<commit_msg>formatting/comment changes<commit_after>// as of 2014-08-14, Niantic have returned to minifying the javascript. This means we no longer get the nemesis object
// and it's various member objects, functions, etc.
// so we need to extract some essential parameters from the code for IITC to use

window.extractFromStock = function() {
  window.niantic_params = {}

  // extract the former nemesis.dashboard.config.CURRENT_VERSION from the code
  var reVersion = new RegExp('[a-z]=[a-z].getData\\(\\);[a-z].v="([a-f0-9]{40})";');

  // we also extract all top-level arrays of strings, for botguard
  var arrays = [];

  var minified = new RegExp('^[a-zA-Z][a-zA-Z0-9]$');

  for (var topLevel in window) {
    if (minified.test(topLevel)) {
      // a minified object - check for minified prototype entries

      if (window[topLevel] && window[topLevel].prototype) {

        // the object has a prototype - iterate through the properties of that
        for (var secLevel in window[topLevel].prototype) {
          if (minified.test(secLevel)) {

            // looks like we've found an object of the format "XX.prototype.YY"...

            var item = window[topLevel].prototype[secLevel];

            if (item && typeof(item) == "function") {
              // a function - test it against the relevant regular expressions
              var funcStr = item.toString();

              var match = reVersion.exec(funcStr);
              if (match) {
                console.log('Found former CURRENT_VERSION in '+topLevel+'.prototype.'+secLevel);
                niantic_params.CURRENT_VERSION = match[1];
              }

            }

          }
        }

      } //end 'if .prototype'

      // finding the required method names for the botguard interface code
      if (window[topLevel] && Object.prototype.toString.call(window[topLevel]) == "[object Array]") {
        // look for all arrays in the top-level namespace

        var arr = window[topLevel];
        var onlyStrings = true;
        if (arr.length > 0) {
          for (var i in arr) {
            if (Object.prototype.toString.call(arr[i]) != "[object String]") {
              onlyStrings = false;
              break;
            }
          }
          if (onlyStrings) {
            arrays.push(arr);
          }
        }

      }

    }
  }

  // we extracted a list of string arrays. now, we need to find which ones we want to use
  // there are two. both contain a list of method names - one is the list of methods protected by either
  // botguard group-a or group-b, while the others is just a list of those in one group

  window.niantic_params.botguard_protected_methods = [];
  window.niantic_params.botguard_group_a_methods = [];

  var countMethods = function(arr) {
    var methods = ['artifacts', 'getGameScore', 'getPlexts', 'getPortalDetails', 'redeemReward', 'sendInviteEmail', 'sendPlext'];
    var count = 0;
    for (var j in arr) {
      if (methods.indexOf(arr[j]) != -1) {
        count++;
      }
    }
    return count;
  }

  var protectedMethodsCount = 0;
  var groupMethodsCount = 0;

  for (var i in arrays) {
    var arr = arrays[i];
    var arrCount = countMethods(arr);

    // now store the longest in niantic_params.botguard_protected_methods, and 2nd longest in .niantic_params.botguard_group_a_methods

    if (arrCount > protectedMethodsCount) {
      // longest found - copy any existing longest to the 2nd longest

      window.niantic_params.botguard_group_a_methods = window.niantic_params.botguard_protected_methods;
      groupMethodsCount = protectedMethodsCount;

      //... and set the longest
      window.niantic_params.botguard_protected_methods = arr;
      protectedMethodsCount = arrCount;

    } else if (arrCount > groupMethodsCount) {
      // 2nd longest - store
      window.niantic_params.botguard_group_a_methods = arr;
      groupMethodsCount = arrCount;
    }

  }

  if (niantic_params.CURRENT_VERSION === undefined || window.niantic_params.botguard_protected_methods.length == 0 || window.niantic_params.botguard_group_a_methods == 0) {
    dialog({
      title: 'IITC Broken',
      html: '
IITC failed to extract the required parameters from the intel site
'
           +'
This can happen after Niantic update the standard intel site. A fix will be needed from the IITC developers.
',
    });

    console.log('Discovered parameters');
    console.log(JSON.stringify(window.niantic_params,null,2));

    throw('Error: IITC failed to extract CURRENT_VERSION string - cannot continue');
  }

}

<|endoftext|>


<commit_before><commit_msg>persist team-size chart settings in localstorage (completes #66)<commit_after><|endoftext|>


<commit_before>var $ = require('jquery');
var classToggle = require('./classToggle');

var Slideshow = function ($content) {

  var _this = this;

  this.$slideshow      = $('

');
  this.$controllerPrev = $('<button class="__control button button--control -prev" data-direction="prev"></button>');
  this.$controllerNext = $('<button class="__control button button--control -next" data-direction="next"></button>');
  this.$carousel       = $('
' + $content.html() + '
');
  this.$slides         = this.$carousel.find('[data-slideshow="content"]').closest('li');  // @TODO: maybe use something else instead of .card?
  this.slidesTotal     = this.$slides.length;
  this.activeIndex     = 0;

  this.$slides.addClass('__slide is-pending');
  this.$slideshow.append(this.$carousel);
  this.$slideshow.append(this.$controllerPrev, this.$controllerNext);

};

Slideshow.prototype.activate = function (selection) {

  if (selection) {
    this.activeIndex = (selection.closest('li').data('slide')) - 1; // account for zero-based index offset
  }

  this.show(this.activeIndex);
  this.controllerActivate();

};

Slideshow.prototype.controller = function (event) {

  var _this = event.data;
  var $controlButton = $(this);
  var direction = $controlButton.data('direction');

  if (direction === 'prev' && !$controlButton.hasClass('is-disabled')) {
    _this.move(direction);
  } else if (direction === 'next' && !$controlButton.hasClass('is-disabled')) {
    _this.move(direction);
  } else {
    return false;
  }

}

Slideshow.prototype.controllerActivate = function () {

  // Update the controller button status.
  this.controllerUpdate();

  this.$slideshow.on('click', '.__control', this, this.controller);

}

Slideshow.prototype.controllerDeactivate = function () {

  this.$slideshow.off('click', '.__control');

}

Slideshow.prototype.controllerUpdate = function() {

  // If first slide selected, turn off the Prev controller button.
  if (this.activeIndex === 0) {
    this.toggleButton(this.$controllerPrev, 'off');
    return;
  }

  // If last slide selected, turn off the Next controller button.
  if (this.activeIndex === (this.slidesTotal - 1)) {
    this.toggleButton(this.$controllerNext, 'off');
    return;
  }

  // If on any slide past first slide and Prev controller button is off, turn it on.
  if (this.activeIndex > 0) {
    if (this.$controllerPrev.hasClass('is-disabled')) {
      this.toggleButton(this.$controllerPrev, 'on');
    }
  }

  // If on any slide prior to last slide and Next controller button is off, turn it on.
  if (this.activeIndex < (this.slidesTotal - 1)) {
    if (this.$controllerNext.hasClass('is-disabled')) {
      this.toggleButton(this.$controllerNext, 'on');
    }
  }

}

Slideshow.prototype.toggleButton = function ($button, status) {

  if (status === 'off') {
    $button.addClass('is-disabled');
    return;
  }

  if (status === 'on') {
    $button.removeClass('is-disabled');
    return;
  }

}

Slideshow.prototype.show = function (slideIndex) {

  var _$slides = this.$slides;

  if (slideIndex > 0) {
    for (i = 0; i < slideIndex; i++) {
      var $thisSlide = $(_$slides[i]);
      classToggle($thisSlide, 'is-pending');
      classToggle($thisSlide, 'is-completed');
    }
  }

  $selectedSlide = $(_$slides.get(slideIndex));
  classToggle($selectedSlide, 'is-pending');
  classToggle($selectedSlide, 'is-viewing');

}

Slideshow.prototype.move = function (direction) {

  var $currentSlide = $(this.$slides.get(this.activeIndex));

  if (direction === 'prev') {
    $currentSlide.removeClass('is-viewing').addClass('is-pending');
    $currentSlide.prev().removeClass('is-completed').addClass('is-viewing');
    this.activeIndex--;
    this.controllerUpdate();
  }

  if (direction === 'next') {
    $currentSlide.removeClass('is-viewing').addClass('is-completed');
    $currentSlide.next().removeClass('is-pending').addClass('is-viewing');
    this.activeIndex++;
    this.controllerUpdate();
  }

}

Slideshow.prototype.reset = function () {

  this.$slides.each(function () {
    $slide = $(this);

    if ($slide.hasClass('is-completed') || $slide.hasClass('is-viewing')) {
      if ($slide.hasClass('is-completed')) {
        $slide.removeClass('is-completed');
      }

      if ($slide.hasClass('is-viewing')) {
        $slide.removeClass('is-viewing');
      }

      $slide.addClass('is-pending');
    }
  });

  this.toggleButton(this.$controllerPrev, 'on');
  this.toggleButton(this.$controllerNext, 'on');
  this.controllerDeactivate();

}

module.exports = Slideshow;
<commit_msg>Refactoring and cleaning up code with help from Señor Furnes.<commit_after>var $ = require('jquery');
var classToggle = require('./classToggle');

var Slideshow = function ($content) {

  var _this = this;

  this.$slideshow      = $('

');
  this.$controllerPrev = $('<button class="__control button button--control -prev" data-direction="prev"></button>');
  this.$controllerNext = $('<button class="__control button button--control -next" data-direction="next"></button>');
  this.$carousel       = $('
' + $content.html() + '
');
  this.$slides         = this.$carousel.find('[data-slideshow="content"]').closest('li');  // @TODO: maybe use something else instead of .card?
  this.slidesTotal     = this.$slides.length;
  this.activeIndex     = 0;

  this.$slides.addClass('__slide is-pending');
  this.$slideshow.append(this.$carousel);
  this.$slideshow.append(this.$controllerPrev, this.$controllerNext);

};

Slideshow.prototype.activate = function (selection) {

  if (selection) {
    this.activeIndex = (selection.closest('li').data('slide')) - 1; // account for zero-based index offset
  }

  this.show(this.activeIndex);
  this.controllerActivate();

};

Slideshow.prototype.controller = function (event) {

  var _this = event.data;
  var direction = $(this).data('direction');

  _this.move(direction);

}

Slideshow.prototype.controllerActivate = function () {

  // Update the controller button status.
  this.controllerUpdate();

  this.$slideshow.on('click', '.__control', this, this.controller);

}

Slideshow.prototype.controllerDeactivate = function () {

  this.$slideshow.off('click', '.__control');

}

Slideshow.prototype.controllerUpdate = function() {

  this.$controllerPrev.toggleClass('is-disabled', this.isFirstSlide());
  this.$controllerNext.toggleClass('is-disabled', this.isLastSlide());

}

Slideshow.prototype.isFirstSlide = function() {

  return (this.activeIndex === 0);

}

Slideshow.prototype.isLastSlide = function() {

  return (this.activeIndex === (this.slidesTotal - 1));

}

Slideshow.prototype.show = function (slideIndex) {

  var _$slides = this.$slides;

  if (slideIndex > 0) {
    for (i = 0; i < slideIndex; i++) {
      var $thisSlide = $(_$slides[i]);
      classToggle($thisSlide, 'is-pending');
      classToggle($thisSlide, 'is-completed');
    }
  }

  $selectedSlide = $(_$slides.get(slideIndex));
  classToggle($selectedSlide, 'is-pending');
  classToggle($selectedSlide, 'is-viewing');

}

Slideshow.prototype.move = function (direction) {

  var $currentSlide = $(this.$slides.get(this.activeIndex));

  if (direction === 'prev' && !this.isFirstSlide()) {
    $currentSlide.removeClass('is-viewing').addClass('is-pending');
    $currentSlide.prev().removeClass('is-completed').addClass('is-viewing');
    this.activeIndex--;
    this.controllerUpdate();
  }
  else if (direction === 'next' && !this.isLastSlide()) {
    $currentSlide.removeClass('is-viewing').addClass('is-completed');
    $currentSlide.next().removeClass('is-pending').addClass('is-viewing');
    this.activeIndex++;
    this.controllerUpdate();
  }
  else {
    return false;
  }

}

Slideshow.prototype.reset = function () {

  this.$slides.each(function () {
    $slide = $(this);

    if ($slide.hasClass('is-completed') || $slide.hasClass('is-viewing')) {
      if ($slide.hasClass('is-completed')) {
        $slide.removeClass('is-completed');
      }

      if ($slide.hasClass('is-viewing')) {
        $slide.removeClass('is-viewing');
      }

      $slide.addClass('is-pending');
    }
  });

  this.controllerDeactivate();

}

module.exports = Slideshow;
<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name openlmis-modal.loadingModalService
     *
     * @description
     * Will show and hide a loading modal that will block the UI and show a simple loading symbol.
     */
    angular.module('openlmis-modal')
        .service('loadingModalService', LoadingModal);

    LoadingModal.$inject = ['$q', '$timeout', 'openlmisModalService'];
    function LoadingModal($q, $timeout, openlmisModalService) {
        var deferred, timeoutPromise, dialog, options = {
            backdrop: 'static',
            templateUrl: 'openlmis-modal/loading-modal.html'
        };

        this.open = open;
        this.close = close;

        /**
         * @ngdoc method
         * @methodOf openlmis-modal.loadingModalService
         * @name open
         *
         * @description
         * Shows the loading modal after a half second delay.
         *
         * @param  {Boolean} delay indicates if modal should be displayed with delay
         * @return {Promise}       modal promise
         */
        function open(delay) {
            if (deferred) {
                return deferred.promise;
            }

            deferred = $q.defer();

            if (delay && !timeoutPromise) {
                timeoutPromise = $timeout(function(){
                    dialog = openlmisModalService.createDialog(angular.copy(options));
                    dialog.promise.finally(cleanUp);
                    timeoutPromise = null;
                }, 500);
            } else {
                dialog = openlmisModalService.createDialog(angular.copy(options));
                dialog.promise.finally(cleanUp);
            }

            return deferred.promise;
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-modal.loadingModalService
         * @name close
         *
         * @description
         * Hides the loading modal OR cancels the promise that was showing the modal.
         */
        function close(){
            if(timeoutPromise){
                $timeout.cancel(timeoutPromise);
                timeoutPromise = null;
            }

            if(dialog) {
                dialog.hide();
            }

            if (deferred) {
                deferred.resolve();
                deferred = undefined;
            }
        }

        function cleanUp() {
            deferred.resolve();
            dialog = undefined;
        }
    }

})();
<commit_msg>OLMIS-2165: Fixed issue with loading modal not closing sometimes<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name openlmis-modal.loadingModalService
     *
     * @description
     * Will show and hide a loading modal that will block the UI and show a simple loading symbol.
     */
    angular.module('openlmis-modal')
        .service('loadingModalService', LoadingModal);

    LoadingModal.$inject = ['$q', '$timeout', 'openlmisModalService'];
    function LoadingModal($q, $timeout, openlmisModalService) {
        var deferred, timeoutPromise, dialog, options = {
            backdrop: 'static',
            templateUrl: 'openlmis-modal/loading-modal.html'
        };

        this.open = open;
        this.close = close;

        /**
         * @ngdoc method
         * @methodOf openlmis-modal.loadingModalService
         * @name open
         *
         * @description
         * Shows the loading modal after a half second delay.
         *
         * @param  {Boolean} delay indicates if modal should be displayed with delay
         * @return {Promise}       modal promise
         */
        function open(delay) {
            if (deferred) {
                return deferred.promise;
            }

            deferred = $q.defer();

            if (delay && !timeoutPromise) {
                timeoutPromise = $timeout(function(){
                    dialog = openlmisModalService.createDialog(angular.copy(options));
                    timeoutPromise = null;
                }, 500);
            } else {
                dialog = openlmisModalService.createDialog(angular.copy(options));
            }

            return deferred.promise;
        }

        /**
         * @ngdoc method
         * @methodOf openlmis-modal.loadingModalService
         * @name close
         *
         * @description
         * Hides the loading modal OR cancels the promise that was showing the modal.
         */
        function close(){
            if(timeoutPromise){
                $timeout.cancel(timeoutPromise);
                timeoutPromise = null;
            }

            if(dialog) {
                dialog.hide();
                dialog = undefined;
            }

            if (deferred) {
                deferred.resolve();
                deferred = undefined;
            }
        }
    }

})();
<|endoftext|>


<commit_before>/**
 * En javascript les commentaires sont indiqué de deux facons:
 *  soit par /* */
/*  soit par //

    Pour tester le fichier, il suffit d'appeler node exos/c1/corrige.js
*/

console.log("Exercice 1")

/**
Sachant le jour(L / M / Me / J / V / S / D) courant, quel jour on sera dans x jours.
*/

jours = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"]
aujourdhui = 4
dans_x_jours = 45

// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators
// l'operateur % donne le reste d'une division.
jour_cible = (aujourdhui + dans_x_jours) % 7
console.log("Dans " + dans_x_jours + " jours, sachant que nous somme un " + jours[aujourdhui] + " nous serons un " + jours[jour_cible])

console.log("Exercice 2")

/**
 * Créer un tableau à deux dimensions de largeur 10 et de hauteur 10, la remplir de 0, assurer que tout le tour du tableau soit remplis de X.
 *   Exemple:
 *   XXXXXX
 *   X0000X
 *   XXXXXX
 */

// methode feignant:

tableau = [
    ["X", "X", "X", "X", "X", "X", "X", "X", "X", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "X", "X", "X", "X", "X", "X", "X", "X", "X"],
]

// methode class ;p

// on créer un tableau qui servira de resultat..
tableau_2 = []

// on va faire varier ligne de 0 a 9

// var ligne = 0; on commence a ligne = 0
// ligne < 10 ; tant que ligne < 10
// ligne++ est equivalent a ligne + 1
for (var ligne = 0; ligne < 10; ligne++) {

    // on créer un tableau qui contiendra notre ligne :)
    ligne_c = []

    // on fait la meme chose pour les colones.
    for (var colone = 0; colone < 10; colone++) {
        // cas de la premiere et derniere ligne.
        if (ligne == 0 || ligne == 9) {
            ligne_c.push("X");

            // cas de la premiere et derniere colone.
        } else if (colone == 0 || colone == 9) {
            ligne_c.push("X");
        } else {
            // le reste :) on remplis de 0
            ligne_c.push("0");
        }
    }
    // on ajoute au tableau la nouvelle ligne.
    tableau_2.push(ligne_c);
}

console.log("Exercice 3");
/**
Faire une fonction qui imprime le tableau sur la sortie standard(params: le tableau)

*/

print = function(tableau) {
    // on itere sur tout les elements du tableau.
    // on se rappelera que tableau.length donne la taille du tableau.
    for (var i = 0; i < tableau.length; i++) {
        // <liste>.join(seperateur) : ici: tableau[i].join("") permet d'ajouter tout les elements les un apres les autres.
        // par exemple [1,2,3].join("-") produirai 1-2-3
        console.log(tableau[i].join(""))
    }
}

print(tableau_2);

console.log("Exercice 4");
/**
Faire une fonction qui retourne l’ objet a une position donnée du tableau(params: tableau, x, y) retourne {: ok, valeur }, {: erreur,: x_invalide }, {: erreur,: y_invalide }

*/

search = function(tableau, x, y) {
    // en javascript and s'ecris &&
    // ici on test que x est dans le tableau
    // (sinon javascript pas content)
    if (x >= 0 && x < tableau.length) {
        ligne = tableau[x];
        // même chose avec les colones.
        if (y >= 0 && y < ligne.length) {
            return { ok: ligne[y] }
        } else {
            return { erreur: "y_invalide" }
        }
    } else
        return { erreur: "x_invalide" }
}

console.log(search(tableau, 5, 5).ok);
// pour affichier les structure, il vaux mieu utiliser JSON.stringify.
// cela permet de transfomer la structure en JSON
// on vera ce qu'est JSON un autre jour ;) mais pour faire simple, cela transforme un objet en string :)
console.log(JSON.stringify(search(tableau, 0, 99)));
console.log(JSON.stringify(search(tableau, 99, 5)));

console.log("Exercice 5");
/**
 * Faire une fonction qui génère le tableau précédant, prenant en paramètre la hauteur et la largeur, elle doit renvoyer le {: ok, tableau }
ou {: erreur,: hauteur }
ou {: erreur,: largeur }
en cas de paramètres invalide.(paramètre valide: > 5)

*/

create = function(lignes, colones) {
    if (lignes <= 3) {
        return { erreur: "lignes" };
    }
    if (colones <= 3) {
        return { erreur: "colones" };
    }

    tableau = [];
    for (var ligne = 0; ligne < lignes; ligne++) {
        ligne_c = []
        for (var colone = 0; colone < colones; colone++) {
            // on notera qu'en javascript
            // or s'ecris ||
            if (ligne == 0 ||
                ligne == lignes - 1) {
                ligne_c.push("X");
            } else if (colone == 0 ||
                colone == colones - 1) {
                ligne_c.push("X");
            } else {
                ligne_c.push("0");
            }
        }
        tableau.push(ligne_c)
    }

    return { ok: tableau };
}

tableau = create(5, 5);
print(tableau.ok);
mauvais_tableau = create(0, 3);
console.log(JSON.stringify(mauvais_tableau))

console.log("Exercice 6");
/**
Faire une fonction qui ajoute un marqueur dans le tableau(params: tableau, marqueur(A, B, C, D), position).
En cas de positionnement valide(
    case cible = 0) renvois {: ok, nouveau tableau }, sinon {: erreur,: position_invalide }

*/

put = function(tableau, marqueur, x, y) {
    res = search(tableau, x, y);
    // On test qu'il n'y a pas d'erreur.
    if (res.erreur == undefined) {
        tableau[x][y] = marqueur;
        return { ok: tableau };
    } else {
        return { erreur: "position_invalide" };
    }
}

insert = function(tableau, marqueur, x, y) {
    ok = marqueur == "A" ||
        marqueur == "B" ||
        marqueur == "C" ||
        marqueur == "D";

    if (!ok) {
        return { erreur: "marqueur_invalide" }
    }

    res = search(tableau, x, y);
    if (res.erreur == undefined) {
        if (res.ok == "0") {
            return put(tableau, marqueur, x, y);
        } else {
            return { erreur: "position_invalide" }
        }
    } else {
        return { erreur: "position_invalide" }
    }
}

t = create(5, 5).ok;
print(t);
nouveau_tableau = insert(t, "A", 2, 2).ok;
print(nouveau_tableau);
// Attention :) Vous pourrez constaté que la table d'origne a été modifiée !
print(t);
fail = insert(t, "O", 344, 232);
console.log(JSON.stringify(fail));

console.log("Exercice 7");
/*
Faire une fonction qui déplace un marqueur dans le tableau(params: tableau, position du marqueur, nouvelle position)
Valid: position dans le tableau = A B C D, nouvelle position = 0 {: ok, nouveau tableau }
sinon {: erreur,: origine_invalide }
sinon {: erreur,: cible_invalide }
*/

move = function(tableau, origin_x, origin_y, x, y) {
    origin = search(tableau, origin_x, origin_y);
    if (origin.erreur == undefined) {
        if (origin.ok == "A" ||
            origin.ok == "B" ||
            origin.ok == "C" ||
            origin.ok == "D") {
            target = insert(tableau, origin.ok, x, y);
            if (target.erreur == undefined) {
                res = put(target.ok, "0", origin_x, origin_y);
                if (res.erreur == undefined) {
                    return { ok: res.ok };
                } else {
                    return { erreur: "cible_invalide" };
                }
            } else {
                return { erreur: "cible_invalide" };
            }
        } else {
            return { erreur: "origine_invalide" };
        }
    } else {
        return { erreur: "origine_invalide" };
    }
}

tableau = create(5, 5).ok;
print(tableau);
nouveau_tableau = insert(tableau, "A", 2, 2).ok;
print(nouveau_tableau);
tableau_2 = move(nouveau_tableau, 2, 2, 3, 3).ok;
print(tableau_2);<commit_msg>fail: inversion ligne colonnes ... :)<commit_after>/**
 * En javascript les commentaires sont indiqué de deux facons:
 *  soit par /* */
/*  soit par //

    Pour tester le fichier, il suffit d'appeler node exos/c1/corrige.js
*/

console.log("Exercice 1")

/**
Sachant le jour(L / M / Me / J / V / S / D) courant, quel jour on sera dans x jours.
*/

jours = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"]
aujourdhui = 4
dans_x_jours = 45

// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators
// l'operateur % donne le reste d'une division.
jour_cible = (aujourdhui + dans_x_jours) % 7
console.log("Dans " + dans_x_jours + " jours, sachant que nous somme un " + jours[aujourdhui] + " nous serons un " + jours[jour_cible])

console.log("Exercice 2")

/**
 * Créer un tableau à deux dimensions de largeur 10 et de hauteur 10, la remplir de 0, assurer que tout le tour du tableau soit remplis de X.
 *   Exemple:
 *   XXXXXX
 *   X0000X
 *   XXXXXX
 */

// methode feignant:

tableau = [
    ["X", "X", "X", "X", "X", "X", "X", "X", "X", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "0", "0", "0", "0", "0", "0", "0", "0", "X"],
    ["X", "X", "X", "X", "X", "X", "X", "X", "X", "X"],
]

// methode class ;p

// on créer un tableau qui servira de resultat..
tableau_2 = []

// on va faire varier ligne de 0 a 9

// var ligne = 0; on commence a ligne = 0
// ligne < 10 ; tant que ligne < 10
// ligne++ est equivalent a ligne + 1
for (var ligne = 0; ligne < 10; ligne++) {

    // on créer un tableau qui contiendra notre ligne :)
    ligne_c = []

    // on fait la meme chose pour les colones.
    for (var colone = 0; colone < 10; colone++) {
        // cas de la premiere et derniere ligne.
        if (ligne == 0 || ligne == 9) {
            ligne_c.push("X");

            // cas de la premiere et derniere colone.
        } else if (colone == 0 || colone == 9) {
            ligne_c.push("X");
        } else {
            // le reste :) on remplis de 0
            ligne_c.push("0");
        }
    }
    // on ajoute au tableau la nouvelle ligne.
    tableau_2.push(ligne_c);
}

console.log("Exercice 3");
/**
Faire une fonction qui imprime le tableau sur la sortie standard(params: le tableau)

*/

print = function(tableau) {
    // on itere sur tout les elements du tableau.
    // on se rappelera que tableau.length donne la taille du tableau.
    for (var i = 0; i < tableau.length; i++) {
        // <liste>.join(seperateur) : ici: tableau[i].join("") permet d'ajouter tout les elements les un apres les autres.
        // par exemple [1,2,3].join("-") produirai 1-2-3
        console.log(tableau[i].join(""))
    }
}

print(tableau_2);

console.log("Exercice 4");
/**
Faire une fonction qui retourne l’ objet a une position donnée du tableau(params: tableau, x, y) retourne {: ok, valeur }, {: erreur,: x_invalide }, {: erreur,: y_invalide }
On notera que le premier tableau correspond au lignes, et les tableaux a l'interieur correspondes au case ( colones ) de chaque ligne !
*/

search = function(tableau, x, y) {
    // en javascript and s'ecris &&
    // ici on test que x est dans le tableau
    // (sinon javascript pas content)
    if (y >= 0 && y < tableau.length) {
        ligne = tableau[y];
        // même chose avec les colones.
        if (x >= 0 && x < ligne.length) {
            return { ok: ligne[x] }
        } else {
            return { erreur: "x_invalide" }
        }
    } else
        return { erreur: "y_invalide" }
}

console.log(search(tableau, 5, 5).ok);
// pour affichier les structure, il vaux mieu utiliser JSON.stringify.
// cela permet de transfomer la structure en JSON
// on vera ce qu'est JSON un autre jour ;) mais pour faire simple, cela transforme un objet en string :)
console.log(JSON.stringify(search(tableau, 0, 99)));
console.log(JSON.stringify(search(tableau, 99, 5)));

console.log("Exercice 5");
/**
 * Faire une fonction qui génère le tableau précédant, prenant en paramètre la hauteur et la largeur, elle doit renvoyer le {: ok, tableau }
ou {: erreur,: hauteur }
ou {: erreur,: largeur }
en cas de paramètres invalide.(paramètre valide: > 5)

*/

create = function(lignes, colones) {
    if (lignes <= 3) {
        return { erreur: "lignes" };
    }
    if (colones <= 3) {
        return { erreur: "colones" };
    }

    tableau = [];
    for (var ligne = 0; ligne < lignes; ligne++) {
        ligne_c = []
        for (var colone = 0; colone < colones; colone++) {
            // on notera qu'en javascript
            // or s'ecris ||
            if (ligne == 0 ||
                ligne == lignes - 1) {
                ligne_c.push("X");
            } else if (colone == 0 ||
                colone == colones - 1) {
                ligne_c.push("X");
            } else {
                ligne_c.push("0");
            }
        }
        tableau.push(ligne_c)
    }

    return { ok: tableau };
}

tableau = create(5, 5);
print(tableau.ok);
mauvais_tableau = create(0, 3);
console.log(JSON.stringify(mauvais_tableau))

console.log("Exercice 6");
/**
Faire une fonction qui ajoute un marqueur dans le tableau(params: tableau, marqueur(A, B, C, D), position).
En cas de positionnement valide(
    case cible = 0) renvois {: ok, nouveau tableau }, sinon {: erreur,: position_invalide }

*/

put = function(tableau, marqueur, x, y) {
    res = search(tableau, x, y);
    // On test qu'il n'y a pas d'erreur.
    if (res.erreur == undefined) {
        tableau[y][x] = marqueur;
        return { ok: tableau };
    } else {
        return { erreur: "position_invalide" };
    }
}

insert = function(tableau, marqueur, x, y) {
    ok = marqueur == "A" ||
        marqueur == "B" ||
        marqueur == "C" ||
        marqueur == "D";

    if (!ok) {
        return { erreur: "marqueur_invalide" }
    }

    res = search(tableau, x, y);
    if (res.erreur == undefined) {
        if (res.ok == "0") {
            return put(tableau, marqueur, x, y);
        } else {
            return { erreur: "position_invalide" }
        }
    } else {
        return { erreur: "position_invalide" }
    }
}

t = create(5, 5).ok;
print(t);
nouveau_tableau = insert(t, "A", 2, 2).ok;
print(nouveau_tableau);
// Attention :) Vous pourrez constaté que la table d'origne a été modifiée !
print(t);
fail = insert(t, "O", 344, 232);
console.log(JSON.stringify(fail));

console.log("Exercice 7");
/*
Faire une fonction qui déplace un marqueur dans le tableau(params: tableau, position du marqueur, nouvelle position)
Valid: position dans le tableau = A B C D, nouvelle position = 0 {: ok, nouveau tableau }
sinon {: erreur,: origine_invalide }
sinon {: erreur,: cible_invalide }
*/

move = function(tableau, origin_x, origin_y, x, y) {
    origin = search(tableau, origin_x, origin_y);
    if (origin.erreur == undefined) {
        if (origin.ok == "A" ||
            origin.ok == "B" ||
            origin.ok == "C" ||
            origin.ok == "D") {
            target = insert(tableau, origin.ok, x, y);
            if (target.erreur == undefined) {
                res = put(target.ok, "0", origin_x, origin_y);
                if (res.erreur == undefined) {
                    return { ok: res.ok };
                } else {
                    return { erreur: "cible_invalide" };
                }
            } else {
                return { erreur: "cible_invalide" };
            }
        } else {
            return { erreur: "origine_invalide" };
        }
    } else {
        return { erreur: "origine_invalide" };
    }
}

tableau = create(5, 5).ok;
print(tableau);
nouveau_tableau = insert(tableau, "A", 2, 2).ok;
print(nouveau_tableau);
tableau_2 = move(nouveau_tableau, 2, 2, 3, 3).ok;
print(tableau_2);<|endoftext|>