<commit_before>'use strict';

angular.module('app').controller('listConnectionsCtrl', [
  '$scope',
  '$timeout',
  'connectionCache',
  'notificationService',
  function($scope, $timeout, connectionCache, notificationService) {
    const connectionModule = require('lib/modules/connection');
    const logger = require('lib/modules/logger');

    $scope.connections = [];

    $scope.loading = false;

    $scope.$parent.selectedConnection = null; //reset the parent's selected connection

    _listConnections();

    $scope.selectAndConnect = function(connection, $event) {
      if (!connection) return false;
      if ($event) $event.preventDefault();

      _.each($scope.connections, (conn) => {
        conn.selected = false;
      });

      connection.selected = true;

      $scope.connect();
    };

    $scope.selectConnection = function(connection, $event) {
      if (!connection) return false;
      if ($event) $event.preventDefault();

      if (connection.selected) {
        connection.selected = false;
        return;
      }

      _.each($scope.connections, function(conn) {
        conn.selected = false;
      });

      connection.selected = true;
    };

    $scope.copyConnection = function(connection, $event) {
      if (!connection) return false;
      if ($event) $event.preventDefault();

      let newConnection = _.clone(connection);
      delete newConnection.id;
      newConnection.name += ' copy';

      $scope.changePage('add', newConnection);
    };

    $scope.connectionSelected = function() {
      return _.any($scope.connections, (conn) => {
        return conn.selected;
      });
    };

    $scope.connect = function($event) {
      if ($event) $event.preventDefault();

      var activeConnection = _.findWhere($scope.connections, {
        selected: true
      });

      if (!activeConnection) return;

      activeConnection.connecting = true;

      let startTime = performance.now();

      activeConnection.connect()
        .then(() => {
          var ellapsed = (performance.now() - startTime).toFixed(5);

          $timeout(() => {
            connectionCache.add(activeConnection);

            $scope.close();
          }, (ellapsed >= 1000 ? 0 : 1000));
        })
        .catch(() => {
          $timeout(() => {
            notificationService.error({
              title: 'Error connecting',
              message: 'Error connecting to your database. Verify your connection settings are correct.'
                // message: err
            });
          });
        })
        .finally(() => {
          var ellapsed = (performance.now() - startTime).toFixed(5);

          $timeout(() => {
            activeConnection.connecting = false;
          }, (ellapsed >= 1000 ? 0 : 1000));
        });
    };

    function _listConnections() {
      $scope.loading = true;

      connectionModule.list()
        .then((connections) => {
          $timeout(() => {
            $scope.connections = connections;
          });
        })
        .catch((response) => {
          $timeout(() => {
            logger.error(response);
          });
        })
        .finally(() => {
          $timeout(() => {
            $scope.loading = false;
          });
        });
    }
  }
]);
<commit_msg>better error message and stack for error when connecting to a database<commit_after>'use strict';

angular.module('app').controller('listConnectionsCtrl', [
  '$scope',
  '$timeout',
  'connectionCache',
  'notificationService',
  function($scope, $timeout, connectionCache, notificationService) {
    const connectionModule = require('lib/modules/connection');
    const logger = require('lib/modules/logger');

    $scope.connections = [];

    $scope.loading = false;

    $scope.$parent.selectedConnection = null; //reset the parent's selected connection

    _listConnections();

    $scope.selectAndConnect = function(connection, $event) {
      if (!connection) return false;
      if ($event) $event.preventDefault();

      _.each($scope.connections, (conn) => {
        conn.selected = false;
      });

      connection.selected = true;

      $scope.connect();
    };

    $scope.selectConnection = function(connection, $event) {
      if (!connection) return false;
      if ($event) $event.preventDefault();

      if (connection.selected) {
        connection.selected = false;
        return;
      }

      _.each($scope.connections, function(conn) {
        conn.selected = false;
      });

      connection.selected = true;
    };

    $scope.copyConnection = function(connection, $event) {
      if (!connection) return false;
      if ($event) $event.preventDefault();

      let newConnection = _.clone(connection);
      delete newConnection.id;
      newConnection.name += ' copy';

      $scope.changePage('add', newConnection);
    };

    $scope.connectionSelected = function() {
      return _.any($scope.connections, (conn) => {
        return conn.selected;
      });
    };

    $scope.connect = function($event) {
      if ($event) $event.preventDefault();

      var activeConnection = _.findWhere($scope.connections, {
        selected: true
      });

      if (!activeConnection) return;

      activeConnection.connecting = true;

      let startTime = performance.now();

      activeConnection.connect()
        .then(() => {
          var ellapsed = (performance.now() - startTime).toFixed(5);

          $timeout(() => {
            connectionCache.add(activeConnection);

            $scope.close();
          }, (ellapsed >= 1000 ? 0 : 1000));
        })
        .catch(err => {
          $timeout(() => {
            err.message = 'Error connecting to your database. Verify your connection settings are correct and the mongod process is running.';

            notificationService.error({
              title: 'Error connecting',
              message: err
            });
          });
        })
        .finally(() => {
          var ellapsed = (performance.now() - startTime).toFixed(5);

          $timeout(() => {
            activeConnection.connecting = false;
          }, (ellapsed >= 1000 ? 0 : 1000));
        });
    };

    function _listConnections() {
      $scope.loading = true;

      connectionModule.list()
        .then((connections) => {
          $timeout(() => {
            $scope.connections = connections;
          });
        })
        .catch((response) => {
          $timeout(() => {
            logger.error(response);
          });
        })
        .finally(() => {
          $timeout(() => {
            $scope.loading = false;
          });
        });
    }
  }
]);
<|endoftext|>


