<commit_before>//global directives go here

angular.module('omniwallet').directive('d3PieChart', function() {
    return {
      template: '<svg></svg>',
      controller: function($scope, $element, $attrs) {

        $scope.chart = {
          width: 300,
          height: 300
        }
        $scope.radius = Math.min($scope.chart.width, $scope.chart.height) / 2

        $element.find('svg').attr('height', $scope.chart.height).attr('width', $scope.chart.width);

        var color = d3.scale.category20()

        var arc = d3.svg.arc()
        .outerRadius($scope.radius - 10)
        .innerRadius(0);

        var pie = d3.layout.pie()
        .sort(null)
        .value(function(d) {
          return d.value;
        });

        var svg = d3.select("svg")

        $scope.totalsPromise.then(function(successData) {

          var data = [],
            keys = Object.keys($scope.totals);
          keys.forEach(function(e, i) {
            data.push({
              value: $scope.totals[e],
              name: keys[i],
              color: Math.floor(Math.random() * 10)
            });
          });

          var g = svg.selectAll(".arc")
          .data(pie(data))
          .enter().append("g")
          .attr("class", "arc");

          g.append("path")
            .attr("d", arc)
            .style("fill", function(d) {
              return color(d.data.color);
            })
            .attr('transform', 'translate(150,150)');

          g.append("text")
            .attr("transform", function(d) {
              var c = arc.centroid(d);
              return "translate(" + (150 + c[0]) + "," + (150 + c[1]) + ")";
            })
            .attr("dy", ".35em")
            .style("text-anchor", "middle")
            .text(function(d) {
            return d.data.name;
          });
        });
      }
    }
  }).directive('omTooltip', function() {
    return {
      template: '(?)',
      link: function(scope, iElement, iAttrs, controller) {
        if (iAttrs.text)
          iElement.tooltip({
            title: iAttrs.text,
            placement: 'down',
            container: 'body'
          });
      }
    }
  }).directive('match', [function() {
    return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ctrl) {

        scope.$watch('[' + attrs.ngModel + ', ' + attrs.match + ']', function(value) {
          ctrl.$setValidity('match', value[0] === value[1]);
        }, true);

      }
    }
  }
}]).directive('autoFocus', function($timeout) {
  return {
    restrict: 'AC',
    scope: {
      'autoFocus': '=autoFocus'
    },
    link: function(scope, element) {
      scope.$watch('autoFocus', function() {
        if(scope.autoFocus) {
          $timeout(function(){
            $(element[0]).focus();
          }, 100);
        }
      });
    }
  };
});<commit_msg>Removed extra bracket<commit_after>//global directives go here

angular.module('omniwallet').directive('d3PieChart', function() {
    return {
      template: '<svg></svg>',
      controller: function($scope, $element, $attrs) {

        $scope.chart = {
          width: 300,
          height: 300
        }
        $scope.radius = Math.min($scope.chart.width, $scope.chart.height) / 2

        $element.find('svg').attr('height', $scope.chart.height).attr('width', $scope.chart.width);

        var color = d3.scale.category20()

        var arc = d3.svg.arc()
        .outerRadius($scope.radius - 10)
        .innerRadius(0);

        var pie = d3.layout.pie()
        .sort(null)
        .value(function(d) {
          return d.value;
        });

        var svg = d3.select("svg")

        $scope.totalsPromise.then(function(successData) {

          var data = [],
            keys = Object.keys($scope.totals);
          keys.forEach(function(e, i) {
            data.push({
              value: $scope.totals[e],
              name: keys[i],
              color: Math.floor(Math.random() * 10)
            });
          });

          var g = svg.selectAll(".arc")
          .data(pie(data))
          .enter().append("g")
          .attr("class", "arc");

          g.append("path")
            .attr("d", arc)
            .style("fill", function(d) {
              return color(d.data.color);
            })
            .attr('transform', 'translate(150,150)');

          g.append("text")
            .attr("transform", function(d) {
              var c = arc.centroid(d);
              return "translate(" + (150 + c[0]) + "," + (150 + c[1]) + ")";
            })
            .attr("dy", ".35em")
            .style("text-anchor", "middle")
            .text(function(d) {
            return d.data.name;
          });
        });
      }
    }
  }).directive('omTooltip', function() {
    return {
      template: '(?)',
      link: function(scope, iElement, iAttrs, controller) {
        if (iAttrs.text)
          iElement.tooltip({
            title: iAttrs.text,
            placement: 'down',
            container: 'body'
          });
      }
    }
  }).directive('match', [function() {
    return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ctrl) {

        scope.$watch('[' + attrs.ngModel + ', ' + attrs.match + ']', function(value) {
          ctrl.$setValidity('match', value[0] === value[1]);
        }, true);

      }
    }
 }]).directive('autoFocus', function($timeout) {
  return {
    restrict: 'AC',
    scope: {
      'autoFocus': '=autoFocus'
    },
    link: function(scope, element) {
      scope.$watch('autoFocus', function() {
        if(scope.autoFocus) {
          $timeout(function(){
            $(element[0]).focus();
          }, 100);
        }
      });
    }
  };
});
<|endoftext|>


<commit_before>/*
Copyright (c) 2015, salesforce.com, inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import deprecatedProperty from '../../utilities/warning/deprecated-property';
import sunsetProperty from '../../utilities/warning/sunset-property';

let checkProps = function () {};

if (process.env.NODE_ENV !== 'production') {
	checkProps = function (COMPONENT, props) {
		/* eslint-disable max-len */
		// Deprecated and changed to another property
		deprecatedProperty(COMPONENT, props.onSelect, 'collection', 'items');
		deprecatedProperty(COMPONENT, props.onSelect, 'onSelect', 'onChange');
		deprecatedProperty(COMPONENT, props.onSelect, 'onDeselect', 'onChange');
		sunsetProperty(COMPONENT, props.sortable, 'sortable', 'The table is sortable if one or more of its columns are sortable.');

		// Deprecated and moved to a child
		sunsetProperty(COMPONENT, props.columns, 'columns', 'Please provide one or more children of the type <Column /> instead.');
		/* eslint-enable max-len */
	};
}

export default checkProps;
<commit_msg>Finish linting data-table<commit_after>/*
Copyright (c) 2015, salesforce.com, inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* eslint-disable import/no-mutable-exports */

import deprecatedProperty from '../../utilities/warning/deprecated-property';
import sunsetProperty from '../../utilities/warning/sunset-property';

let checkProps = function () {};

if (process.env.NODE_ENV !== 'production') {
	checkProps = function (COMPONENT, props) {
		/* eslint-disable max-len */
		// Deprecated and changed to another property
		deprecatedProperty(COMPONENT, props.onSelect, 'collection', 'items');
		deprecatedProperty(COMPONENT, props.onSelect, 'onSelect', 'onChange');
		deprecatedProperty(COMPONENT, props.onSelect, 'onDeselect', 'onChange');
		sunsetProperty(COMPONENT, props.sortable, 'sortable', 'The table is sortable if one or more of its columns are sortable.');

		// Deprecated and moved to a child
		sunsetProperty(COMPONENT, props.columns, 'columns', 'Please provide one or more children of the type <Column /> instead.');
		/* eslint-enable max-len */
	};
}

export default checkProps;
<|endoftext|>