<commit_before>(function(d3) {
  d3.data = d3.data || {};

  d3.graph = function (graph) {
    var graph = graph ? graph : {},
        nodes = [],
        links = [];

    graph.description = function() {
      return "d3.data.graph with " + nodes.length + " nodes and " + links.length + " links";
    };

    graph.nodes = function(x) {
      if (!arguments.length) return nodes;
      nodes = x;
      return this;
    };

    graph.links = function(x) {
      if (!arguments.length) return links;
      links = x;
      return this;
    };

    graph.matrix = function(x) {
      if (!arguments.length) return d3.graph.fromList.matrix(links);
      links = d3.graph.toList.matrix(x);
      // TODO nodes
      return this;
    };

    graph.traverse = function() {
      var traversal = {},
          selected = {};            // selected entities

      traversal.filter = function(f) {
        // only works on nodes
        if (!arguments.length) return this;
        selected = nodes.filter(f);
        return this;
      };

      traversal.value = function(x) {
        if (!arguments.length) {
          // reset selection
          var result = selected;
          selected_type = false;
          selected = {};
          return result;
        }
        selected = x;
        return this;
      };

      traversal.selected_type = function(x) {
        if (!arguments.length) return selected_type;
        selected_type = x;
        return this;
      };

      return traversal;
    };

    return graph;
  };

  d3.graph.fromList = {
    matrix: function(links) {
      var matrix = [],
          n = links.length,
          max = d3.max(links, function(d) {
            return d3.max([d.source, d.target]);
          });

      // zero matrix
      var i = -1; while (++i <= max) {
        matrix[i] = [];
        var j = -1; while (++j <= max) {
          matrix[i][j] = 0;
        }
      }

      i = -1; while (++i < n) {
        matrix[ links[i].source ][ links[i].target ] = links[i].value;
      };

      return matrix;
    }
  };

  d3.graph.toList = {
    matrix: function(matrix) {
      var links = [],
          n = matrix.length;

      var i = -1; while (++i < n) {
        var j = -1; while (++j < n) {
          links.push({
            source: i,
            target: j,
            value: matrix[i][j]
          });
        }
      }

      return links
    }
  };

})(d3);
<commit_msg>removed d3.data references<commit_after>(function(d3) {
  d3.graph = function (graph) {
    var graph = graph ? graph : {},
        nodes = [],
        links = [];

    graph.description = function() {
      return "d3.graph with " + nodes.length + " nodes and " + links.length + " links";
    };

    graph.nodes = function(x) {
      if (!arguments.length) return nodes;
      nodes = x;
      return this;
    };

    graph.links = function(x) {
      if (!arguments.length) return links;
      links = x;
      return this;
    };

    graph.matrix = function(x) {
      if (!arguments.length) return d3.graph.fromList.matrix(links);
      links = d3.graph.toList.matrix(x);
      // TODO nodes
      return this;
    };

    graph.traverse = function() {
      var traversal = {},
          selected = {};            // selected entities

      traversal.filter = function(f) {
        // only works on nodes
        if (!arguments.length) return this;
        selected = nodes.filter(f);
        return this;
      };

      traversal.value = function(x) {
        if (!arguments.length) {
          // reset selection
          var result = selected;
          selected_type = false;
          selected = {};
          return result;
        }
        selected = x;
        return this;
      };

      traversal.selected_type = function(x) {
        if (!arguments.length) return selected_type;
        selected_type = x;
        return this;
      };

      return traversal;
    };

    return graph;
  };

  d3.graph.fromList = {
    matrix: function(links) {
      var matrix = [],
          n = links.length,
          max = d3.max(links, function(d) {
            return d3.max([d.source, d.target]);
          });

      // zero matrix
      var i = -1; while (++i <= max) {
        matrix[i] = [];
        var j = -1; while (++j <= max) {
          matrix[i][j] = 0;
        }
      }

      i = -1; while (++i < n) {
        matrix[ links[i].source ][ links[i].target ] = links[i].value;
      };

      return matrix;
    }
  };

  d3.graph.toList = {
    matrix: function(matrix) {
      var links = [],
          n = matrix.length;

      var i = -1; while (++i < n) {
        var j = -1; while (++j < n) {
          links.push({
            source: i,
            target: j,
            value: matrix[i][j]
          });
        }
      }

      return links
    }
  };

})(d3);
<|endoftext|>


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

    var mod = angular.module("slugifier", []);

    // Unicode (non-control) characters in the Latin-1 Supplement and Latin
    // Extended-A blocks, transliterated into ASCII characters.
    var charmap = {
        ' ': " ",
        '¡': "!",
        '¢': "c",
        '£': "lb",
        '¥': "yen",
        '¦': "|",
        '§': "SS",
        '¨': "\"",
        '©': "(c)",
        'ª': "a",
        '«': "<<",
        '¬': "not",
        /* jshint -W100 */
        '': "-",
        /* jshint +W100 */
        '®': "(R)",
        '°': "^0",
        '±': "+/-",
        '²': "^2",
        '³': "^3",
        '´': "'",
        'µ': "u",
        '¶': "P",
        '·': ".",
        '¸': ",",
        '¹': "^1",
        'º': "o",
        '»': ">>",
        '¼': " 1/4 ",
        '½': " 1/2 ",
        '¾': " 3/4 ",
        '¿': "?",
        'À': "`A",
        'Á': "'A",
        'Â': "^A",
        'Ã': "~A",
        'Ä': '"A',
        'Å': "A",
        'Æ': "AE",
        'Ç': "C",
        'È': "`E",
        'É': "'E",
        'Ê': "^E",
        'Ë': '"E',
        'Ì': "`I",
        'Í': "'I",
        'Î': "^I",
        'Ï': '"I',
        'Ð': "D",
        'Ñ': "~N",
        'Ò': "`O",
        'Ó': "'O",
        'Ô': "^O",
        'Õ': "~O",
        'Ö': '"O',
        '×': "x",
        'Ø': "O",
        'Ù': "`U",
        'Ú': "'U",
        'Û': "^U",
        'Ü': '"U',
        'Ý': "'Y",
        'Þ': "Th",
        'ß': "ss",
        'à': "`a",
        'á': "'a",
        'â': "^a",
        'ã': "~a",
        'ä': '"a',
        'å': "a",
        'æ': "ae",
        'ç': "c",
        'è': "`e",
        'é': "'e",
        'ê': "^e",
        'ë': '"e',
        'ì': "`i",
        'í': "'i",
        'î': "^i",
        'ï': '"i',
        'ð': "d",
        'ñ': "~n",
        'ò': "`o",
        'ó': "'o",
        'ô': "^o",
        'õ': "~o",
        'ö': '"o',
        '÷': ":",
        'ø': "o",
        'ù': "`u",
        'ú': "'u",
        'û': "^u",
        'ü': '"u',
        'ý': "'y",
        'þ': "th",
        'ÿ': '"y',
        'Ā': "A",
        'ā': "a",
        'Ă': "A",
        'ă': "a",
        'Ą': "A",
        'ą': "a",
        'Ć': "'C",
        'ć': "'c",
        'Ĉ': "^C",
        'ĉ': "^c",
        'Ċ': "C",
        'ċ': "c",
        'Č': "C",
        'č': "c",
        'Ď': "D",
        'ď': "d",
        'Đ': "D",
        'đ': "d",
        'Ē': "E",
        'ē': "e",
        'Ĕ': "E",
        'ĕ': "e",
        'Ė': "E",
        'ė': "e",
        'Ę': "E",
        'ę': "e",
        'Ě': "E",
        'ě': "e",
        'Ĝ': "^G",
        'ĝ': "^g",
        'Ğ': "G",
        'ğ': "g",
        'Ġ': "G",
        'ġ': "g",
        'Ģ': "G",
        'ģ': "g",
        'Ĥ': "^H",
        'ĥ': "^h",
        'Ħ': "H",
        'ħ': "h",
        'Ĩ': "~I",
        'ĩ': "~i",
        'Ī': "I",
        'ī': "i",
        'Ĭ': "I",
        'ĭ': "i",
        'Į': "I",
        'į': "i",
        'İ': "I",
        'ı': "i",
        'Ĳ': "IJ",
        'ĳ': "ij",
        'Ĵ': "^J",
        'ĵ': "^j",
        'Ķ': "K",
        'ķ': "k",
        'Ĺ': "L",
        'ĺ': "l",
        'Ļ': "L",
        'ļ': "l",
        'Ľ': "L",
        'ľ': "l",
        'Ŀ': "L",
        'ŀ': "l",
        'Ł': "L",
        'ł': "l",
        'Ń': "'N",
        'ń': "'n",
        'Ņ': "N",
        'ņ': "n",
        'Ň': "N",
        'ň': "n",
        'ŉ': "'n",
        'Ō': "O",
        'ō': "o",
        'Ŏ': "O",
        'ŏ': "o",
        'Ő': '"O',
        'ő': '"o',
        'Œ': "OE",
        'œ': "oe",
        'Ŕ': "'R",
        'ŕ': "'r",
        'Ŗ': "R",
        'ŗ': "r",
        'Ř': "R",
        'ř': "r",
        'Ś': "'S",
        'ś': "'s",
        'Ŝ': "^S",
        'ŝ': "^s",
        'Ş': "S",
        'ş': "s",
        'Š': "S",
        'š': "s",
        'Ţ': "T",
        'ţ': "t",
        'Ť': "T",
        'ť': "t",
        'Ŧ': "T",
        'ŧ': "t",
        'Ũ': "~U",
        'ũ': "~u",
        'Ū': "U",
        'ū': "u",
        'Ŭ': "U",
        'ŭ': "u",
        'Ů': "U",
        'ů': "u",
        'Ű': '"U',
        'ű': '"u',
        'Ų': "U",
        'ų': "u",
        'Ŵ': "^W",
        'ŵ': "^w",
        'Ŷ': "^Y",
        'ŷ': "^y",
        'Ÿ': '"Y',
        'Ź': "'Z",
        'ź': "'z",
        'Ż': "Z",
        'ż': "z",
        'Ž': "Z",
        'ž': "z",
        'ſ': "s"
    };

    function _slugify(s) {
        if (!s) return "";
        var ascii = [];
        var ch, cp;
        for (var i = 0; i < s.length; i++) {
            if ((cp = s.charCodeAt(i)) < 0x180) {
                ch = String.fromCharCode(cp);
                ascii.push(charmap[ch] || ch);
            }
        }
        s = ascii.join("");
        s = s.replace(/[^\w\s-]/g, "").trim().toLowerCase();
        return s.replace(/[-\s]+/g, "-");
    }

    mod.factory("Slug", function () {
        return {
            slugify: _slugify
        };
    });

    mod.directive("slug", ["Slug", function (Slug) {
        return {
            restrict: "E",
            scope: {
                to: "=",
            },
            transclude: true,
            replace: true,
            template: "

",
            link: function(scope, elem, attrs) {
                if (!attrs.from) {
                    throw "must set attribute 'from'";
                }
                scope.$parent.$watch(attrs.from, function(val) {
                    scope.to = Slug.slugify(val);
                });
            }
        };
    }]);

    mod.filter("slugify", ["Slug", function (Slug) {
        return function (input) {
            return Slug.slugify(input);
        };
    }]);
})();
<commit_msg>test one cyr symbol<commit_after>(function () {
    "use strict";

    var mod = angular.module("slugifier", []);

    // Unicode (non-control) characters in the Latin-1 Supplement and Latin
    // Extended-A blocks, transliterated into ASCII characters.
    var charmap = {
        ' ': " ",
        '¡': "!",
        '¢': "c",
        '£': "lb",
        '¥': "yen",
        '¦': "|",
        '§': "SS",
        '¨': "\"",
        '©': "(c)",
        'ª': "a",
        '«': "<<",
        '¬': "not",
        /* jshint -W100 */
        '': "-",
        /* jshint +W100 */
        '®': "(R)",
        '°': "^0",
        '±': "+/-",
        '²': "^2",
        '³': "^3",
        '´': "'",
        'µ': "u",
        '¶': "P",
        '·': ".",
        '¸': ",",
        '¹': "^1",
        'º': "o",
        '»': ">>",
        '¼': " 1/4 ",
        '½': " 1/2 ",
        '¾': " 3/4 ",
        '¿': "?",
        'À': "`A",
        'Á': "'A",
        'Â': "^A",
        'Ã': "~A",
        'Ä': '"A',
        'Å': "A",
        'Æ': "AE",
        'Ç': "C",
        'È': "`E",
        'É': "'E",
        'Ê': "^E",
        'Ë': '"E',
        'Ì': "`I",
        'Í': "'I",
        'Î': "^I",
        'Ï': '"I',
        'Ð': "D",
        'Ñ': "~N",
        'Ò': "`O",
        'Ó': "'O",
        'Ô': "^O",
        'Õ': "~O",
        'Ö': '"O',
        '×': "x",
        'Ø': "O",
        'Ù': "`U",
        'Ú': "'U",
        'Û': "^U",
        'Ü': '"U',
        'Ý': "'Y",
        'Þ': "Th",
        'ß': "ss",
        'à': "`a",
        'á': "'a",
        'â': "^a",
        'ã': "~a",
        'ä': '"a',
        'å': "a",
        'æ': "ae",
        'ç': "c",
        'è': "`e",
        'é': "'e",
        'ê': "^e",
        'ë': '"e',
        'ì': "`i",
        'í': "'i",
        'î': "^i",
        'ï': '"i',
        'ð': "d",
        'ñ': "~n",
        'ò': "`o",
        'ó': "'o",
        'ô': "^o",
        'õ': "~o",
        'ö': '"o',
        '÷': ":",
        'ø': "o",
        'ù': "`u",
        'ú': "'u",
        'û': "^u",
        'ü': '"u',
        'ý': "'y",
        'þ': "th",
        'ÿ': '"y',
        'Ā': "A",
        'ā': "a",
        'Ă': "A",
        'ă': "a",
        'Ą': "A",
        'ą': "a",
        'Ć': "'C",
        'ć': "'c",
        'Ĉ': "^C",
        'ĉ': "^c",
        'Ċ': "C",
        'ċ': "c",
        'Č': "C",
        'č': "c",
        'Ď': "D",
        'ď': "d",
        'Đ': "D",
        'đ': "d",
        'Ē': "E",
        'ē': "e",
        'Ĕ': "E",
        'ĕ': "e",
        'Ė': "E",
        'ė': "e",
        'Ę': "E",
        'ę': "e",
        'Ě': "E",
        'ě': "e",
        'Ĝ': "^G",
        'ĝ': "^g",
        'Ğ': "G",
        'ğ': "g",
        'Ġ': "G",
        'ġ': "g",
        'Ģ': "G",
        'ģ': "g",
        'Ĥ': "^H",
        'ĥ': "^h",
        'Ħ': "H",
        'ħ': "h",
        'Ĩ': "~I",
        'ĩ': "~i",
        'Ī': "I",
        'ī': "i",
        'Ĭ': "I",
        'ĭ': "i",
        'Į': "I",
        'į': "i",
        'İ': "I",
        'ı': "i",
        'Ĳ': "IJ",
        'ĳ': "ij",
        'Ĵ': "^J",
        'ĵ': "^j",
        'Ķ': "K",
        'ķ': "k",
        'Ĺ': "L",
        'ĺ': "l",
        'Ļ': "L",
        'ļ': "l",
        'Ľ': "L",
        'ľ': "l",
        'Ŀ': "L",
        'ŀ': "l",
        'Ł': "L",
        'ł': "l",
        'Ń': "'N",
        'ń': "'n",
        'Ņ': "N",
        'ņ': "n",
        'Ň': "N",
        'ň': "n",
        'ŉ': "'n",
        'Ō': "O",
        'ō': "o",
        'Ŏ': "O",
        'ŏ': "o",
        'Ő': '"O',
        'ő': '"o',
        'Œ': "OE",
        'œ': "oe",
        'Ŕ': "'R",
        'ŕ': "'r",
        'Ŗ': "R",
        'ŗ': "r",
        'Ř': "R",
        'ř': "r",
        'Ś': "'S",
        'ś': "'s",
        'Ŝ': "^S",
        'ŝ': "^s",
        'Ş': "S",
        'ş': "s",
        'Š': "S",
        'š': "s",
        'Ţ': "T",
        'ţ': "t",
        'Ť': "T",
        'ť': "t",
        'Ŧ': "T",
        'ŧ': "t",
        'Ũ': "~U",
        'ũ': "~u",
        'Ū': "U",
        'ū': "u",
        'Ŭ': "U",
        'ŭ': "u",
        'Ů': "U",
        'ů': "u",
        'Ű': '"U',
        'ű': '"u',
        'Ų': "U",
        'ų': "u",
        'Ŵ': "^W",
        'ŵ': "^w",
        'Ŷ': "^Y",
        'ŷ': "^y",
        'Ÿ': '"Y',
        'Ź': "'Z",
        'ź': "'z",
        'Ż': "Z",
        'ż': "z",
        'Ž': "Z",
        'ž': "z",
        'ſ': "s",

		//Cyrillic
		'а': "a",

    };

    function _slugify(s) {
        if (!s) return "";
        var ascii = [];
        var ch, cp;
        for (var i = 0; i < s.length; i++) {
            if ((cp = s.charCodeAt(i)) < 0x180) {
                ch = String.fromCharCode(cp);
                ascii.push(charmap[ch] || ch);
            }
        }
        s = ascii.join("");
        s = s.replace(/[^\w\s-]/g, "").trim().toLowerCase();
        return s.replace(/[-\s]+/g, "-");
    }

    mod.factory("Slug", function () {
        return {
            slugify: _slugify
        };
    });

    mod.directive("slug", ["Slug", function (Slug) {
        return {
            restrict: "E",
            scope: {
                to: "=",
            },
            transclude: true,
            replace: true,
            template: "

",
            link: function(scope, elem, attrs) {
                if (!attrs.from) {
                    throw "must set attribute 'from'";
                }
                scope.$parent.$watch(attrs.from, function(val) {
                    scope.to = Slug.slugify(val);
                });
            }
        };
    }]);

    mod.filter("slugify", ["Slug", function (Slug) {
        return function (input) {
            return Slug.slugify(input);
        };
    }]);
})();
<|endoftext|>


<commit_before>let definitionService = ["ObjectFactory", "UtilitiesService", DefinitionsService];

export default definitionService;

/**
 * Module Service to hold the state and methods of definitions
 */
export function DefinitionsService(ObjectFactory, UtilitiesService) {

    var definitions = {};

    var publicAPI = {
        addDefinition,
        clearDefinitions,
        updateDefinition,
        getDefinitions,
        setDefinitions,
        getDefinition,
        deleteDefinition
    };

    return publicAPI;

    /**
     * Adds a new definition object to the list of definitions
     * @param {string} definitionName - name of definition object
     * @param {string} description - descrition of the definition object
     * @param {string} type - specific type of definition object
     */
    function addDefinition(definitionName, description, type) {
        if (definitions.hasOwnProperty(definitionName)) {
            // throw "Cannot Add, Definition Already Exists";
            console.warn("Cannot Add, Definition Already Exists");
            UtilitiesService.toast("Cannot Add, Definition Already Exists", 3000);
        } else {

            definitions[definitionName] = ObjectFactory.newSchema(definitionName, description, type);
        }
    }

    /**
     * Removes all definition keys from the list
     */
    function clearDefinitions() {
        for (var key in definitions) {
            if (definitions.hasOwnProperty(key)) {
                delete definitions[key];
            }
        }
    }

    /**
     * Updates a definition
     * @param {object} originalDefinition - original state of a definition
     * @param {object} updatedDefinition - modified definition
     */
    function updateDefinition(originalDefinition, updatedDefinition) {
        var oName = originalDefinition.name,
            // oValue = originalDefinition.value,
            uName = updatedDefinition.name,
            uValue = updatedDefinition.value;

        if (oName === uName) {
            var definitionToUpdate = definitions[oName];

            for (var defKey in definitionToUpdate) {
                if (definitionToUpdate.hasOwnProperty(defKey)) {
                    definitionToUpdate[defKey] = uValue[defKey];
                }
            }

        } else {

            if (definitions.hasOwnProperty(uName)) {
                UtilitiesService.toast("Definition already exists, cannot change definition name.", 3000);

                return;

            } else {

                addDefinition(uName);

                var currentDefinition = definitions[uName];

                for (var key in currentDefinition) {
                    if (currentDefinition.hasOwnProperty(key)) {
                        currentDefinition[key] = uValue[key];
                    }
                }

                delete definitions[oName];

            }
        }

    }

    /**
     * Returns the entire list of definitions
     * @returns {object}
     */
    function getDefinitions() {
        return definitions;
    }

    /**
     * Replaces the current definition set with a new definitions object
     * @param {object} newDefinitions - a list of definitions
     */
    function setDefinitions(newDefinitions) {
        for (var definition in newDefinitions) {
            if (newDefinitions.hasOwnProperty(definition)) {
                definitions[definition] = ObjectFactory.newSchema();
                definitions[definition].setSchema(definitions[definition]);
            }
        }
    }

    /**
     * Returns a specified definition
     * @param {string} definitionName - a specific definition key
     * @returns {object}
     */
    function getDefinition(definitionName) {
        return definitions[definitionName];
    }

    /**
     * Removes a specified definition
     * @param {string} definitionName - a specific definition key
     */
    function deleteDefinition(definitionName) {
        delete definitions[definitionName];
    }

}
<commit_msg>fixed definitions not being brought in properly<commit_after>let definitionService = ["ObjectFactory", "UtilitiesService", DefinitionsService];

export default definitionService;

/**
 * Module Service to hold the state and methods of definitions
 */
export function DefinitionsService(ObjectFactory, UtilitiesService) {

    var definitions = {};

    var publicAPI = {
        addDefinition,
        clearDefinitions,
        updateDefinition,
        getDefinitions,
        setDefinitions,
        getDefinition,
        deleteDefinition
    };

    return publicAPI;

    /**
     * Adds a new definition object to the list of definitions
     * @param {string} definitionName - name of definition object
     * @param {string} description - descrition of the definition object
     * @param {string} type - specific type of definition object
     */
    function addDefinition(definitionName, description, type) {
        if (definitions.hasOwnProperty(definitionName)) {
            // throw "Cannot Add, Definition Already Exists";
            console.warn("Cannot Add, Definition Already Exists");
            UtilitiesService.toast("Cannot Add, Definition Already Exists", 3000);
        } else {

            definitions[definitionName] = ObjectFactory.newSchema(definitionName, description, type);
        }
    }

    /**
     * Removes all definition keys from the list
     */
    function clearDefinitions() {
        for (var key in definitions) {
            if (definitions.hasOwnProperty(key)) {
                delete definitions[key];
            }
        }
    }

    /**
     * Updates a definition
     * @param {object} originalDefinition - original state of a definition
     * @param {object} updatedDefinition - modified definition
     */
    function updateDefinition(originalDefinition, updatedDefinition) {
        var oName = originalDefinition.name,
            // oValue = originalDefinition.value,
            uName = updatedDefinition.name,
            uValue = updatedDefinition.value;

        if (oName === uName) {
            var definitionToUpdate = definitions[oName];

            for (var defKey in definitionToUpdate) {
                if (definitionToUpdate.hasOwnProperty(defKey)) {
                    definitionToUpdate[defKey] = uValue[defKey];
                }
            }

        } else {

            if (definitions.hasOwnProperty(uName)) {
                UtilitiesService.toast("Definition already exists, cannot change definition name.", 3000);

                return;

            } else {

                addDefinition(uName);

                var currentDefinition = definitions[uName];

                for (var key in currentDefinition) {
                    if (currentDefinition.hasOwnProperty(key)) {
                        currentDefinition[key] = uValue[key];
                    }
                }

                delete definitions[oName];

            }
        }

    }

    /**
     * Returns the entire list of definitions
     * @returns {object}
     */
    function getDefinitions() {
        return definitions;
    }

    /**
     * Replaces the current definition set with a new definitions object
     * @param {object} newDefinitions - a list of definitions
     */
    function setDefinitions(newDefinitions) {
        debugger;
        for (var definition in newDefinitions) {
            if (newDefinitions.hasOwnProperty(definition)) {
                definitions[definition] = ObjectFactory.newSchema();
                definitions[definition].setSchema(newDefinitions[definition]);
            }
        }
    }

    /**
     * Returns a specified definition
     * @param {string} definitionName - a specific definition key
     * @returns {object}
     */
    function getDefinition(definitionName) {
        return definitions[definitionName];
    }

    /**
     * Removes a specified definition
     * @param {string} definitionName - a specific definition key
     */
    function deleteDefinition(definitionName) {
        delete definitions[definitionName];
    }

}
<|endoftext|>


<commit_before>'use strict';