<commit_before>/*global weknowhow:true*/
(function (global, factory) {
    if (typeof exports === 'object') {
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        define(factory);
    } else {
        weknowhow.magicpen = factory();
    }
}(this, function () {
    var global = this;
    function getKeys(obj) {
        var result = [];

        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                result.push(i);
            }
        }

        return result;
    }

    function forEach(arr, callback, that) {
        for (var i = 0, n = arr.length; i < n; i += 1)
            if (i in arr)
                callback.call(that, arr[i], i, arr);
    }

    function map(arr, callback, that) {
        var result = [];
        for (var i = 0, n = arr.length; i < n; i += 1)
            if (i in arr)
                result.push(callback.call(that, arr[i], i, arr));
        return result;
    }

    function filter(arr, callback, that) {
        var result = [];
        for (var i = 0, n = arr.length; i < n; i += 1)
            if (i in arr && callback.call(that, arr[i], i, arr))
                result.push(arr[i]);
        return result;
    }

    function extend(target) {
        var sources = Array.prototype.slice.call(arguments, 1);
        forEach(sources, function (source) {
            forEach(getKeys(source), function (key) {
                target[key] = source[key];
            });
        });
        return target;
    }

    var requireStyles = ['lines', 'text', 'space', 'block'];

    function Serializer(styles) {
        var that = this;
        forEach(requireStyles, function (style) {
            if (!styles[style]) {
                throw new Error("Required style '" + style + "' is missing");
            }
        });
        this.styles = styles;
        this.styles.raw = function (text) {
            return text;
        };

        // Alias space as sp
        this.styles.sp = this.styles.space;

        var textStyles = [
            'bold',
            'dim',
            'italic',
            'underline',
            'inverse',
            'hidden',
            'strikethrough',
            'black',
            'red',
            'green',
            'yellow',
            'blue',
            'magenta',
            'cyan',
            'white',
            'gray',
            'bgBlack',
            'bgRed',
            'bgGreen',
            'bgYellow',
            'bgBlue',
            'bgMagenta',
            'bgCyan',
            'bgWhite'
        ];

        forEach(textStyles, function (textStyle) {
            if (!that.styles[textStyle]) {
                that.styles[textStyle] = function (text) {
                    return this.text.call(that, text, textStyle);
                };
            }
        });
    }

    Serializer.prototype.serialize = function (lines) {
        return this.serializeLines(lines);
    };

    Serializer.prototype.serializeLines = function (lines) {
        return this.styles.lines(map(lines, function (line) {
            return {
                indentation: line.indentation,
                content: this.serializeLineContent(line)
            };
        }, this));
    };

    Serializer.prototype.serializeLineContent = function (content) {
        return map(content, this.serializeEntry, this);
    };

    function isOutputEntry(obj) {
        return typeof obj === 'object' && 'style' in obj && 'args' in obj;
    }

    Serializer.prototype.serializeEntry = function (entry) {
        var that = this;
        if (entry.style in this.styles) {
            return this.styles[entry.style].apply(this.styles, entry.args);
        } else {
            return entry.args.join('');
        }
    };

    function createSerializer(styles) {
        function CustomSerializer() {
        }
        CustomSerializer.prototype = new Serializer(styles);
        return CustomSerializer;
    }

    function duplicateText(text, times) {
        var result = '';
        for (var i = 0; i < times; i += 1) {
            result += text;
        }
        return result;
    }

    // copied from https://github.com/sindresorhus/ansi-regex
    // License https://raw.githubusercontent.com/sindresorhus/ansi-regex/master/license
    var ansiRegex = /\u001b\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]/g;

    var PlainSerializer = createSerializer({
        text: function (text) {
            return text;
        },
        lines: function (lines) {
            function serializeLine(line) {
                var serializedLines = [''];

                forEach(line.content, function (inlineBlock, blockIndex) {
                    var blockLines = map(String(inlineBlock).split('\n'), function (serializedBlockLine) {
                        return {
                            content: serializedBlockLine,
                            length: serializedBlockLine.replace(ansiRegex, '').length
                        };
                    });
                    var longestBlockLine = 0;
                    forEach(blockLines, function (blockLine) {
                        longestBlockLine = Math.max(longestBlockLine, blockLine.length);
                    });

                    var blockStartIndex = serializedLines[0].replace(ansiRegex, '').length;
                    serializedLines[0] += blockLines[0].content;
                    if (blockLines.length > 1 && blockIndex < line.content.length - 1) {
                        serializedLines[0] += duplicateText(' ', longestBlockLine - blockLines[0].length);
                    }

                    forEach(blockLines.slice(1), function (blockLine, index) {
                        var lineIndex = index + 1;
                        serializedLines[lineIndex] = serializedLines[lineIndex] || '';
                        var padding = duplicateText(' ', blockStartIndex - serializedLines[lineIndex].replace(ansiRegex, '').length);
                        serializedLines[lineIndex] += padding + blockLine.content;
                    });
                });

                return serializedLines.join('\n');
            }

            return map(lines, serializeLine).join('\n');
        },
        space: function (count) {
            return duplicateText(' ', count || 1);
        },
        block: function (content) {
            return content;
        }
    });

    var ansiStyles = (function () {
        // Copied from https://github.com/sindresorhus/ansi-styles/
        // License: raw.githubusercontent.com/sindresorhus/ansi-styles/master/license
        var styles = {};

        var codes = {
            bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
            dim: [2, 22],
            italic: [3, 23],
            underline: [4, 24],
            inverse: [7, 27],
            hidden: [8, 28],
            strikethrough: [9, 29],

            black: [30, 39],
            red: [31, 39],
            green: [32, 39],
            yellow: [33, 39],
            blue: [34, 39],
            magenta: [35, 39],
            cyan: [36, 39],
            white: [37, 39],
            gray: [90, 39],

            bgBlack: [40, 49],
            bgRed: [41, 49],
            bgGreen: [42, 49],
            bgYellow: [43, 49],
            bgBlue: [44, 49],
            bgMagenta: [45, 49],
            bgCyan: [46, 49],
            bgWhite: [47, 49]
        };

        Object.keys(codes).forEach(function (key) {
            var val = codes[key];
            var style = styles[key] = {};
            style.open = '\x1B[' + val[0] + 'm';
            style.close = '\x1B[' + val[1] + 'm';
        });

        return styles;
    }());

    var AnsiSerializer = createSerializer(extend({}, PlainSerializer.prototype.styles, {
        text: function (text) {
            if (arguments.length > 1) {
                var stylesString = Array.prototype.slice.call(arguments, 1).join(',');
                var styles = stylesString.split(/\s*,\s*/);
                forEach(styles, function (style) {
                    if (ansiStyles[style]) {
                        text = ansiStyles[style].open + text + ansiStyles[style].close;
                    }
                });
            }

            return text;
        }
    }));

    var htmlStyles = {
        bold: 'font-weight: bold',
        dim: 'opacity: 0.7',
        italic: 'font-style: italic',
        underline: 'text-decoration: underline',
        inverse: '-webkit-filter: invert(%100); filter: invert(100%)',
        hidden: 'visibility: hidden',
        strikethrough: 'text-decoration: line-through',

        black: 'color: black',
        red: 'color: red',
        green: 'color: green',
        yellow: 'color: yellow',
        blue: 'color: blue',
        magenta: 'color: magenta',
        cyan: 'color: cyan',
        white: 'color: white',
        gray: 'color: gray',

        bgBlack: 'background-color: black',
        bgRed: 'background-color: red',
        bgGreen: 'background-color: green',
        bgYellow: 'background-color: yellow',
        bgBlue: 'background-color: blue',
        bgMagenta: 'background-color: magenta',
        bgCyan: 'background-color: cyan',
        bgWhite: 'background-color: white'
    };

    var HtmlSerializer = createSerializer({
        text: function (text) {
            text = String(text)
                .replace(/&/g, '&')
                .replace(/ /g, ' ')
                .replace(/</g, '<')
                .replace(/>/g, '>')
                .replace(/"/g, '"');

            if (arguments.length > 1) {
                var stylesString = Array.prototype.slice.call(arguments, 1).join(',');
                var styles = filter(stylesString.split(/\s*,\s*/), function (styleName) {
                    return htmlStyles[styleName];
                });

                text = '' + text + '';
            }
            return text;
        },
        lines: function (lines) {
            return '\n' +
                map(lines, function (line) {
                    return '
' + line.content.join('') + '
';
                }).join('\n') + '\n' +
                '';
        },
        block: function (content) {
            return '
' + content + '
';
        },
        space: function (count) {
            return duplicateText(' ', count || 1);
        }
    });

    var defaults = {
        mode: 'plain'
    };

    function MagicPen(mode) {
        if (this === global) {
            return new MagicPen(mode);
        }

        var that = this;

        extend(this, defaults, {
            indentationLevel: 0,
            output: [],
            styles: {}
        });

        this.mode = mode || this.mode;
        this.serializer = new MagicPen.serializers[this.mode]();

        forEach(getKeys(this.serializer.styles), function (style) {
            if (!that[style]) {
                that[style] = function () {
                    var args = Array.prototype.slice.call(arguments);
                    return this.write.call(this, { style: style, args: args });
                };
            }
        });
    }

    MagicPen.prototype.newline = MagicPen.prototype.nl = function () {
        this.output.push([]);
        return this;
    };

    MagicPen.serializers = {
        plain: PlainSerializer,
        ansi: AnsiSerializer,
        html: HtmlSerializer
    };

    MagicPen.prototype.write = function () {
        var args = Array.prototype.slice.call(arguments);
        if (args.length === 0) {
            return this;
        } else if (args.length === 1 && isOutputEntry(args[0])) {
            var options = args[0];
            if (this.styles[options.style]) {
                this.styles[options.style].apply(this, options.args);
                return this;
            }
            this.output[0] = this.output[0] || [];
            this.output[this.output.length - 1].push(options);
            return this;
        } else if (args.length === 1) {
            return this.write({ style: 'text', args: args });
        } else {
            return this.write({ style: args[0], args: args.slice(1) });
        }
    };

    MagicPen.prototype.indentLines = function () {
        this.indentationLevel += 1;
        this.newline();
        return this;
    };

    MagicPen.prototype.indent = MagicPen.prototype.i = function () {
        for (var i = 0; i < this.indentationLevel; i += 1) {
            this.space(2);
        }
        return this;
    };

    MagicPen.prototype.outdentLines = function () {
        this.indentationLevel = Math.max(0, this.indentationLevel - 1);
        this.newline();
        return this;
    };

    MagicPen.prototype.addStyle = function (style, handler) {
        var that = this;
        this.styles[style] = handler;
        if (!this[style]) {
            this[style] = function () {
                handler.apply(that, arguments);
                return that;
            };
        }
        return this;
    };

    MagicPen.prototype.toString = function () {
        return this.serializer.serialize(this.output);
    };

    MagicPen.prototype.ensurePenWithSameMode = function (pen) {
        if (!(pen instanceof MagicPen) || pen.mode !== this.mode) {
            throw new Error('Expected an instance of a MagicPen in ' + this.mode + ' mode');
        }
    };

    MagicPen.prototype.block = function (pen) {
        this.ensurePenWithSameMode(pen);
        return this.write('block', pen.toString());
    };

    MagicPen.prototype.append = function (pen) {
        this.ensurePenWithSameMode(pen);
        if (pen.output.length === 0) {
            return this;
        }

        this.output[0] = this.output[0] || [];
        this.output[0].push.apply(this.output[0], pen.output[0]);

        this.output.push.apply(this.output, pen.output.slice(1));

        return this;
    };

    MagicPen.prototype.prependLinesWith = function (pen) {
        this.ensurePenWithSameMode(pen);
        if (pen.output.length === 0 || this.output.length === 0) {
            return this;
        }
        var outputToPrepend = Array.prototype.concat.apply([], pen.output);

        this.output = map(this.output, function (line) {
            return outputToPrepend.concat(line);
        });

        return this;
    };

    MagicPen.prototype.clone = function () {
        function MagicPenClone() {}
        MagicPenClone.prototype = this;
        var clonedPen = new MagicPenClone();
        clonedPen.indentationLevel = 0;
        clonedPen.output = [];
        return clonedPen;
    };

    return MagicPen;
}));
<commit_msg>Renamed strikethrough to strikeThrough<commit_after>/*global weknowhow:true*/
(function (global, factory) {
    if (typeof exports === 'object') {
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        define(factory);
    } else {
        weknowhow.magicpen = factory();
    }
}(this, function () {
    var global = this;
    function getKeys(obj) {
        var result = [];

        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                result.push(i);
            }
        }

        return result;
    }

    function forEach(arr, callback, that) {
        for (var i = 0, n = arr.length; i < n; i += 1)
            if (i in arr)
                callback.call(that, arr[i], i, arr);
    }

    function map(arr, callback, that) {
        var result = [];
        for (var i = 0, n = arr.length; i < n; i += 1)
            if (i in arr)
                result.push(callback.call(that, arr[i], i, arr));
        return result;
    }

    function filter(arr, callback, that) {
        var result = [];
        for (var i = 0, n = arr.length; i < n; i += 1)
            if (i in arr && callback.call(that, arr[i], i, arr))
                result.push(arr[i]);
        return result;
    }

    function extend(target) {
        var sources = Array.prototype.slice.call(arguments, 1);
        forEach(sources, function (source) {
            forEach(getKeys(source), function (key) {
                target[key] = source[key];
            });
        });
        return target;
    }

    var requireStyles = ['lines', 'text', 'space', 'block'];

    function Serializer(styles) {
        var that = this;
        forEach(requireStyles, function (style) {
            if (!styles[style]) {
                throw new Error("Required style '" + style + "' is missing");
            }
        });
        this.styles = styles;
        this.styles.raw = function (text) {
            return text;
        };

        // Alias space as sp
        this.styles.sp = this.styles.space;

        var textStyles = [
            'bold',
            'dim',
            'italic',
            'underline',
            'inverse',
            'hidden',
            'strikeThrough',
            'black',
            'red',
            'green',
            'yellow',
            'blue',
            'magenta',
            'cyan',
            'white',
            'gray',
            'bgBlack',
            'bgRed',
            'bgGreen',
            'bgYellow',
            'bgBlue',
            'bgMagenta',
            'bgCyan',
            'bgWhite'
        ];

        forEach(textStyles, function (textStyle) {
            if (!that.styles[textStyle]) {
                that.styles[textStyle] = function (text) {
                    return this.text.call(that, text, textStyle);
                };
            }
        });
    }

    Serializer.prototype.serialize = function (lines) {
        return this.serializeLines(lines);
    };

    Serializer.prototype.serializeLines = function (lines) {
        return this.styles.lines(map(lines, function (line) {
            return {
                indentation: line.indentation,
                content: this.serializeLineContent(line)
            };
        }, this));
    };

    Serializer.prototype.serializeLineContent = function (content) {
        return map(content, this.serializeEntry, this);
    };

    function isOutputEntry(obj) {
        return typeof obj === 'object' && 'style' in obj && 'args' in obj;
    }

    Serializer.prototype.serializeEntry = function (entry) {
        var that = this;
        if (entry.style in this.styles) {
            return this.styles[entry.style].apply(this.styles, entry.args);
        } else {
            return entry.args.join('');
        }
    };

    function createSerializer(styles) {
        function CustomSerializer() {
        }
        CustomSerializer.prototype = new Serializer(styles);
        return CustomSerializer;
    }

    function duplicateText(text, times) {
        var result = '';
        for (var i = 0; i < times; i += 1) {
            result += text;
        }
        return result;
    }

    // copied from https://github.com/sindresorhus/ansi-regex
    // License https://raw.githubusercontent.com/sindresorhus/ansi-regex/master/license
    var ansiRegex = /\u001b\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]/g;

    var PlainSerializer = createSerializer({
        text: function (text) {
            return text;
        },
        lines: function (lines) {
            function serializeLine(line) {
                var serializedLines = [''];

                forEach(line.content, function (inlineBlock, blockIndex) {
                    var blockLines = map(String(inlineBlock).split('\n'), function (serializedBlockLine) {
                        return {
                            content: serializedBlockLine,
                            length: serializedBlockLine.replace(ansiRegex, '').length
                        };
                    });
                    var longestBlockLine = 0;
                    forEach(blockLines, function (blockLine) {
                        longestBlockLine = Math.max(longestBlockLine, blockLine.length);
                    });

                    var blockStartIndex = serializedLines[0].replace(ansiRegex, '').length;
                    serializedLines[0] += blockLines[0].content;
                    if (blockLines.length > 1 && blockIndex < line.content.length - 1) {
                        serializedLines[0] += duplicateText(' ', longestBlockLine - blockLines[0].length);
                    }

                    forEach(blockLines.slice(1), function (blockLine, index) {
                        var lineIndex = index + 1;
                        serializedLines[lineIndex] = serializedLines[lineIndex] || '';
                        var padding = duplicateText(' ', blockStartIndex - serializedLines[lineIndex].replace(ansiRegex, '').length);
                        serializedLines[lineIndex] += padding + blockLine.content;
                    });
                });

                return serializedLines.join('\n');
            }

            return map(lines, serializeLine).join('\n');
        },
        space: function (count) {
            return duplicateText(' ', count || 1);
        },
        block: function (content) {
            return content;
        }
    });

    var ansiStyles = (function () {
        // Copied from https://github.com/sindresorhus/ansi-styles/
        // License: raw.githubusercontent.com/sindresorhus/ansi-styles/master/license
        var styles = {};

        var codes = {
            bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
            dim: [2, 22],
            italic: [3, 23],
            underline: [4, 24],
            inverse: [7, 27],
            hidden: [8, 28],
            strikeThrough: [9, 29],

            black: [30, 39],
            red: [31, 39],
            green: [32, 39],
            yellow: [33, 39],
            blue: [34, 39],
            magenta: [35, 39],
            cyan: [36, 39],
            white: [37, 39],
            gray: [90, 39],

            bgBlack: [40, 49],
            bgRed: [41, 49],
            bgGreen: [42, 49],
            bgYellow: [43, 49],
            bgBlue: [44, 49],
            bgMagenta: [45, 49],
            bgCyan: [46, 49],
            bgWhite: [47, 49]
        };

        Object.keys(codes).forEach(function (key) {
            var val = codes[key];
            var style = styles[key] = {};
            style.open = '\x1B[' + val[0] + 'm';
            style.close = '\x1B[' + val[1] + 'm';
        });

        return styles;
    }());

    var AnsiSerializer = createSerializer(extend({}, PlainSerializer.prototype.styles, {
        text: function (text) {
            if (arguments.length > 1) {
                var stylesString = Array.prototype.slice.call(arguments, 1).join(',');
                var styles = stylesString.split(/\s*,\s*/);
                forEach(styles, function (style) {
                    if (ansiStyles[style]) {
                        text = ansiStyles[style].open + text + ansiStyles[style].close;
                    }
                });
            }

            return text;
        }
    }));

    var htmlStyles = {
        bold: 'font-weight: bold',
        dim: 'opacity: 0.7',
        italic: 'font-style: italic',
        underline: 'text-decoration: underline',
        inverse: '-webkit-filter: invert(%100); filter: invert(100%)',
        hidden: 'visibility: hidden',
        strikeThrough: 'text-decoration: line-through',

        black: 'color: black',
        red: 'color: red',
        green: 'color: green',
        yellow: 'color: yellow',
        blue: 'color: blue',
        magenta: 'color: magenta',
        cyan: 'color: cyan',
        white: 'color: white',
        gray: 'color: gray',

        bgBlack: 'background-color: black',
        bgRed: 'background-color: red',
        bgGreen: 'background-color: green',
        bgYellow: 'background-color: yellow',
        bgBlue: 'background-color: blue',
        bgMagenta: 'background-color: magenta',
        bgCyan: 'background-color: cyan',
        bgWhite: 'background-color: white'
    };

    var HtmlSerializer = createSerializer({
        text: function (text) {
            text = String(text)
                .replace(/&/g, '&')
                .replace(/ /g, ' ')
                .replace(/</g, '<')
                .replace(/>/g, '>')
                .replace(/"/g, '"');

            if (arguments.length > 1) {
                var stylesString = Array.prototype.slice.call(arguments, 1).join(',');
                var styles = filter(stylesString.split(/\s*,\s*/), function (styleName) {
                    return htmlStyles[styleName];
                });

                text = '' + text + '';
            }
            return text;
        },
        lines: function (lines) {
            return '\n' +
                map(lines, function (line) {
                    return '
' + line.content.join('') + '
';
                }).join('\n') + '\n' +
                '';
        },
        block: function (content) {
            return '
' + content + '
';
        },
        space: function (count) {
            return duplicateText(' ', count || 1);
        }
    });

    var defaults = {
        mode: 'plain'
    };

    function MagicPen(mode) {
        if (this === global) {
            return new MagicPen(mode);
        }

        var that = this;

        extend(this, defaults, {
            indentationLevel: 0,
            output: [],
            styles: {}
        });

        this.mode = mode || this.mode;
        this.serializer = new MagicPen.serializers[this.mode]();

        forEach(getKeys(this.serializer.styles), function (style) {
            if (!that[style]) {
                that[style] = function () {
                    var args = Array.prototype.slice.call(arguments);
                    return this.write.call(this, { style: style, args: args });
                };
            }
        });
    }

    MagicPen.prototype.newline = MagicPen.prototype.nl = function () {
        this.output.push([]);
        return this;
    };

    MagicPen.serializers = {
        plain: PlainSerializer,
        ansi: AnsiSerializer,
        html: HtmlSerializer
    };

    MagicPen.prototype.write = function () {
        var args = Array.prototype.slice.call(arguments);
        if (args.length === 0) {
            return this;
        } else if (args.length === 1 && isOutputEntry(args[0])) {
            var options = args[0];
            if (this.styles[options.style]) {
                this.styles[options.style].apply(this, options.args);
                return this;
            }
            this.output[0] = this.output[0] || [];
            this.output[this.output.length - 1].push(options);
            return this;
        } else if (args.length === 1) {
            return this.write({ style: 'text', args: args });
        } else {
            return this.write({ style: args[0], args: args.slice(1) });
        }
    };

    MagicPen.prototype.indentLines = function () {
        this.indentationLevel += 1;
        this.newline();
        return this;
    };

    MagicPen.prototype.indent = MagicPen.prototype.i = function () {
        for (var i = 0; i < this.indentationLevel; i += 1) {
            this.space(2);
        }
        return this;
    };

    MagicPen.prototype.outdentLines = function () {
        this.indentationLevel = Math.max(0, this.indentationLevel - 1);
        this.newline();
        return this;
    };

    MagicPen.prototype.addStyle = function (style, handler) {
        var that = this;
        this.styles[style] = handler;
        if (!this[style]) {
            this[style] = function () {
                handler.apply(that, arguments);
                return that;
            };
        }
        return this;
    };

    MagicPen.prototype.toString = function () {
        return this.serializer.serialize(this.output);
    };

    MagicPen.prototype.ensurePenWithSameMode = function (pen) {
        if (!(pen instanceof MagicPen) || pen.mode !== this.mode) {
            throw new Error('Expected an instance of a MagicPen in ' + this.mode + ' mode');
        }
    };

    MagicPen.prototype.block = function (pen) {
        this.ensurePenWithSameMode(pen);
        return this.write('block', pen.toString());
    };

    MagicPen.prototype.append = function (pen) {
        this.ensurePenWithSameMode(pen);
        if (pen.output.length === 0) {
            return this;
        }

        this.output[0] = this.output[0] || [];
        this.output[0].push.apply(this.output[0], pen.output[0]);

        this.output.push.apply(this.output, pen.output.slice(1));

        return this;
    };

    MagicPen.prototype.prependLinesWith = function (pen) {
        this.ensurePenWithSameMode(pen);
        if (pen.output.length === 0 || this.output.length === 0) {
            return this;
        }
        var outputToPrepend = Array.prototype.concat.apply([], pen.output);

        this.output = map(this.output, function (line) {
            return outputToPrepend.concat(line);
        });

        return this;
    };

    MagicPen.prototype.clone = function () {
        function MagicPenClone() {}
        MagicPenClone.prototype = this;
        var clonedPen = new MagicPenClone();
        clonedPen.indentationLevel = 0;
        clonedPen.output = [];
        return clonedPen;
    };

    return MagicPen;
}));
<|endoftext|>