var Mapusaurus = {
    //  Leaflet map
    map: null,
    //  Leaflet layers
    layers: {tract: {minority: null}},
    //  Stores geo data, along with fields for layers
    dataStore: {tract: {}},
    //  Stores stat data when the associated geos aren't loaded
    dataWithoutGeo: {tract: {minority: {}}},

    initialize: function (map) {
        map.setView([41.88, -87.63], 12);
        Mapusaurus.map = map;
        Mapusaurus.layers.tract.minority = L.geoJson(
            {type: 'FeatureCollection', features: []},
            {onEachFeature: Mapusaurus.eachMinority}
        );
        Mapusaurus.layers.tract.minority.addTo(map);
        //  @todo: really, we only care about the part of the viewport which
        //  is new
        map.on('moveend', Mapusaurus.reloadGeo);
        //  @todo: really, we only care on zoom-out + part which is new
        map.on('zoomend', Mapusaurus.reloadGeo);
        //  Kick it off
        Mapusaurus.reloadGeo();
    },

    /* Whenever the map is shifted/zoomed, reload geo data */
    reloadGeo: function() {
        var bounds = Mapusaurus.map.getBounds(),
            halfWidth = Math.abs(bounds.getEast() - bounds.getWest()) / 2,
            halfHeight = Math.abs(bounds.getNorth() - bounds.getSouth()) / 2,
            //  NW-hemisphere centric
            expandedN = bounds.getNorth() + halfHeight,
            expandedS = bounds.getSouth() - halfHeight,
            expandedW = bounds.getWest() - halfWidth,
            expandedE = bounds.getEast() + halfWidth;

        /* To be responsive, only load census tract data at zoom-level 10
         * or above */
        if (Mapusaurus.map.getZoom() >= 10) {
            Mapusaurus.loadTractData(
                1,
                L.latLngBounds(L.latLng(expandedS, expandedW),
                               L.latLng(expandedN, expandedE)));
        }
    },

    /* Load census tract geo data (by pages) into dataStore. Bounds should
     * remain consistent between pages of results */
    loadTractData: function(page, bounds) {
        //  This is north-western-hemisphere-centric for now
        $.getJSON('/shapes/tracts-in/?minlat=' + bounds.getSouth().toString() +
                  '&maxlat=' + bounds.getNorth().toString() +
                  '&minlon=' + bounds.getWest().toString() +
                  '&maxlon=' + bounds.getEast().toString() +
                  '&page_num=' + page.toString(),
                  function(data) {
            var newTracts = [];   //  geos we've never seen

            //  Collect new tracts, add them to dataStore
            _.each(data.features, function(feature) {
                var geoid = feature.properties.geoid;
                if (!_.has(Mapusaurus.dataStore.tract, geoid)) {
                    Mapusaurus.dataStore.tract[geoid] = feature;
                    newTracts.push(geoid);
                }
            });

            //  Check if there's anything new to draw, load stats data
            if (newTracts.length > 0) {
                Mapusaurus.updateDataWithoutGeos(newTracts);
                Mapusaurus.fetchMissingStats(newTracts);
            }

            //  Continue with next page of geo results
            if (data.features.length > 0) {
                Mapusaurus.loadTractData(page + 1, bounds);
            }
        });
    },

    /*  We may have previously loaded stats data without the geos. Run through
     *  that data and see if the new geo data matches */
    updateDataWithoutGeos: function(newTracts) {
        var toDraw = [];  // geoids
        _.each(newTracts, function(geoid) {
            //  Stats data is present
            if (_.has(Mapusaurus.dataWithoutGeo.tract.minority, geoid)) {
                Mapusaurus.dataStore.tract[geoid].properties.layer_minority =
                    Mapusaurus.dataWithoutGeo.tract.minority[geoid];
                toDraw.push(geoid);
                delete Mapusaurus.dataWithoutGeo.tract.minority[geoid];
            }
        });
        Mapusaurus.draw(toDraw);
    },

    /* We have geos without their associated stats - kick off the load */
    fetchMissingStats: function(newTracts) {
        var missingData = null,   //  state + county strings
            afterLoad = null;     //  fn to be called after each data load
        //  We only care about unseen stat data
        missingData = _.filter(newTracts, function(geoid) {
            return !_.has(Mapusaurus.dataStore.tract[geoid].properties,
                          'layer_minority');
        });
        //  convert to state + county strings
        missingData = _.map(missingData, function(geoid) {
            var geo = Mapusaurus.dataStore.tract[geoid];
            return geo.properties.statefp + geo.properties.countyfp;
        });
        missingData = _.uniq(missingData);

        afterLoad = function(data) {
            var toDraw = [];
            _.each(_.keys(data), function(geoid) {
                var geo = Mapusaurus.dataStore.tract[geoid];
                //  Have not loaded the geo data yet
                if (!geo) {
                    Mapusaurus.dataWithoutGeo.tract.minority[geoid] =
                        data[geoid].non_hisp_white_only_perc;
                //  Have the geo data, but haven't drawn the stats yet
                } else if (!geo.properties.layer_minority) {
                    geo.properties.layer_minority =
                        data[geoid].non_hisp_white_only_perc;
                    toDraw.push(geoid);
                }
            });
            Mapusaurus.draw(toDraw);
        };
        //  start loading the stat data
        _.each(missingData, function(stateCounty) {
            var state = stateCounty.substr(0, 2),
                county = stateCounty.substr(2);
            $.getJSON('/census/race-summary?state_fips=' + state +
                      '&county_fips=' + county, afterLoad);
        });
    },

    /* Given a list of geo ids, add them to the minority layer */
    draw: function(geoids) {
        var geoData = _.map(geoids, function(geoid) {
            return Mapusaurus.dataStore.tract[geoid];
        });
        Mapusaurus.layers.tract.minority.addData(geoData);
    },

    /* Style/extras for each census tract in the minorities layer */
    eachMinority: function(feature, layer) {
      var nonMinorityPercent = feature.properties.layer_minority;
      layer.setStyle({
          fillColor: Mapusaurus.getColorValue(1 - nonMinorityPercent),
          fillOpacity: 0.7,
          weight: 2,
          color: '#babbbd'
      });
      //  keep expected functionality with double clicking
      layer.on('dblclick', function(ev) {
        Mapusaurus.map.setZoomAround(ev.latlng, Mapusaurus.map.getZoom() + 1);
      });
      layer.on('mouseover', function() {
        $('

', {
          id: 'perc-popup-' + feature.properties.geoid,
          text: (nonMinorityPercent * 100).toFixed() +
                 '% Non-hispanic White-Only',
          css: {
            position: 'absolute',
            bottom: '85px',
            left: '50px',
            zIndex: 1002,
            backgroundColor: 'white',
            padding: '8px',
            border: '1px solid #ccc'
          }
        }).appendTo('#map');
      });
      layer.on('mouseout', function() {
        $('#perc-popup-' + feature.properties.geoid).remove();
      });
    },

    colorRanges: [
        {
            upperBound: 0.4999,
            colors: {
                lowR: 255,
                lowG: 255,
                lowB: 217,
                highR: 242,
                highG: 251,
                highB: 184
            }
        },
        {
            upperBound: 0.79999,
            colors: {
                lowR: 198,
                lowG: 234,
                lowB: 178,
                highR: 124,
                highG: 206,
                highB: 187
            }
        },
        {
            upperBound: 1,
            colors: {
                lowR: 14,
                lowG: 144,
                lowB: 194,
                highR: 29,
                highG: 92,
                highB: 170
            }
        }
    ],

    toBucket: function(percent) {
        var i,
            len = Mapusaurus.colorRanges.length;
        for (i = 0; i < len; i++) {
            if (Mapusaurus.colorRanges[i]['upperBound'] >= percent) {
                return Mapusaurus.colorRanges[i]['colors'];
            }
        }
    },

    getColorValue: function(percent) {
        var colorVals = Mapusaurus.toBucket(percent);
        return Mapusaurus.colorFromPercent(percent, colorVals);
    },

    /* Given low and high colors and a percent, figure out the RGB of said
     * percent in that scale */
    colorFromPercent: function(percent, c) {
        var diffR = (c.highR - c.lowR) * percent,
            diffG = (c.highG - c.lowG) * percent,
            diffB = (c.highB - c.lowB) * percent;
        return 'rgb(' + (c.lowR + diffR).toFixed() + ', ' +
               (c.lowG + diffG).toFixed() + ', ' +
               (c.lowB + diffB).toFixed() + ')';
    }
};
<commit_msg>more accurate upper bounds<commit_after>'use strict';