<commit_before>function * allMultiples (multiple, limit) {
  for(let j = multiple; j < limit; j+=multiple ) {
    yield j
  }
}

const flatten = (acc, arr) => [...acc, ...arr]
const sum = (acc, n) => acc + n
const unique = (n, i, arr) => arr.indexOf(n) === i

const sumOfMultiples = (multiples) => {
  return {
    to: (limit) => {
      return multiples
        .map((n) => [...allMultiples(n, limit)])
        .reduce(flatten, [])
        .filter(unique)
        .reduce(sum, 0)
    }
  }
}

export default sumOfMultiples
<commit_msg>More beautiful solution<commit_after>const sum = (acc, n) => acc + n
const range = n => [...Array(n).keys()]

const sumOfMultiples = (multiples) => {
  return {
    to: (limit) => {
      return range(limit)
        .filter(i => multiples.some(multiple => i % multiple === 0))
        .reduce(sum, 0)
    }
  }
}

export default sumOfMultiples
<|endoftext|>


<commit_before>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2014 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

define([
    "jquery",
    "base1/cockpit",
    "base1/po"
], function($, cockpit, po) {
    "use strict";

    cockpit.locale(po);
    var _ = cockpit.gettext;

    var kubernetes = { };

    function debug() {
        if (window.debugging == "all" || window.debugging == "kubernetes")
            console.debug.apply(console, arguments);
    }

    function failure(ex) {
        console.warn(ex);
    }

    /*
     * KubernetesWatch:
     * @api: a cockpit.http() object for the api server
     * @type: a string like 'pods' or 'nodes'
     * @update: invoked when ADDED or MODIFIED happens
     * @remove: invoked when DELETED happens
     *
     * Generates callbacks based on a Kubernetes watch.
     *
     * Each KubernetesWatch object watches a single type of object
     * in Kubernetes. The URI watched is /api/v1beta3/watch/<type>
     *
     * In addition to the above noted invocations of the callbacks,
     * if there is an ERROR, we restart the watch and invoke the
     * @remove callback with a null argument to indicate we are
     * starting over.
     */
    function KubernetesWatch(api, type, update, remove) {
        var self = this;

        var lastResource;
        var stopping = false;
        var requested = false;
        var req = null;

        /*
         * Each change is sent as an individual line from Kubernetes
         * but they may not arrive exactly that way, so we buffer
         * and split lines again.
         */

        var buffer;
        function handle_watch(data) {
            if (buffer)
                data = buffer + data;

            var lines = data.split("\n");
            var i, length = lines.length - 1;

            /* Last line is incomplete save for later */
            buffer = lines[length];

            /* Process all the others */
            var action, object;
            for (i = 0; i < length; i++) {
                try {
                    action = JSON.parse(lines[i]);
                } catch (ex) {
                    failure(ex);
                    req.close();
                    continue;
                }

                object = action.object;
                if (!object) {
                    console.warn("invalid watch without object");
                    continue;
                }

                if (object.metadata)
                    lastResource = object.metadata.resourceVersion;
                else
                    lastResource = null;

                if (action.type == "ADDED") {
                    update(object);
                } else if (action.type == "MODIFIED") {
                    update(object);
                } else if (action.type == "DELETED") {
                    remove(object);

                /* The watch failed, likely due to invalid resourceVersion */
                } else if (action.type == "ERROR") {
                    if (lastResource) {
                        lastResource = null;
                        start_watch();
                    }

                } else {
                    console.warn("invalid watch action type: " + action.type);
                    continue;
                }
            }
        }

        function start_watch() {
            var uri = "/api/v1beta3/watch/" + type;

            /*
             * If we have a last resource we can guarantee that we don't miss
             * any objects or changes to objects. If we don't have one, then we
             * have to list everything again. Still watch at the same time though.
             */
            if (requested && lastResource)
                uri += "?resourceVersion=" + encodeURIComponent(lastResource);

            /* Tell caller to remove all sources */
            else if (!requested)
                remove(null);

            /*
             * As a precaution, watch must take at least 1 second
             * to complete. Otherwise we could be in a tight loop here.
             * eg: if the API of Kubernetes changes unpredictably.
             */
            var waited = false;
            window.setTimeout(function() {
                waited = true;
            }, 1000);

            if (req) {
                req.cancelled = true;
                req.close();
            }

            req = api.get(uri)
                .stream(handle_watch)
                .fail(function(ex) {
                    req = null;
                    if (!stopping)
                        console.warn("watching kubernetes " + type + " failed: " + ex);
                })
                .done(function(data) {
                    var cancelled = req && req.cancelled;
                    req = null;
                    if (!stopping && !cancelled) {
                        if (!waited)
                            console.warn("watching kubernetes " + type + " didn't block");
                        else
                            start_watch();
                    }
                });
            requested = true;
        }

        start_watch();

        self.stop = function stop() {
            stopping = true;
            if (req)
                req.close();
        };
    }

    function KubernetesClient() {
        var self = this;

        var api = cockpit.http(8080);
        var watches = [ ];

        self.resourceVersion = null;

        /*
         * Here we create KubernetesWatch object, and a property
         * definition for each type of object and hook them together.
         */
        function bind(type, items) {
            var flat = null;
            var timeout;

            /* Always delay the update event a bit */
            function trigger() {
                flat = null;
                if (!timeout) {
                    timeout = window.setTimeout(function() {
                        timeout = null;
                        $(self).triggerHandler(type);
                    }, 100);
                }
            }

            function updated(item) {
                var meta = item.metadata;
                if (!meta || !meta.uid) {
                    console.warn("kubernetes item without uid");
                    return;
                }
                if (meta.resourceVersion && meta.resourceVersion > self.resourceVersion)
                    self.resourceVersion = meta.resourceVersion;

                items[item.metadata.uid] = item;
                trigger();
            }

            function removed(item) {
                var key;
                if (!item) {
                    for (key in items)
                        delete items[key];
                } else {
                    key = item.metadata ? item.metadata.uid : null;
                    if (!key) {
                        console.warn("kubernetes item without uid");
                        return;
                    }
                    delete items[key];
                }
                trigger();
            }

            Object.defineProperty(self, type, {
                enumerable: true,
                get: function get() {
                    if (!flat) {
                        flat = [];
                        for (var key in items)
                            flat.push(items[key]);
                        flat.sort(function(a1, a2) {
                            return (a1.metadata.name || "").localeCompare(a2.metadata.name || "");
                        });
                    }
                    return flat;
                }
            });

            var wc = new KubernetesWatch(api, type, updated, removed);
            watches.push(wc);
        }

        /* Define and bind various properties which are arrays of objects */

        var nodes = { };
        bind("nodes", nodes);

        var pods =  { };
        bind("pods", pods);

        var services = { };
        bind("services", services);

        var replicationcontrollers = { };
        bind("replicationcontrollers", replicationcontrollers);

        this.delete_pod = function delete_pod(pod_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/pods/" + encodeURIComponent(pod_name)
            }).fail(failure);
        };

        this.delete_node = function delete_node(nodes_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/nodes/" + encodeURIComponent(nodes_name)
            }).fail(failure);
        };

        this.delete_replicationcontroller = function delete_replicationcontroller(rc_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/replicationcontrollers/" + encodeURIComponent(rc_name)
            }).fail(failure);
        };

        this.delete_service = function delete_service(service_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/services/" + encodeURIComponent(service_name)
            }).fail(failure);
        };

        this.create_replicationcontroller = function create_replicationcontroller(replicationcontroller_json) {
            api.post("/api/v1beta3/namespaces/default/replicationcontrollers", replicationcontroller_json)
               .fail(failure);
        };

        this.create_node = function create_node(node_json) {
            api.post("/api/v1beta3/namespaces/default/nodes", node_json)
               .fail(failure);
        };

        this.create_pod = function create_pod(pod_json) {
            api.post("/api/v1beta3/namespaces/default/pods", pod_json)
               .fail(failure);
        };

        this.create_service = function create_pod(service_json) {
            api.post("/api/v1beta3/namespaces/default/services", service_json)
               .fail(failure);
        };

        this.update_replicationcontroller = function update_replicationcontroller(rc_json, rc_name) {
            api.request({"method": "PUT",
                "body": rc_json,
                "path": "/api/v1beta3/namespaces/default/replicationcontrollers/" + encodeURIComponent(rc_name)
            }).fail(failure);
        };

        self.close = function close() {
            var w = watches;
            watches = [ ];
            $.each(w, function(i, wc) {
                wc.stop();
            });
        };
    }

    function EtcdClient() {
        var self = this;

        var etcd_api = cockpit.http(7001);
        var first = true;
        var later;

        function receive(data, what ,kind) {
            var resp = JSON.parse(data);
            self[what] = resp;

            if (!first)
                $(self).triggerHandler(what, [ self[what] ]);
        }

        function update() {
            var reqs = [];

            reqs.push(etcd_api.get("/v2/admin/machines")
                .fail(failure)
                .done(function(data) {
                    receive(data, "etcdHosts");
                }));

            reqs.push(etcd_api.get("/v2/keys/coreos.com/network/config")
                .fail(failure)
                .done(function(data) {
                    receive(data, "flannelConfig");
                }));

            if (first) {
                $.when.apply($, reqs)
                    .always(function() {
                        first = false;
                        $(self).triggerHandler("etcdHosts", [ self.etcdHosts ]);
                    });
            }
        }

        update();
    }

    kubernetes.k8client = function client() {
        return new KubernetesClient();
    };

    kubernetes.etcdclient = function client() {
        return new EtcdClient();
    };

    return kubernetes;
});
<commit_msg>kubernetes: Remove unneeded items arrays<commit_after>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2014 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