var Mapusaurus = {
    //  Leaflet map
    map: null,
    //  Leaflet layers
    layers: {tract: {minority: null}},
    //  Stores geo data, along with fields for layers
    dataStore: {tract: {}},
    //  Stores stat data when the associated geos aren't loaded
    dataWithoutGeo: {tract: {minority: {}}},

    initialize: function (map) {
        map.setView([41.88, -87.63], 12);
        Mapusaurus.map = map;
        Mapusaurus.layers.tract.minority = L.geoJson(
            {type: 'FeatureCollection', features: []},
            {onEachFeature: Mapusaurus.eachMinority}
        );
        Mapusaurus.layers.tract.minority.addTo(map);
        //  @todo: really, we only care about the part of the viewport which
        //  is new
        map.on('moveend', Mapusaurus.reloadGeo);
        //  @todo: really, we only care on zoom-out + part which is new
        map.on('zoomend', Mapusaurus.reloadGeo);
        //  Kick it off
        Mapusaurus.reloadGeo();
    },

    /* Whenever the map is shifted/zoomed, reload geo data */
    reloadGeo: function() {
        var bounds = Mapusaurus.map.getBounds(),
            halfWidth = Math.abs(bounds.getEast() - bounds.getWest()) / 2,
            halfHeight = Math.abs(bounds.getNorth() - bounds.getSouth()) / 2,
            //  NW-hemisphere centric
            expandedN = bounds.getNorth() + halfHeight,
            expandedS = bounds.getSouth() - halfHeight,
            expandedW = bounds.getWest() - halfWidth,
            expandedE = bounds.getEast() + halfWidth;

        /* To be responsive, only load census tract data at zoom-level 10
         * or above */
        if (Mapusaurus.map.getZoom() >= 10) {
            Mapusaurus.loadTractData(
                1,
                L.latLngBounds(L.latLng(expandedS, expandedW),
                               L.latLng(expandedN, expandedE)));
        }
    },

    /* Load census tract geo data (by pages) into dataStore. Bounds should
     * remain consistent between pages of results */
    loadTractData: function(page, bounds) {
        //  This is north-western-hemisphere-centric for now
        $.getJSON('/shapes/tracts-in/?minlat=' + bounds.getSouth().toString() +
                  '&maxlat=' + bounds.getNorth().toString() +
                  '&minlon=' + bounds.getWest().toString() +
                  '&maxlon=' + bounds.getEast().toString() +
                  '&page_num=' + page.toString(),
                  function(data) {
            var newTracts = [];   //  geos we've never seen

            //  Collect new tracts, add them to dataStore
            _.each(data.features, function(feature) {
                var geoid = feature.properties.geoid;
                if (!_.has(Mapusaurus.dataStore.tract, geoid)) {
                    Mapusaurus.dataStore.tract[geoid] = feature;
                    newTracts.push(geoid);
                }
            });

            //  Check if there's anything new to draw, load stats data
            if (newTracts.length > 0) {
                Mapusaurus.updateDataWithoutGeos(newTracts);
                Mapusaurus.fetchMissingStats(newTracts);
            }

            //  Continue with next page of geo results
            if (data.features.length > 0) {
                Mapusaurus.loadTractData(page + 1, bounds);
            }
        });
    },

    /*  We may have previously loaded stats data without the geos. Run through
     *  that data and see if the new geo data matches */
    updateDataWithoutGeos: function(newTracts) {
        var toDraw = [];  // geoids
        _.each(newTracts, function(geoid) {
            //  Stats data is present
            if (_.has(Mapusaurus.dataWithoutGeo.tract.minority, geoid)) {
                Mapusaurus.dataStore.tract[geoid].properties.layer_minority =
                    Mapusaurus.dataWithoutGeo.tract.minority[geoid];
                toDraw.push(geoid);
                delete Mapusaurus.dataWithoutGeo.tract.minority[geoid];
            }
        });
        Mapusaurus.draw(toDraw);
    },

    /* We have geos without their associated stats - kick off the load */
    fetchMissingStats: function(newTracts) {
        var missingData = null,   //  state + county strings
            afterLoad = null;     //  fn to be called after each data load
        //  We only care about unseen stat data
        missingData = _.filter(newTracts, function(geoid) {
            return !_.has(Mapusaurus.dataStore.tract[geoid].properties,
                          'layer_minority');
        });
        //  convert to state + county strings
        missingData = _.map(missingData, function(geoid) {
            var geo = Mapusaurus.dataStore.tract[geoid];
            return geo.properties.statefp + geo.properties.countyfp;
        });
        missingData = _.uniq(missingData);

        afterLoad = function(data) {
            var toDraw = [];
            _.each(_.keys(data), function(geoid) {
                var geo = Mapusaurus.dataStore.tract[geoid];
                //  Have not loaded the geo data yet
                if (!geo) {
                    Mapusaurus.dataWithoutGeo.tract.minority[geoid] =
                        data[geoid].non_hisp_white_only_perc;
                //  Have the geo data, but haven't drawn the stats yet
                } else if (!geo.properties.layer_minority) {
                    geo.properties.layer_minority =
                        data[geoid].non_hisp_white_only_perc;
                    toDraw.push(geoid);
                }
            });
            Mapusaurus.draw(toDraw);
        };
        //  start loading the stat data
        _.each(missingData, function(stateCounty) {
            var state = stateCounty.substr(0, 2),
                county = stateCounty.substr(2);
            $.getJSON('/census/race-summary?state_fips=' + state +
                      '&county_fips=' + county, afterLoad);
        });
    },

    /* Given a list of geo ids, add them to the minority layer */
    draw: function(geoids) {
        var geoData = _.map(geoids, function(geoid) {
            return Mapusaurus.dataStore.tract[geoid];
        });
        Mapusaurus.layers.tract.minority.addData(geoData);
    },

    /* Style/extras for each census tract in the minorities layer */
    eachMinority: function(feature, layer) {
      var nonMinorityPercent = feature.properties.layer_minority;
      layer.setStyle({
          fillColor: Mapusaurus.getColorValue(1 - nonMinorityPercent),
          fillOpacity: 0.7,
          weight: 2,
          color: '#babbbd'
      });
      //  keep expected functionality with double clicking
      layer.on('dblclick', function(ev) {
        Mapusaurus.map.setZoomAround(ev.latlng, Mapusaurus.map.getZoom() + 1);
      });
      layer.on('mouseover', function() {
        $('

', {
          id: 'perc-popup-' + feature.properties.geoid,
          text: (nonMinorityPercent * 100).toFixed() +
                 '% Non-hispanic White-Only',
          css: {
            position: 'absolute',
            bottom: '85px',
            left: '50px',
            zIndex: 1002,
            backgroundColor: 'white',
            padding: '8px',
            border: '1px solid #ccc'
          }
        }).appendTo('#map');
      });
      layer.on('mouseout', function() {
        $('#perc-popup-' + feature.properties.geoid).remove();
      });
    },

    colorRanges: [
        {
            upperBound: 0.5,
            colors: {
                lowR: 255,
                lowG: 255,
                lowB: 217,
                highR: 242,
                highG: 251,
                highB: 184
            }
        },
        {
            upperBound: 0.8,
            colors: {
                lowR: 198,
                lowG: 234,
                lowB: 178,
                highR: 124,
                highG: 206,
                highB: 187
            }
        },
        {
            upperBound: 1,
            colors: {
                lowR: 14,
                lowG: 144,
                lowB: 194,
                highR: 29,
                highG: 92,
                highB: 170
            }
        }
    ],

    toBucket: function(percent) {
        var i,
            len = Mapusaurus.colorRanges.length;
        for (i = 0; i < len; i++) {
            if (Mapusaurus.colorRanges[i]['upperBound'] > percent) {
                return Mapusaurus.colorRanges[i]['colors'];
            }
        }
    },

    getColorValue: function(percent) {
        var colorVals = Mapusaurus.toBucket(percent);
        return Mapusaurus.colorFromPercent(percent, colorVals);
    },

    /* Given low and high colors and a percent, figure out the RGB of said
     * percent in that scale */
    colorFromPercent: function(percent, c) {
        var diffR = (c.highR - c.lowR) * percent,
            diffG = (c.highG - c.lowG) * percent,
            diffB = (c.highB - c.lowB) * percent;
        return 'rgb(' + (c.lowR + diffR).toFixed() + ', ' +
               (c.lowG + diffG).toFixed() + ', ' +
               (c.lowB + diffB).toFixed() + ')';
    }
};
<|endoftext|>


<commit_before>$(function() {
    Settings = window.Settings;
    PushManager = window.PushManager || {};
    PushManager.Request = PushManager.Request || {}

    PushManager.Request.format_comments_dom = function(domobj) {
        var link_re = /((?:http:\/\/|https:\/\/)?(?:\w+\.)+(?!py|tmpl|js)[a-z]{2,}(?:\/\S*)*)/ig

        var that = $(domobj);
        var data = that.text();

        // Escape
        data = data.replace(/</g, '<');
        data = data.replace(/>/g, '>');
        data = data.replace(/"/g, '"');

        // Newlines -> Rendered newlines
        data = data.replace(/\n/g, '\n
');

        // Bold comment headers
        data = data.replace(/Comment from \w+:/g, function(m) { return '' + m + ''; });

        // Linkify
        data = data.replace(link_re, function(match) {
            return '' + match + '';
        });

        that.html(data);
    };

    // Format initial comments
    $('.request-comments').each(function() { PushManager.Request.format_comments_dom(this); });
    $('.request-description').each(function() { PushManager.Request.format_comments_dom(this); });

    PushManager.Request.expand_push_item = function() {
        var that = $(this);
        var req = that.closest('.request-module');
        req.find('.request-info-extended').toggle();
        var button = req.find('.request-item-expander');
        if(button.attr('src') == "/static/img/button_hide.gif") {
            button.attr('src', "/static/img/button_expand.gif");
        } else {
            button.attr('src', "/static/img/button_hide.gif");
        }
    };

    PushManager.Request.collapse_push_item = function() {
        var that = $(this);
        var req = that.find('.request-module');
        req.find('.request-info-extended').hide();
        var button = req.find('.request-item-expander');
        button.attr('src', "/static/img/button_expand.gif");
    };

    // Bind expander to both title and expand icon
    $('.request-item-expander, .request-item-title').live('click', PushManager.Request.expand_push_item);
    $('.request-item-expander[expand=yes]').each(PushManager.Request.expand_push_item);

    PushManager.Request.delay_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        $.ajax({
            'type': 'POST',
            'url': '/delayrequest',
            'data': {'id': requestid},
            'success': function() { window.location.reload(); },
            'error': function() { alert('Something went wrong while trying to delay the request.'); }
        });
    };

    PushManager.Request.pushmaster_delay_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        $.ajax({
            'type': 'POST',
            'url': '/delayrequest',
            'data': {'id': requestid},
            'success': function() { that.parent("li").remove(); },
            'error': function() { alert('Something went wrong while trying to delay the request.'); }
        });
    };

    PushManager.Request.undelay_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        $.ajax({
            'type': 'POST',
            'url': '/undelayrequest',
            'data': {'id': requestid},
            'success': function() { window.location.reload(); },
            'error': function() { alert('Something went wrong while trying to un-delay the request.'); }
        });
    };

    PushManager.Request.discard_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        if(confirm("Are you sure you want to discard this request?")) {
            $.ajax({
                'type': 'POST',
                'url': '/discardrequest',
                'data': {'id': requestid},
                'success': function() { window.location.reload(); },
                'error': function() { alert('Something went wrong while trying to discard the request.'); }
            });
        }
    };

    // Bind various buttons
    $('.delay-request').live('click', PushManager.Request.delay_request);
    $('.pushmaster-delay-request').live('click', PushManager.Request.pushmaster_delay_request);
    $('.undelay-request').live('click', PushManager.Request.undelay_request);
    $('.discard-request').live('click', PushManager.Request.discard_request);

    PushManager.Request.load_bb_failures = function(domobj) {
        var dataurl = "https://" + Settings['buildbot']['servername'] + "/rev/%REVISION%";
        var that = $(domobj);
        if(that.hasClass('bb-data-loaded')) {
            return;
        }
        var req = that.closest('.request-module');

        var revision = req.attr('revision');
        $.ajax({
            'url': dataurl.replace('%REVISION%', revision),
            'data': {'format': 'json'},
            'dataType': 'json',
            'success': function(data) {
                if(!data || data.error) {
                    that.find('a').first().append(' (NOT FOUND - rev changed?)');
                } else {
                    var a = that.find('a').first();
                    a.append(' (');
                    a.append('' + data['total_fails'] + ' fails');
                    a.append(',  ' + data['total_flakes'] + ' flakes');
                    if(data['total_unfinished']) {
                        a.append(', ' + data['total_unfinished'] + ' unfinished');
                    }
                    if(data['missing_builders']) {
                        a.append(', ' + data['missing_builders'] + ' missing');
                    }
                    if(data['unfinished_builders']) {
                        a.append(', ' + data['unfinished_builders'] + ' builders not finished');
                    }
                    a.append(')');
                }
                that.addClass('bb-data-loaded');
            }
        });
    };
});
<commit_msg>Update the linkify regex<commit_after>$(function() {
    Settings = window.Settings;
    PushManager = window.PushManager || {};
    PushManager.Request = PushManager.Request || {}

    PushManager.Request.format_comments_dom = function(domobj) {
        var link_re = /((?:http:\/\/|https:\/\/)(?:\w+(?:\.|-))+(?!py|tmpl|js)[a-z]{2,}(?::[0-9]+)?(?:\/\S*)*)/ig

        var that = $(domobj);
        var data = that.text();

        // Escape
        data = data.replace(/</g, '<');
        data = data.replace(/>/g, '>');
        data = data.replace(/"/g, '"');

        // Newlines -> Rendered newlines
        data = data.replace(/\n/g, '\n
');

        // Bold comment headers
        data = data.replace(/Comment from \w+:/g, function(m) { return '' + m + ''; });

        // Linkify
        data = data.replace(link_re, function(match) {
            return '' + match + '';
        });

        that.html(data);
    };

    // Format initial comments
    $('.request-comments').each(function() { PushManager.Request.format_comments_dom(this); });
    $('.request-description').each(function() { PushManager.Request.format_comments_dom(this); });

    PushManager.Request.expand_push_item = function() {
        var that = $(this);
        var req = that.closest('.request-module');
        req.find('.request-info-extended').toggle();
        var button = req.find('.request-item-expander');
        if(button.attr('src') == "/static/img/button_hide.gif") {
            button.attr('src', "/static/img/button_expand.gif");
        } else {
            button.attr('src', "/static/img/button_hide.gif");
        }
    };

    PushManager.Request.collapse_push_item = function() {
        var that = $(this);
        var req = that.find('.request-module');
        req.find('.request-info-extended').hide();
        var button = req.find('.request-item-expander');
        button.attr('src', "/static/img/button_expand.gif");
    };

    // Bind expander to both title and expand icon
    $('.request-item-expander, .request-item-title').live('click', PushManager.Request.expand_push_item);
    $('.request-item-expander[expand=yes]').each(PushManager.Request.expand_push_item);

    PushManager.Request.delay_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        $.ajax({
            'type': 'POST',
            'url': '/delayrequest',
            'data': {'id': requestid},
            'success': function() { window.location.reload(); },
            'error': function() { alert('Something went wrong while trying to delay the request.'); }
        });
    };

    PushManager.Request.pushmaster_delay_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        $.ajax({
            'type': 'POST',
            'url': '/delayrequest',
            'data': {'id': requestid},
            'success': function() { that.parent("li").remove(); },
            'error': function() { alert('Something went wrong while trying to delay the request.'); }
        });
    };

    PushManager.Request.undelay_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        $.ajax({
            'type': 'POST',
            'url': '/undelayrequest',
            'data': {'id': requestid},
            'success': function() { window.location.reload(); },
            'error': function() { alert('Something went wrong while trying to un-delay the request.'); }
        });
    };

    PushManager.Request.discard_request = function() {
        var that = $(this).closest('.request-module');
        var requestid = that.attr('request');
        if(confirm("Are you sure you want to discard this request?")) {
            $.ajax({
                'type': 'POST',
                'url': '/discardrequest',
                'data': {'id': requestid},
                'success': function() { window.location.reload(); },
                'error': function() { alert('Something went wrong while trying to discard the request.'); }
            });
        }
    };

    // Bind various buttons
    $('.delay-request').live('click', PushManager.Request.delay_request);
    $('.pushmaster-delay-request').live('click', PushManager.Request.pushmaster_delay_request);
    $('.undelay-request').live('click', PushManager.Request.undelay_request);
    $('.discard-request').live('click', PushManager.Request.discard_request);

    PushManager.Request.load_bb_failures = function(domobj) {
        var dataurl = "https://" + Settings['buildbot']['servername'] + "/rev/%REVISION%";
        var that = $(domobj);
        if(that.hasClass('bb-data-loaded')) {
            return;
        }
        var req = that.closest('.request-module');

        var revision = req.attr('revision');
        $.ajax({
            'url': dataurl.replace('%REVISION%', revision),
            'data': {'format': 'json'},
            'dataType': 'json',
            'success': function(data) {
                if(!data || data.error) {
                    that.find('a').first().append(' (NOT FOUND - rev changed?)');
                } else {
                    var a = that.find('a').first();
                    a.append(' (');
                    a.append('' + data['total_fails'] + ' fails');
                    a.append(',  ' + data['total_flakes'] + ' flakes');
                    if(data['total_unfinished']) {
                        a.append(', ' + data['total_unfinished'] + ' unfinished');
                    }
                    if(data['missing_builders']) {
                        a.append(', ' + data['missing_builders'] + ' missing');
                    }
                    if(data['unfinished_builders']) {
                        a.append(', ' + data['unfinished_builders'] + ' builders not finished');
                    }
                    a.append(')');
                }
                that.addClass('bb-data-loaded');
            }
        });
    };
});
<|endoftext|>


<commit_before>var hgots = angular.module('HGOTSApp', [ 'ngRoute', 'ngAnimate', 'HGOTSServices', 'HGOTSAdmin', 'angular-loading-bar', 'ngActivityIndicator', 'pascalprecht.translate' ]);

hgots.config([ '$routeProvider', 'cfpLoadingBarProvider', function($routeProvider, cfpLoadingBarProvider) {
  // routes
  $routeProvider
    .when('/', {
      templateUrl: 'views/home.html',
      controller: 'HomeController'
    })
    .when('/admin', {
      templateUrl: 'views/admin.html',
      controller: 'AdminController'
    })
    .when('/admin/:new', {
      templateUrl: 'views/admin.html',
      controller: 'AdminController'
    })
    .when('/admin/user/:userId', {
      templateUrl: 'views/admin.html',
      controller: 'AdminController',
      reloadOnSearch: false
    })
    .when('/logs', {
      templateUrl: 'views/logs.html',
      controller: 'LogsController'
    })
    .when('/about', {
      templateUrl: 'views/about.html',
      controller: 'AboutController'
    })
    .otherwise({
      redirectTo: '/'
    });

  // loading bar
  cfpLoadingBarProvider.includeSpinner = false;
}]);

hgots.service('AppShared', [ '$http', function($http) {
  var obj = {
    currentUser: {},
    pkg: {
      name: '...',
      version: 'v0.0.0'
    }
  };
  // fill object with data from server
  obj.currentUser = $http({ method: 'GET', url: '/api/v2/user' }).then(function(currentUser) {
    obj.currentUser = currentUser.data.user;
  });
  $http({ method: 'GET', url: '/info' }).then(function(response) {
    obj.pkg = response.data;
  });

  return obj;
}]);

hgots.controller('NavbarController', [ '$scope', '$http', 'AppShared', '$window', function($scope, $http, AppShared, $window) {
  // Navbar itself
  $scope.currentUserIsPrivileged = false;
  $scope.$watch(function() { return AppShared.currentUser; }, function(user) {
    $scope.currentUserIsPrivileged = ( !!user && !!user.type && user.type !== "User" );
  });

  // Loading bar, related to navbar
  $(function() {
    // onload
    var className = 'scrolled';
    var body = $(document.body);
    var navbarHeight = $(".navbar").height();

    $(window).on('scroll', function() {
      var scrollY = $window.scrollY;

      if ( scrollY > 0 && !body.hasClass(className) ) {
        body.addClass(className);
      } else if ( scrollY === 0 && body.hasClass(className) ) {
        body.removeClass(className);
      }

      if ( !body.hasClass(className) || scrollY >= navbarHeight ) {
        $("#loading-bar .bar").css('top', '');
      } else {
        if ( scrollY < navbarHeight ) {
          // keep the indicator at the level until navbar is away
          $("#loading-bar .bar").css('top', ( navbarHeight - scrollY ) + "px");
        }
      }
    });
  });
}]);
<commit_msg>Explicitly disabling angular's html5mode.<commit_after>var hgots = angular.module('HGOTSApp', [ 'ngRoute', 'ngAnimate', 'HGOTSServices', 'HGOTSAdmin', 'angular-loading-bar', 'ngActivityIndicator', 'pascalprecht.translate' ]);

hgots.config([ '$locationProvider', '$routeProvider', 'cfpLoadingBarProvider', function($locationProvider, $routeProvider, cfpLoadingBarProvider) {

  $locationProvider.html5Mode(false).hashPrefix('');

  // routes
  $routeProvider
    .when('/', {
      templateUrl: 'views/home.html',
      controller: 'HomeController'
    })
    .when('/admin', {
      templateUrl: 'views/admin.html',
      controller: 'AdminController'
    })
    .when('/admin/:new', {
      templateUrl: 'views/admin.html',
      controller: 'AdminController'
    })
    .when('/admin/user/:userId', {
      templateUrl: 'views/admin.html',
      controller: 'AdminController',
      reloadOnSearch: false
    })
    .when('/logs', {
      templateUrl: 'views/logs.html',
      controller: 'LogsController'
    })
    .when('/about', {
      templateUrl: 'views/about.html',
      controller: 'AboutController'
    })
    .otherwise({
      redirectTo: '/'
    });

  // loading bar
  cfpLoadingBarProvider.includeSpinner = false;
}]);