define([
    "jquery",
    "base1/cockpit",
    "base1/po"
], function($, cockpit, po) {
    "use strict";

    cockpit.locale(po);
    var _ = cockpit.gettext;

    var kubernetes = { };

    function debug() {
        if (window.debugging == "all" || window.debugging == "kubernetes")
            console.debug.apply(console, arguments);
    }

    function failure(ex) {
        console.warn(ex);
    }

    /*
     * KubernetesWatch:
     * @api: a cockpit.http() object for the api server
     * @type: a string like 'pods' or 'nodes'
     * @update: invoked when ADDED or MODIFIED happens
     * @remove: invoked when DELETED happens
     *
     * Generates callbacks based on a Kubernetes watch.
     *
     * Each KubernetesWatch object watches a single type of object
     * in Kubernetes. The URI watched is /api/v1beta3/watch/<type>
     *
     * In addition to the above noted invocations of the callbacks,
     * if there is an ERROR, we restart the watch and invoke the
     * @remove callback with a null argument to indicate we are
     * starting over.
     */
    function KubernetesWatch(api, type, update, remove) {
        var self = this;

        var lastResource;
        var stopping = false;
        var requested = false;
        var req = null;

        /*
         * Each change is sent as an individual line from Kubernetes
         * but they may not arrive exactly that way, so we buffer
         * and split lines again.
         */

        var buffer;
        function handle_watch(data) {
            if (buffer)
                data = buffer + data;

            var lines = data.split("\n");
            var i, length = lines.length - 1;

            /* Last line is incomplete save for later */
            buffer = lines[length];

            /* Process all the others */
            var action, object;
            for (i = 0; i < length; i++) {
                try {
                    action = JSON.parse(lines[i]);
                } catch (ex) {
                    failure(ex);
                    req.close();
                    continue;
                }

                object = action.object;
                if (!object) {
                    console.warn("invalid watch without object");
                    continue;
                }

                if (object.metadata)
                    lastResource = object.metadata.resourceVersion;
                else
                    lastResource = null;

                if (action.type == "ADDED") {
                    update(object);
                } else if (action.type == "MODIFIED") {
                    update(object);
                } else if (action.type == "DELETED") {
                    remove(object);

                /* The watch failed, likely due to invalid resourceVersion */
                } else if (action.type == "ERROR") {
                    if (lastResource) {
                        lastResource = null;
                        start_watch();
                    }

                } else {
                    console.warn("invalid watch action type: " + action.type);
                    continue;
                }
            }
        }

        function start_watch() {
            var uri = "/api/v1beta3/watch/" + type;

            /*
             * If we have a last resource we can guarantee that we don't miss
             * any objects or changes to objects. If we don't have one, then we
             * have to list everything again. Still watch at the same time though.
             */
            if (requested && lastResource)
                uri += "?resourceVersion=" + encodeURIComponent(lastResource);

            /* Tell caller to remove all sources */
            else if (!requested)
                remove(null);

            /*
             * As a precaution, watch must take at least 1 second
             * to complete. Otherwise we could be in a tight loop here.
             * eg: if the API of Kubernetes changes unpredictably.
             */
            var waited = false;
            window.setTimeout(function() {
                waited = true;
            }, 1000);

            if (req) {
                req.cancelled = true;
                req.close();
            }

            req = api.get(uri)
                .stream(handle_watch)
                .fail(function(ex) {
                    req = null;
                    if (!stopping)
                        console.warn("watching kubernetes " + type + " failed: " + ex);
                })
                .done(function(data) {
                    var cancelled = req && req.cancelled;
                    req = null;
                    if (!stopping && !cancelled) {
                        if (!waited)
                            console.warn("watching kubernetes " + type + " didn't block");
                        else
                            start_watch();
                    }
                });
            requested = true;
        }

        start_watch();

        self.stop = function stop() {
            stopping = true;
            if (req)
                req.close();
        };
    }

    function KubernetesClient() {
        var self = this;

        var api = cockpit.http(8080);
        var watches = [ ];

        self.resourceVersion = null;

        /*
         * Here we create KubernetesWatch object, and a property
         * definition for each type of object and hook them together.
         */
        function bind(type) {
            var flat = null;
            var items = { };
            var timeout;

            /* Always delay the update event a bit */
            function trigger() {
                flat = null;
                if (!timeout) {
                    timeout = window.setTimeout(function() {
                        timeout = null;
                        $(self).triggerHandler(type);
                    }, 100);
                }
            }

            function updated(item) {
                var meta = item.metadata;
                if (!meta || !meta.uid) {
                    console.warn("kubernetes item without uid");
                    return;
                }
                if (meta.resourceVersion && meta.resourceVersion > self.resourceVersion)
                    self.resourceVersion = meta.resourceVersion;

                items[item.metadata.uid] = item;
                trigger();
            }

            function removed(item) {
                var key;
                if (!item) {
                    for (key in items)
                        delete items[key];
                } else {
                    key = item.metadata ? item.metadata.uid : null;
                    if (!key) {
                        console.warn("kubernetes item without uid");
                        return;
                    }
                    delete items[key];
                }
                trigger();
            }

            Object.defineProperty(self, type, {
                enumerable: true,
                get: function get() {
                    if (!flat) {
                        flat = [];
                        for (var key in items)
                            flat.push(items[key]);
                        flat.sort(function(a1, a2) {
                            return (a1.metadata.name || "").localeCompare(a2.metadata.name || "");
                        });
                    }
                    return flat;
                }
            });

            var wc = new KubernetesWatch(api, type, updated, removed);
            watches.push(wc);
        }

        /* Define and bind various properties which are arrays of objects */

        bind("nodes");
        bind("pods");
        bind("services");
        bind("replicationcontrollers");

        this.delete_pod = function delete_pod(pod_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/pods/" + encodeURIComponent(pod_name)
            }).fail(failure);
        };

        this.delete_node = function delete_node(nodes_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/nodes/" + encodeURIComponent(nodes_name)
            }).fail(failure);
        };

        this.delete_replicationcontroller = function delete_replicationcontroller(rc_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/replicationcontrollers/" + encodeURIComponent(rc_name)
            }).fail(failure);
        };

        this.delete_service = function delete_service(service_name) {
            api.request({"method": "DELETE",
                "body": "",
                "path": "/api/v1beta3/namespaces/default/services/" + encodeURIComponent(service_name)
            }).fail(failure);
        };

        this.create_replicationcontroller = function create_replicationcontroller(replicationcontroller_json) {
            api.post("/api/v1beta3/namespaces/default/replicationcontrollers", replicationcontroller_json)
               .fail(failure);
        };

        this.create_node = function create_node(node_json) {
            api.post("/api/v1beta3/namespaces/default/nodes", node_json)
               .fail(failure);
        };

        this.create_pod = function create_pod(pod_json) {
            api.post("/api/v1beta3/namespaces/default/pods", pod_json)
               .fail(failure);
        };

        this.create_service = function create_pod(service_json) {
            api.post("/api/v1beta3/namespaces/default/services", service_json)
               .fail(failure);
        };

        this.update_replicationcontroller = function update_replicationcontroller(rc_json, rc_name) {
            api.request({"method": "PUT",
                "body": rc_json,
                "path": "/api/v1beta3/namespaces/default/replicationcontrollers/" + encodeURIComponent(rc_name)
            }).fail(failure);
        };

        self.close = function close() {
            var w = watches;
            watches = [ ];
            $.each(w, function(i, wc) {
                wc.stop();
            });
        };
    }

    function EtcdClient() {
        var self = this;

        var etcd_api = cockpit.http(7001);
        var first = true;
        var later;

        function receive(data, what ,kind) {
            var resp = JSON.parse(data);
            self[what] = resp;

            if (!first)
                $(self).triggerHandler(what, [ self[what] ]);
        }

        function update() {
            var reqs = [];

            reqs.push(etcd_api.get("/v2/admin/machines")
                .fail(failure)
                .done(function(data) {
                    receive(data, "etcdHosts");
                }));

            reqs.push(etcd_api.get("/v2/keys/coreos.com/network/config")
                .fail(failure)
                .done(function(data) {
                    receive(data, "flannelConfig");
                }));

            if (first) {
                $.when.apply($, reqs)
                    .always(function() {
                        first = false;
                        $(self).triggerHandler("etcdHosts", [ self.etcdHosts ]);
                    });
            }
        }

        update();
    }

    kubernetes.k8client = function client() {
        return new KubernetesClient();
    };

    kubernetes.etcdclient = function client() {
        return new EtcdClient();
    };

    return kubernetes;
});
<|endoftext|>