hgots.service('AppShared', [ '$http', function($http) {
  var obj = {
    currentUser: {},
    pkg: {
      name: '...',
      version: 'v0.0.0'
    }
  };
  // fill object with data from server
  obj.currentUser = $http({ method: 'GET', url: '/api/v2/user' }).then(function(currentUser) {
    obj.currentUser = currentUser.data.user;
  });
  $http({ method: 'GET', url: '/info' }).then(function(response) {
    obj.pkg = response.data;
  });

  return obj;
}]);

hgots.controller('NavbarController', [ '$scope', '$http', 'AppShared', '$window', function($scope, $http, AppShared, $window) {
  // Navbar itself
  $scope.currentUserIsPrivileged = false;
  $scope.$watch(function() { return AppShared.currentUser; }, function(user) {
    $scope.currentUserIsPrivileged = ( !!user && !!user.type && user.type !== "User" );
  });

  // Loading bar, related to navbar
  $(function() {
    // onload
    var className = 'scrolled';
    var body = $(document.body);
    var navbarHeight = $(".navbar").height();

    $(window).on('scroll', function() {
      var scrollY = $window.scrollY;

      if ( scrollY > 0 && !body.hasClass(className) ) {
        body.addClass(className);
      } else if ( scrollY === 0 && body.hasClass(className) ) {
        body.removeClass(className);
      }

      if ( !body.hasClass(className) || scrollY >= navbarHeight ) {
        $("#loading-bar .bar").css('top', '');
      } else {
        if ( scrollY < navbarHeight ) {
          // keep the indicator at the level until navbar is away
          $("#loading-bar .bar").css('top', ( navbarHeight - scrollY ) + "px");
        }
      }
    });
  });
}]);
<|endoftext|>


<commit_before>/**
 * (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
 *
 * 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.
 */

(function() {
  'use strict';

  /**
   * @ngdoc overview
   * @ngname horizon.app.core.images
   *
   * @description
   * Provides all of the services and widgets required
   * to support and display images related content.
   */
  angular
    .module('horizon.app.core.images', [
      'ngRoute',
      'horizon.app.core.images.actions',
      'horizon.app.core.images.details'
    ])
    .constant('horizon.app.core.images.events', events())
    .constant('horizon.app.core.images.non_bootable_image_types', ['aki', 'ari'])
    .constant('horizon.app.core.images.validationRules', validationRules())
    .constant('horizon.app.core.images.imageFormats', imageFormats())
    .constant('horizon.app.core.images.resourceType', 'OS::Glance::Image')
    .constant('horizon.app.core.images.statuses', {
      'active': gettext('Active'),
      'saving': gettext('Saving'),
      'queued': gettext('Queued'),
      'pending_delete': gettext('Pending Delete'),
      'killed': gettext('Killed'),
      'deleted': gettext('Deleted')
    })
    .constant('horizon.app.core.images.transitional-statuses', [
      "saving",
      "queued",
      "pending_delete"
    ])
    .run(run)
    .config(config);

  run.$inject = [
    'horizon.framework.conf.resource-type-registry.service',
    'horizon.app.core.images.basePath',
    'horizon.app.core.images.service',
    'horizon.app.core.images.statuses',
    'horizon.app.core.images.resourceType',
    'horizon.framework.util.filters.$memoize',
    'horizon.app.core.openstack-service-api.keystone'
  ];

  function run(registry,
               basePath,
               imagesService,
               statuses,
               imageResourceType,
               $memoize,
               keystone) {
    registry.getResourceType(imageResourceType)
      .setNames(gettext('Image'), gettext('Images'))
      .setSummaryTemplateUrl(basePath + 'details/drawer.html')
      .setItemInTransitionFunction(imagesService.isInTransition)
      .setProperties(imageProperties(imagesService, statuses))
      .setListFunction(imagesService.getImagesPromise)
      .tableColumns
      .append({
        id: 'owner',
        priority: 1,
        filters: [$memoize(keystone.getProjectName)],
        policies: [{rules: [['identity', 'identity:get_project']]}]
      })
      .append({
        id: 'name',
        priority: 1,
        sortDefault: true,
        urlFunction: imagesService.getDetailsPath
      })
      .append({
        id: 'type',
        priority: 1
      })
      .append({
        id: 'status',
        priority: 1,
        itemInTransitionFunction: imagesService.isInTransition
      })
      .append({
        id: 'visibility',
        priority: 1
      })
      .append({
        id: 'protected',
        priority: 1
      })
      .append({
        id: 'disk_format',
        priority: 2
      })
      .append({
        id: 'size',
        priority: 2
      });

    registry.getResourceType(imageResourceType).filterFacets
      .append({
        label: gettext('Name'),
        name: 'name',
        isServer: true,
        singleton: true,
        persistent: true
      })
      .append({
        label: gettext('Status'),
        name: 'status',
        isServer: true,
        singleton: true,
        options: [
          {label: gettext('Active'), key: 'active'},
          {label: gettext('Saving'), key: 'saving'},
          {label: gettext('Queued'), key: 'queued'},
          {label: gettext('Pending Delete'), key: 'pending_delete'},
          {label: gettext('Killed'), key: 'killed'},
          {label: gettext('Deactivated'), key: 'deactivated'},
          {label: gettext('Deleted'), key: 'deleted'}
        ]
      })
      .append({
        label: gettext('Visibility'),
        name: 'visibility',
        isServer: false,
        singleton: true,
        options: [
          {label: gettext('Public'), key: 'public'},
          {label: gettext('Private'), key: 'private'},
          {label: gettext('Shared With Project'), key: 'shared'},
          {label: gettext('Unknown'), key: 'unknown'}
        ]
      })
      .append({
        label: gettext('Protected'),
        name: 'protected',
        isServer: true,
        singleton: true,
        options: [
          {label: gettext('Yes'), key: 'true'},
          {label: gettext('No'), key: 'false'}
        ]
      })
      .append({
        label: gettext('Format'),
        name: 'disk_format',
        isServer: true,
        singleton: true,
        options: [
          {label: gettext('AKI'), key: 'aki'},
          {label: gettext('AMI'), key: 'ami'},
          {label: gettext('ARI'), key: 'ari'},
          {label: gettext('Docker'), key: 'docker'},
          {label: gettext('ISO'), key: 'iso'},
          {label: gettext('OVA'), key: 'ova'},
          {label: gettext('PLOOP'), key: 'ploop'},
          {label: gettext('QCOW2'), key: 'qcow2'},
          {label: gettext('Raw'), key: 'raw'},
          {label: gettext('VDI'), key: 'vdi'},
          {label: gettext('VHD'), key: 'vhd'},
          {label: gettext('VMDK'), key: 'vmdk'}
        ]
      })
      .append({
        label: gettext('Min. Size (bytes)'),
        name: 'size_min',
        isServer: true,
        singleton: true
      })
      .append({
        label: gettext('Max. Size (bytes)'),
        name: 'size_max',
        isServer: true,
        singleton: true
      });
  }

  /**
   * @ngdoc constant
   * @name horizon.app.core.images.validationRules
   * @description constants for use in validation fields
   */
  function validationRules() {
    return {
      integer: /^[0-9]+$/,
      fieldMaxLength: 255
    };
  }

  /**
   * @ngdoc constant
   * @name horizon.app.core.images.imageFormats
   * @description constants for list of image types in dropdowns
   */
  function imageFormats() {
    return {
      iso: gettext('ISO - Optical Disk Image'),
      ova: gettext('OVA - Open Virtual Appliance'),
      ploop: gettext('PLOOP - Virtuozzo/Parallels Loopback Disk'),
      qcow2: gettext('QCOW2 - QEMU Emulator'),
      raw: gettext('Raw'),
      vdi: gettext('VDI - Virtual Disk Image'),
      vhd: gettext('VHD - Virtual Hard Disk'),
      vmdk: gettext('VMDK - Virtual Machine Disk'),
      aki: gettext('AKI - Amazon Kernel Image'),
      ami: gettext('AMI - Amazon Machine Image'),
      ari: gettext('ARI - Amazon Ramdisk Image'),
      docker: gettext('Docker')
    };
  }

  /**
   * @name imageProperties
   * @description resource properties for image module
   */
  function imageProperties(imagesService, statuses) {
    return {
      id: gettext('ID'),
      checksum: gettext('Checksum'),
      members: gettext('Members'),
      min_disk: gettext('Min. Disk'),
      min_ram: gettext('Min. RAM'),
      name: gettext('Name'),
      owner: gettext('Owner'),
      tags: gettext('Tags'),
      updated_at: gettext('Updated At'),
      virtual_size: gettext('Virtual Size'),
      visibility: gettext('Visibility'),
      description: gettext('Description'),
      architecture: gettext('Architecture'),
      kernel_id: gettext('Kernel ID'),
      ramdisk_id: gettext('Ramdisk ID'),
      created_at: gettext('Created At'),
      container_format: { label: gettext('Container Format'), filters: ['uppercase'] },
      disk_format: { label: gettext('Disk Format'), filters: ['noValue', 'uppercase'] },
      is_public: { label: gettext('Is Public'), filters: ['yesno'] },
      type: { label: gettext('Type'), filters: [imagesService.imageType] },
      'protected': { label: gettext('Protected'), filters: ['yesno'] },
      size: { label: gettext('Size'), filters: ['bytes'] },
      status: { label: gettext('Status'), values: statuses }
    };
  }

  /**
   * @ngdoc value
   * @name horizon.app.core.images.events
   * @description a list of events for images
   * @returns {Object} The event object
   */
  function events() {
    return {
      VOLUME_CHANGED: 'horizon.app.core.images.VOLUME_CHANGED',
      IMAGE_CHANGED: 'horizon.app.core.images.IMAGE_CHANGED',
      IMAGE_METADATA_CHANGED: 'horizon.app.core.images.IMAGE_METADATA_CHANGED',
      IMAGE_UPLOAD_PROGRESS: 'horizon.app.core.images.IMAGE_UPLOAD_PROGRESS'
    };
  }

  config.$inject = [
    '$provide',
    '$windowProvider',
    '$routeProvider'
  ];

  /**
   * @name config
   * @param {Object} $provide
   * @param {Object} $windowProvider
   * @param {Object} $routeProvider
   * @description Routes used by this module.
   * @returns {undefined} Returns nothing
   */
  function config($provide, $windowProvider, $routeProvider) {
    var path = $windowProvider.$get().STATIC_URL + 'app/core/images/';
    $provide.constant('horizon.app.core.images.basePath', path);

    $routeProvider.when('/project/images/:id', {
      redirectTo: goToAngularDetails
    });

    $routeProvider.when('/admin/images/:id/detail', {
      redirectTo: goToAngularDetails
    });

    $routeProvider.when('/project/images', {
      templateUrl: path + 'panel.html'
    });

    $routeProvider.when('/admin/images', {
      templateUrl: path + 'admin-panel.html'
    });

    function goToAngularDetails(params) {
      return 'project/ngdetails/OS::Glance::Image/' + params.id;
    }
  }

})();
<commit_msg>Angular images deactivate status fix<commit_after>/**
 * (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
 *
 * 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.
 */

(function() {
  'use strict';

  /**
   * @ngdoc overview
   * @ngname horizon.app.core.images
   *
   * @description
   * Provides all of the services and widgets required
   * to support and display images related content.
   */
  angular
    .module('horizon.app.core.images', [
      'ngRoute',
      'horizon.app.core.images.actions',
      'horizon.app.core.images.details'
    ])
    .constant('horizon.app.core.images.events', events())
    .constant('horizon.app.core.images.non_bootable_image_types', ['aki', 'ari'])
    .constant('horizon.app.core.images.validationRules', validationRules())
    .constant('horizon.app.core.images.imageFormats', imageFormats())
    .constant('horizon.app.core.images.resourceType', 'OS::Glance::Image')
    .constant('horizon.app.core.images.statuses', {
      'active': gettext('Active'),
      'saving': gettext('Saving'),
      'queued': gettext('Queued'),
      'pending_delete': gettext('Pending Delete'),
      'killed': gettext('Killed'),
      'deactivated': gettext('Deactivated'),
      'deleted': gettext('Deleted')
    })
    .constant('horizon.app.core.images.transitional-statuses', [
      "saving",
      "queued",
      "pending_delete"
    ])
    .run(run)
    .config(config);

  run.$inject = [
    'horizon.framework.conf.resource-type-registry.service',
    'horizon.app.core.images.basePath',
    'horizon.app.core.images.service',
    'horizon.app.core.images.statuses',
    'horizon.app.core.images.resourceType',
    'horizon.framework.util.filters.$memoize',
    'horizon.app.core.openstack-service-api.keystone'
  ];

  function run(registry,
               basePath,
               imagesService,
               statuses,
               imageResourceType,
               $memoize,
               keystone) {
    registry.getResourceType(imageResourceType)
      .setNames(gettext('Image'), gettext('Images'))
      .setSummaryTemplateUrl(basePath + 'details/drawer.html')
      .setItemInTransitionFunction(imagesService.isInTransition)
      .setProperties(imageProperties(imagesService, statuses))
      .setListFunction(imagesService.getImagesPromise)
      .tableColumns
      .append({
        id: 'owner',
        priority: 1,
        filters: [$memoize(keystone.getProjectName)],
        policies: [{rules: [['identity', 'identity:get_project']]}]
      })
      .append({
        id: 'name',
        priority: 1,
        sortDefault: true,
        urlFunction: imagesService.getDetailsPath
      })
      .append({
        id: 'type',
        priority: 1
      })
      .append({
        id: 'status',
        priority: 1,
        itemInTransitionFunction: imagesService.isInTransition
      })
      .append({
        id: 'visibility',
        priority: 1
      })
      .append({
        id: 'protected',
        priority: 1
      })
      .append({
        id: 'disk_format',
        priority: 2
      })
      .append({
        id: 'size',
        priority: 2
      });

    registry.getResourceType(imageResourceType).filterFacets
      .append({
        label: gettext('Name'),
        name: 'name',
        isServer: true,
        singleton: true,
        persistent: true
      })
      .append({
        label: gettext('Status'),
        name: 'status',
        isServer: true,
        singleton: true,
        options: [
          {label: gettext('Active'), key: 'active'},
          {label: gettext('Saving'), key: 'saving'},
          {label: gettext('Queued'), key: 'queued'},
          {label: gettext('Pending Delete'), key: 'pending_delete'},
          {label: gettext('Killed'), key: 'killed'},
          {label: gettext('Deactivated'), key: 'deactivated'},
          {label: gettext('Deleted'), key: 'deleted'}
        ]
      })
      .append({
        label: gettext('Visibility'),
        name: 'visibility',
        isServer: false,
        singleton: true,
        options: [
          {label: gettext('Public'), key: 'public'},
          {label: gettext('Private'), key: 'private'},
          {label: gettext('Shared With Project'), key: 'shared'},
          {label: gettext('Unknown'), key: 'unknown'}
        ]
      })
      .append({
        label: gettext('Protected'),
        name: 'protected',
        isServer: true,
        singleton: true,
        options: [
          {label: gettext('Yes'), key: 'true'},
          {label: gettext('No'), key: 'false'}
        ]
      })
      .append({
        label: gettext('Format'),
        name: 'disk_format',
        isServer: true,
        singleton: true,
        options: [
          {label: gettext('AKI'), key: 'aki'},
          {label: gettext('AMI'), key: 'ami'},
          {label: gettext('ARI'), key: 'ari'},
          {label: gettext('Docker'), key: 'docker'},
          {label: gettext('ISO'), key: 'iso'},
          {label: gettext('OVA'), key: 'ova'},
          {label: gettext('PLOOP'), key: 'ploop'},
          {label: gettext('QCOW2'), key: 'qcow2'},
          {label: gettext('Raw'), key: 'raw'},
          {label: gettext('VDI'), key: 'vdi'},
          {label: gettext('VHD'), key: 'vhd'},
          {label: gettext('VMDK'), key: 'vmdk'}
        ]
      })
      .append({
        label: gettext('Min. Size (bytes)'),
        name: 'size_min',
        isServer: true,
        singleton: true
      })
      .append({
        label: gettext('Max. Size (bytes)'),
        name: 'size_max',
        isServer: true,
        singleton: true
      });
  }

  /**
   * @ngdoc constant
   * @name horizon.app.core.images.validationRules
   * @description constants for use in validation fields
   */
  function validationRules() {
    return {
      integer: /^[0-9]+$/,
      fieldMaxLength: 255
    };
  }

  /**
   * @ngdoc constant
   * @name horizon.app.core.images.imageFormats
   * @description constants for list of image types in dropdowns
   */
  function imageFormats() {
    return {
      iso: gettext('ISO - Optical Disk Image'),
      ova: gettext('OVA - Open Virtual Appliance'),
      ploop: gettext('PLOOP - Virtuozzo/Parallels Loopback Disk'),
      qcow2: gettext('QCOW2 - QEMU Emulator'),
      raw: gettext('Raw'),
      vdi: gettext('VDI - Virtual Disk Image'),
      vhd: gettext('VHD - Virtual Hard Disk'),
      vmdk: gettext('VMDK - Virtual Machine Disk'),
      aki: gettext('AKI - Amazon Kernel Image'),
      ami: gettext('AMI - Amazon Machine Image'),
      ari: gettext('ARI - Amazon Ramdisk Image'),
      docker: gettext('Docker')
    };
  }

  /**
   * @name imageProperties
   * @description resource properties for image module
   */
  function imageProperties(imagesService, statuses) {
    return {
      id: gettext('ID'),
      checksum: gettext('Checksum'),
      members: gettext('Members'),
      min_disk: gettext('Min. Disk'),
      min_ram: gettext('Min. RAM'),
      name: gettext('Name'),
      owner: gettext('Owner'),
      tags: gettext('Tags'),
      updated_at: gettext('Updated At'),
      virtual_size: gettext('Virtual Size'),
      visibility: gettext('Visibility'),
      description: gettext('Description'),
      architecture: gettext('Architecture'),
      kernel_id: gettext('Kernel ID'),
      ramdisk_id: gettext('Ramdisk ID'),
      created_at: gettext('Created At'),
      container_format: { label: gettext('Container Format'), filters: ['uppercase'] },
      disk_format: { label: gettext('Disk Format'), filters: ['noValue', 'uppercase'] },
      is_public: { label: gettext('Is Public'), filters: ['yesno'] },
      type: { label: gettext('Type'), filters: [imagesService.imageType] },
      'protected': { label: gettext('Protected'), filters: ['yesno'] },
      size: { label: gettext('Size'), filters: ['bytes'] },
      status: { label: gettext('Status'), values: statuses }
    };
  }

  /**
   * @ngdoc value
   * @name horizon.app.core.images.events
   * @description a list of events for images
   * @returns {Object} The event object
   */
  function events() {
    return {
      VOLUME_CHANGED: 'horizon.app.core.images.VOLUME_CHANGED',
      IMAGE_CHANGED: 'horizon.app.core.images.IMAGE_CHANGED',
      IMAGE_METADATA_CHANGED: 'horizon.app.core.images.IMAGE_METADATA_CHANGED',
      IMAGE_UPLOAD_PROGRESS: 'horizon.app.core.images.IMAGE_UPLOAD_PROGRESS'
    };
  }

  config.$inject = [
    '$provide',
    '$windowProvider',
    '$routeProvider'
  ];

  /**
   * @name config
   * @param {Object} $provide
   * @param {Object} $windowProvider
   * @param {Object} $routeProvider
   * @description Routes used by this module.
   * @returns {undefined} Returns nothing
   */
  function config($provide, $windowProvider, $routeProvider) {
    var path = $windowProvider.$get().STATIC_URL + 'app/core/images/';
    $provide.constant('horizon.app.core.images.basePath', path);

    $routeProvider.when('/project/images/:id', {
      redirectTo: goToAngularDetails
    });

    $routeProvider.when('/admin/images/:id/detail', {
      redirectTo: goToAngularDetails
    });

    $routeProvider.when('/project/images', {
      templateUrl: path + 'panel.html'
    });

    $routeProvider.when('/admin/images', {
      templateUrl: path + 'admin-panel.html'
    });

    function goToAngularDetails(params) {
      return 'project/ngdetails/OS::Glance::Image/' + params.id;
    }
  }

})();
<|endoftext|>