<commit_before>var aws      = require('aws-sdk');
var feedRead = require('feed-read');
var fs       = require('fs');
var slug     = require('slug');
var _url     = require('url');
var util     = require('util');

slug.defaults.mode ='rfc3986';

// build feed index for fast lookup
var index = {};
var conf = JSON.parse(fs.readFileSync('feeds.json'));
conf.forEach(function (category) {
  var categoryId = slug(category.title);
  index[categoryId] = {};
  category.feeds.forEach(function (feed) {
    var feedId = slug(feed.title);
    index[categoryId][feedId] = feed.url;
  });
});

function fetchFeed(url, cb) {
  console.log('Fetching feed: ' + url);

  feedRead(url, function(err, articles) {
    if (err) {
      console.error('Unable to fetch feed: ' + url, err);
      cb(err);
    } else {

      var articlesList = [];
      articles.forEach(function (article) {

        // append link to feed host if link doesn't contain protocol
        if (!article.link.match(/^http/)) {
          if (!article.link.match(/^\//)) {
            article.link = '/' + article.link;
          }
          var elems = _url.parse(url);
          article.link = url.replace(new RegExp(elems.path), '') + article.link;
        }

        articlesList.push({
          url  : article.link,
          title: article.title
        });
      });

      cb(null, articlesList);
    }
  });
}

function getFeed(event, context) {

  var url      = index[event.categoryId][event.feedId];
  var bucket   = 'feedpaper-data-stg';
  var endpoint = 's3-ap-southeast-2.amazonaws.com';
  var key      = util.format('%s/%s/%s', category, id, slug(url));

  var s3 = new aws.S3({ endpoint: new aws.Endpoint(endpoint) });

  function fetchFeedCb(err, articlesList) {
    if (err) {
      context.fail(err);
    } else {
      var params = {
        Bucket: bucket,
        Key: key,
        Body: JSON.stringify(articlesList)
      };
      console.log('Saving feed: ' + url);
      s3.putObject(params, function (err, data) {
        if (err) {
          console.error('Unable to save feed: ' + url, err);
          context.fail(err);
        } else {
          context.succeed(params.Body);
        }
      });
    }
  }

  var params = {
    Bucket: bucket,
    Key: key
  };
  s3.getObject(params, function (err, data) {
    if (err) {
      fetchFeed(url, fetchFeedCb);
    } else {
      console.log('Found feed: ' + url);
      context.succeed(data.Body.toString('utf-8'));
    }
  });
}

exports.handler = getFeed;
<commit_msg>Category and feed IDs should be retrieved from event.<commit_after>var aws      = require('aws-sdk');
var feedRead = require('feed-read');
var fs       = require('fs');
var slug     = require('slug');
var _url     = require('url');
var util     = require('util');

slug.defaults.mode ='rfc3986';

// build feed index for fast lookup
var index = {};
var conf = JSON.parse(fs.readFileSync('feeds.json'));
conf.forEach(function (category) {
  var categoryId = slug(category.title);
  index[categoryId] = {};
  category.feeds.forEach(function (feed) {
    var feedId = slug(feed.title);
    index[categoryId][feedId] = feed.url;
  });
});

function fetchFeed(url, cb) {
  console.log('Fetching feed: ' + url);

  feedRead(url, function(err, articles) {
    if (err) {
      console.error('Unable to fetch feed: ' + url, err);
      cb(err);
    } else {

      var articlesList = [];
      articles.forEach(function (article) {

        // append link to feed host if link doesn't contain protocol
        if (!article.link.match(/^http/)) {
          if (!article.link.match(/^\//)) {
            article.link = '/' + article.link;
          }
          var elems = _url.parse(url);
          article.link = url.replace(new RegExp(elems.path), '') + article.link;
        }

        articlesList.push({
          url  : article.link,
          title: article.title
        });
      });

      cb(null, articlesList);
    }
  });
}

function getFeed(event, context) {

  var url      = index[event.categoryId][event.feedId];
  var bucket   = 'feedpaper-data-stg';
  var endpoint = 's3-ap-southeast-2.amazonaws.com';
  var key      = util.format('%s/%s/%s', event.categoryId, event.feedId, slug(url));

  var s3 = new aws.S3({ endpoint: new aws.Endpoint(endpoint) });

  function fetchFeedCb(err, articlesList) {
    if (err) {
      context.fail(err);
    } else {
      var params = {
        Bucket: bucket,
        Key: key,
        Body: JSON.stringify(articlesList)
      };
      console.log('Saving feed: ' + url);
      s3.putObject(params, function (err, data) {
        if (err) {
          console.error('Unable to save feed: ' + url, err);
          context.fail(err);
        } else {
          context.succeed(params.Body);
        }
      });
    }
  }

  var params = {
    Bucket: bucket,
    Key: key
  };
  s3.getObject(params, function (err, data) {
    if (err) {
      fetchFeed(url, fetchFeedCb);
    } else {
      console.log('Found feed: ' + url);
      context.succeed(data.Body.toString('utf-8'));
    }
  });
}

exports.handler = getFeed;
<|endoftext|>


<commit_before>var Chunks = require('../Chunks');

var SameFinder = function(original, updated) {
    this.original = original;
    this.updated = updated;
    this.same = [];
    this.lastFoundIndex = -1;
}

SameFinder.prototype.loopChunks = function(func) {
    for (var index = 0; index < this.original.length; index++) {
        func.call(this, index);
    }
}

SameFinder.prototype.isSame = function(foundIndex) {
    return foundIndex !== -1;
}

SameFinder.prototype.addChunk = function(originalIndex, foundIndex, chunks) {
    this.same.push({
        type: 'same',
        originalIndex: originalIndex,
        index: foundIndex,
        chunks: new Chunks([chunks])
    });
}

SameFinder.prototype.determineChunk = function(index) {

    var original = this.original.get(index);
    var begin = this.beginSearchIndex();
    var foundIndex = this.updated.indexOf(original, begin);

    if (this.isSame(foundIndex)) {
        this.setLastFoundIndex(foundIndex);
        this.removeHitsAfterIndex(foundIndex);
        this.addChunk(index, foundIndex, original);
    }
}

SameFinder.prototype.beginSearchIndex = function() {
    var chunkIndex = this.same.length - 2;
    return chunkIndex >= 0 ? this.same[chunkIndex].index : 0;
}

SameFinder.prototype.removeHitsAfterIndex = function(foundIndex) {
    this.same = this.same.filter(function(item) {
        return item.index < foundIndex;
    });
}

SameFinder.prototype.setLastFoundIndex = function(index) {
    this.lastFoundIndex = index;
}

SameFinder.prototype.result = function() {
    return this.same;
}

SameFinder.prototype.get = function() {
    this.loopChunks(this.determineChunk);
    return this.result();
}

module.exports = SameFinder;
<commit_msg>begin search from latest item in SameFinder<commit_after>var Chunks = require('../Chunks');

var SameFinder = function(original, updated) {
    this.original = original;
    this.updated = updated;
    this.same = [];
    this.lastFoundIndex = -1;
}

SameFinder.prototype.loopChunks = function(func) {
    for (var index = 0; index < this.original.length; index++) {
        func.call(this, index);
    }
}

SameFinder.prototype.isSame = function(foundIndex) {
    return foundIndex !== -1;
}

SameFinder.prototype.addChunk = function(originalIndex, foundIndex, chunks) {
    this.same.push({
        type: 'same',
        originalIndex: originalIndex,
        index: foundIndex,
        chunks: new Chunks([chunks])
    });
}

SameFinder.prototype.determineChunk = function(index) {

    var original = this.original.get(index);
    var begin = this.beginSearchIndex();
    var foundIndex = this.updated.indexOf(original, begin);

    if (this.isSame(foundIndex)) {
        this.setLastFoundIndex(foundIndex);
        this.removeHitsAfterIndex(foundIndex);
        this.addChunk(index, foundIndex, original);
    }
}

SameFinder.prototype.beginSearchIndex = function() {
    var chunkIndex = this.same.length - 1;
    return chunkIndex >= 0 ? this.same[chunkIndex].index : 0;
}

SameFinder.prototype.removeHitsAfterIndex = function(foundIndex) {
    this.same = this.same.filter(function(item) {
        return item.index < foundIndex;
    });
}

SameFinder.prototype.setLastFoundIndex = function(index) {
    this.lastFoundIndex = index;
}

SameFinder.prototype.result = function() {
    return this.same;
}

SameFinder.prototype.get = function() {
    this.loopChunks(this.determineChunk);
    return this.result();
}

module.exports = SameFinder;
<|endoftext|>


<commit_before>/*
Copyright (c) 2011 Cimaron Shanahan

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

function glClear(mask) {

	var ctx, buffer, clear, i;

	ctx = cnvgl_context.getCurrentContext();

	if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
		cnvgl_throw_error(GL_INVALID_VALUE);
		return;
	}

	//GL_COLOR_BUFFER_BIT
	if (mask & GL_COLOR_BUFFER_BIT) {
		buffer = ctx.color_buffer;
		clear = [];
		for (i = 0; i < 4; i++) {
			clear[i] = Math.round(255 * ctx.color.clearColor[i]);
		}
		for (i = 0; i < buffer.length; i += 4) {
			buffer[i] = clear[0];
			buffer[i + 1] = clear[1];
			buffer[i + 2] = clear[2];
			buffer[i + 3] = clear[3];
		}
	}

	//GL_DEPTH_BUFFER_BIT
	if (mask & GL_DEPTH_BUFFER_BIT) {
		buffer = ctx.depth_buffer;
		clear = ctx.depth.clear;
		for (i = 0; i < buffer.length; i ++) {
			buffer[i] = clear;
		}
	}

	if (mask & ~(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)) {
		throw new Error('glClear: todo');
	}

}

<commit_msg>Major speedup in glClear<commit_after>/*
Copyright (c) 2011 Cimaron Shanahan

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

function glClear(mask) {
	var ctx, buffer, clear, i, l;

	ctx = cnvgl_context.getCurrentContext();

	if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
		cnvgl_throw_error(GL_INVALID_VALUE);
		return;
	}

	//Color Buffer
	if (mask & GL_COLOR_BUFFER_BIT) {
		buffer = ctx.color_buffer;
		clear = [];
		for (i = 0; i < 4; i++) {
			clear[i] = Math.round(255 * ctx.color.clearColor[i]);
		}
		l = buffer.length;
		for (i = 0; i < l; i += 4) {
			buffer[i] = clear[0];
			buffer[i + 1] = clear[1];
			buffer[i + 2] = clear[2];
			buffer[i + 3] = clear[3];
		}
	}

	//Depth Buffer
	if (mask & GL_DEPTH_BUFFER_BIT) {
		buffer = ctx.depth_buffer;
		clear = ctx.depth.clear;
		l = buffer.length;
		for (i = 0; i < l; i++) {
			buffer[i] = clear;
		}
	}

	//Stencil Buffer
	if (mask & GL_STENCIL_BUFFER_BIT) {
		throw new Error('glClear: todo');
	}
}

<|endoftext|>