<commit_before>/*jshint indent:2, curly:true eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
regexp:true, undef:true, trailing:true, white:true */
/*global XT:true, XM:true, enyo:true, _:true */

(function () {

  /**
    Implements a dropdown. Unlike the {XV.RelationWidget}, the collection is stored local to the
    widget.

    @class
    @name XV.PickerWidget
    @see XV.Relation
   */
  enyo.kind(/** @lends XV.PickerWidget# */{
    name: "XV.PickerWidget",
    kind: "enyo.Control",
    classes: "xv-pickerwidget",
    events: /** @lends XV.PickerWidget# */{
      /**
        @property {Object} inEvent The payload that's attached to bubbled-up events
        @property {XV.PickerWidget} inEvent.originator This
        @property inEvent.value The value passed up is the key of the object and not the object itself
       */
      onValueChange: ""
    },
    published: {
      attr: null,
      label: "",
      showLabel: true,
      value: null,
      collection: null,
      disabled: false,
      idAttribute: "id",
      nameAttribute: "name",
      orderBy: null,
      noneText: "_none".loc(),
      noneClasses: ""
    },
    handlers: {
      onSelect: "itemSelected"
    },
    components: [
      {kind: "FittableColumns", components: [
        {name: "label", content: "", classes: "xv-picker-label"},
        {kind: "onyx.InputDecorator", classes: "xv-input-decorator",
          components: [
          {kind: "onyx.PickerDecorator",
            components: [
            {content: "_none".loc(), classes: "xv-picker"},
            {name: "picker", kind: "onyx.Picker"}
          ]}
        ]}
      ]}
    ],
    buildList: function () {
      var nameAttribute = this.getNameAttribute(),
        models = this.filteredList(),
        none = this.getNoneText(),
        classes = this.getNoneClasses(),
        name,
        model,
        i;
      this.$.picker.destroyClientControls();
      this.$.picker.createComponent({
        value: null,
        content: none,
        classes: classes
      });
      for (i = 0; i < models.length; i++) {
        model = models[i];
        name = model.get(nameAttribute);
        this.$.picker.createComponent({ value: model, content: name });
      }
      this.render();
    },
    clear: function (options) {
      this.setValue(null, options);
    },
    collectionChanged: function () {
      var collection = XT.getObjectByName(this.collection),
        callback,
        didStartup = false,
        that = this;

      // If we don't have data yet, try again after start up tasks complete
      if (!collection) {
        if (didStartup) {
          XT.log('Could not find collection ' + this.getCollection());
          return;
        }
        callback = function () {
          didStartup = true;
          that.collectionChanged();
        };
        XT.getStartupManager().registerCallback(callback);
        return;
      }
      this._collection = collection;
      this.orderByChanged();
      if (this._collection.comparator) { this._collection.sort(); }
      this.buildList();
    },
    create: function () {
      this.inherited(arguments);
      if (this.getCollection()) { this.collectionChanged(); }
      this.labelChanged();
      this.showLabelChanged();
    },
    disabledChanged: function (inSender, inEvent) {
      this.$.pickerButton.setDisabled(this.getDisabled());
    },
    getValueToString: function () {
      return this.$.pickerButton.getContent();
    },
    itemSelected: function (inSender, inEvent) {
      var value = this.$.picker.getSelected().value;
      this.setValue(value);
      return true;
    },
    /**
      Implement your own filter function here. By default
      simply returns the array of models passed.

      @param {Array}
      returns {Array}
    */
    filter: function (models) {
      return models || [];
    },
    /**
      Returns array of models for current collection instance with `filter`
      applied.
    */
    filteredList: function () {
      return this._collection ? this.filter(this._collection.models) : [];
    },
    labelChanged: function () {
      var label = this.getLabel() ||
        (this.attr ? ("_" + this.attr).loc() : "");
      this.$.label.setShowing(label);
      this.$.label.setContent(label + ":");
    },
    noneTextChanged: function () {
      this.buildList();
    },
    noneClassesChanged: function () {
      this.buildList();
    },
    orderByChanged: function () {
      var orderBy = this.getOrderBy();
      if (this._collection && orderBy) {
        this._collection.comparator = function (a, b) {
          var aval,
            bval,
            attr,
            i;
          for (i = 0; i < orderBy.length; i++) {
            attr = orderBy[i].attribute;
            aval = orderBy[i].descending ? b.getValue(attr) : a.getValue(attr);
            bval = orderBy[i].descending ? a.getValue(attr) : b.getValue(attr);
            // Bad hack for null 'order' values
            if (attr === "order" && !_.isNumber(aval)) { aval = 9999; }
            if (attr === "order" && !_.isNumber(bval)) { bval = 9999; }
            aval = !isNaN(aval) ? aval - 0 : aval;
            bval = !isNaN(aval) ? bval - 0 : bval;
            if (aval !== bval) {
              return aval > bval ? 1 : -1;
            }
          }
          return 0;
        };
      }
    },
    select: function (index) {
      var i = 0,
        component = _.find(this.$.picker.getComponents(), function (c) {
          if (c.kind === "onyx.MenuItem") { i++; }
          return i > index;
        });
      if (component) {
        this.setValue(component.value);
      }
    },
    /**
      Programatically sets the value of this widget.

      @param value Can be a model or the id of a model (String or Number).
        If it is an ID, then the correct model will be fetched and this
        function will be called again recursively with the model.
      @param options {Object}
     */
    setValue: function (value, options) {
      options = options || {};
      var inEvent,
        oldValue = this.getValue(),
        actualMenuItem,
        actualModel;

      // here is where we find the model and re-call this method if we're given
      // an id instead of a whole model.
      // note that we assume that all of the possible models are already
      // populated in the menu items of the picker
      if (value && typeof value !== 'object') {
        actualMenuItem = _.find(this.$.picker.controls, function (menuItem) {
          return menuItem.value && menuItem.value.id === value;
        });
        if (actualMenuItem) {
          // a menu item matches the selection. Use the model back backs the menu item
          actualModel = actualMenuItem.value;
          this.setValue(actualModel, options);
        }
        // (else "none" is selected and there's no need to do anything)
        return;
      }

      if (value !== oldValue) {
        if (!this._selectValue(value)) { value = null; }
        if (value !== oldValue) {
          this.value = value;
          if (!options.silent) {
            inEvent = { originator: this, value: value && value.id ? value.id : value };
            this.doValueChange(inEvent);
          }
        }
      }
    },
    showLabelChanged: function () {
      if (this.getShowLabel()) {
        this.$.label.show();
      } else {
        this.$.label.hide();
      }
    },
    /** @private */
    _selectValue: function (value) {
      value = value ? value.id : value;
      var component = _.find(this.$.picker.getComponents(), function (c) {
        if (c.kind === "onyx.MenuItem") {
          return (c.value ? c.value.id : null) === value;
        }
      });
      if (!component) { value = null; }
      this.$.picker.setSelected(component);
      return value;
    }
  });

}());
<commit_msg>issue #18788: Add support for idAttribute proprety that was there, but did not work<commit_after>/*jshint indent:2, curly:true eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
regexp:true, undef:true, trailing:true, white:true */
/*global XT:true, XM:true, enyo:true, _:true */

(function () {

  /**
    Implements a dropdown. Unlike the {XV.RelationWidget}, the collection is stored local to the
    widget.

    @class
    @name XV.PickerWidget
    @see XV.Relation
   */
  enyo.kind(/** @lends XV.PickerWidget# */{
    name: "XV.PickerWidget",
    kind: "enyo.Control",
    classes: "xv-pickerwidget",
    events: /** @lends XV.PickerWidget# */{
      /**
        @property {Object} inEvent The payload that's attached to bubbled-up events
        @property {XV.PickerWidget} inEvent.originator This
        @property inEvent.value The value passed up is the key of the object and not the object itself
       */
      onValueChange: ""
    },
    published: {
      attr: null,
      label: "",
      showLabel: true,
      value: null,
      collection: null,
      disabled: false,
      idAttribute: "id",
      nameAttribute: "name",
      orderBy: null,
      noneText: "_none".loc(),
      noneClasses: ""
    },
    handlers: {
      onSelect: "itemSelected"
    },
    components: [
      {kind: "FittableColumns", components: [
        {name: "label", content: "", classes: "xv-picker-label"},
        {kind: "onyx.InputDecorator", classes: "xv-input-decorator",
          components: [
          {kind: "onyx.PickerDecorator",
            components: [
            {content: "_none".loc(), classes: "xv-picker"},
            {name: "picker", kind: "onyx.Picker"}
          ]}
        ]}
      ]}
    ],
    buildList: function () {
      var nameAttribute = this.getNameAttribute(),
        models = this.filteredList(),
        none = this.getNoneText(),
        classes = this.getNoneClasses(),
        name,
        model,
        i;
      this.$.picker.destroyClientControls();
      this.$.picker.createComponent({
        value: null,
        content: none,
        classes: classes
      });
      for (i = 0; i < models.length; i++) {
        model = models[i];
        name = model.get(nameAttribute);
        this.$.picker.createComponent({ value: model, content: name });
      }
      this.render();
    },
    clear: function (options) {
      this.setValue(null, options);
    },
    collectionChanged: function () {
      var collection = XT.getObjectByName(this.collection),
        callback,
        didStartup = false,
        that = this;

      // If we don't have data yet, try again after start up tasks complete
      if (!collection) {
        if (didStartup) {
          XT.log('Could not find collection ' + this.getCollection());
          return;
        }
        callback = function () {
          didStartup = true;
          that.collectionChanged();
        };
        XT.getStartupManager().registerCallback(callback);
        return;
      }
      this._collection = collection;
      this.orderByChanged();
      if (this._collection.comparator) { this._collection.sort(); }
      this.buildList();
    },
    create: function () {
      this.inherited(arguments);
      if (this.getCollection()) { this.collectionChanged(); }
      this.labelChanged();
      this.showLabelChanged();
    },
    disabledChanged: function (inSender, inEvent) {
      this.$.pickerButton.setDisabled(this.getDisabled());
    },
    getValueToString: function () {
      return this.$.pickerButton.getContent();
    },
    itemSelected: function (inSender, inEvent) {
      var value = this.$.picker.getSelected().value;
      this.setValue(value);
      return true;
    },
    /**
      Implement your own filter function here. By default
      simply returns the array of models passed.

      @param {Array}
      returns {Array}
    */
    filter: function (models) {
      return models || [];
    },
    /**
      Returns array of models for current collection instance with `filter`
      applied.
    */
    filteredList: function () {
      return this._collection ? this.filter(this._collection.models) : [];
    },
    labelChanged: function () {
      var label = this.getLabel() ||
        (this.attr ? ("_" + this.attr).loc() : "");
      this.$.label.setShowing(label);
      this.$.label.setContent(label + ":");
    },
    noneTextChanged: function () {
      this.buildList();
    },
    noneClassesChanged: function () {
      this.buildList();
    },
    orderByChanged: function () {
      var orderBy = this.getOrderBy();
      if (this._collection && orderBy) {
        this._collection.comparator = function (a, b) {
          var aval,
            bval,
            attr,
            i;
          for (i = 0; i < orderBy.length; i++) {
            attr = orderBy[i].attribute;
            aval = orderBy[i].descending ? b.getValue(attr) : a.getValue(attr);
            bval = orderBy[i].descending ? a.getValue(attr) : b.getValue(attr);
            // Bad hack for null 'order' values
            if (attr === "order" && !_.isNumber(aval)) { aval = 9999; }
            if (attr === "order" && !_.isNumber(bval)) { bval = 9999; }
            aval = !isNaN(aval) ? aval - 0 : aval;
            bval = !isNaN(aval) ? bval - 0 : bval;
            if (aval !== bval) {
              return aval > bval ? 1 : -1;
            }
          }
          return 0;
        };
      }
    },
    select: function (index) {
      var i = 0,
        component = _.find(this.$.picker.getComponents(), function (c) {
          if (c.kind === "onyx.MenuItem") { i++; }
          return i > index;
        });
      if (component) {
        this.setValue(component.value);
      }
    },
    /**
      Programatically sets the value of this widget.

      @param value Can be a model or the id of a model (String or Number).
        If it is an ID, then the correct model will be fetched and this
        function will be called again recursively with the model.
      @param options {Object}
     */
    setValue: function (value, options) {
      options = options || {};
      var inEvent,
        oldValue = this.getValue(),
        actualMenuItem,
        actualModel,
        key = this.getIdAttribute();

      // here is where we find the model and re-call this method if we're given
      // an id instead of a whole model.
      // note that we assume that all of the possible models are already
      // populated in the menu items of the picker
      if (value && typeof value !== 'object') {
        actualMenuItem = _.find(this.$.picker.controls, function (menuItem) {
          var ret = false;
          if (menuItem.value && menuItem.value.get) {
            ret = menuItem.value.get(key) === value;
          } else if (menuItem.value) {
            ret = menuItem.value[key] === value;
          }
          return ret;
        });
        if (actualMenuItem) {
          // a menu item matches the selection. Use the model back backs the menu item
          actualModel = actualMenuItem.value;
          this.setValue(actualModel, options);
        }
        // (else "none" is selected and there's no need to do anything)
        return;
      }

      if (value !== oldValue) {
        if (!this._selectValue(value)) { value = null; }
        if (value !== oldValue) {
          this.value = value;
          if (!options.silent) {
            inEvent = { originator: this, value: value && value.get ? value.get(key) : value };
            this.doValueChange(inEvent);
          }
        }
      }
    },
    showLabelChanged: function () {
      if (this.getShowLabel()) {
        this.$.label.show();
      } else {
        this.$.label.hide();
      }
    },
    /** @private */
    _selectValue: function (value) {
      var key = this.getIdAttribute(),
        component;
      value = value ? value.get(key) : value;
      component = _.find(this.$.picker.getComponents(), function (c) {
        if (c.kind === "onyx.MenuItem") {
          return (c.value ? c.value.get(key) : null) === value;
        }
      });
      if (!component) { value = null; }
      this.$.picker.setSelected(component);
      return value;
    }
  });

}());
<|endoftext|>


<commit_before>"use strict";

var
    esPhinx,
    Constructor;

(function ($module) {

    const
        CSS_CLASS = "esphinx ui",
        CSS_CLASS_QUERY = "." + CSS_CLASS.replace(/ +/g, ".");

    var
        $ = esPhinx;

    $module.extend({

        panels: {

            autocomplete: {

                new: function (searchTextBox, originalList, options = {},
                    callback) {

                    var
                        ConstructorReference = $module.panels.autocomplete.new,
                        self = this,
                        nodeListFound,
                        referenceNode,
                        created = false,

                        show = function (autocompletedList, nodeListFound) {
                            nodeListFound.deflate();

                            if (searchTextBox.value()) {
                                if (originalList instanceof $) {
                                    originalList.hide();
                                }
                                autocompletedList.each(function (li) {
                                    nodeListFound.append(li);
                                });
                                nodeListFound.show();
                            } else {
                                if (originalList instanceof $) {
                                    originalList.show();
                                }
                                nodeListFound.hide();
                            }

                            return nodeListFound.childElements();
                        },

                        create = function (referenceNode) {
                            var
                                nodeListFound = $("

")
                                    .addClass("originalList-built-found"),
                                marginBottom,
                                width,
                                borderBottom,
                                paddingLeft,
                                paddingRight,
                                marginLeft,
                                marginRight,
                                border,

                                targetWasListFound = function (target) {
                                    if (!target
                                        .is(nodeListFound.childElements())
                                        && !target.is(referenceNode)) {
                                        return true;
                                    }
                                    return false;
                                };

                            if (referenceNode.instanceOf(HTMLInputElement)) {
                                // solution, listening tab
                                // relatedTarget still doesn't work in FF
                                // referenceNode.on("blur", function (e) {
                                //     var
                                //         selection = document.getSelection();
                                //     debugger
                                //     // focused = document.getSelection().focusNode
                                //     // self.hide();
                                // });

                                // if options.multiSelection
                                $(document).on("mouseup", function (e) {
                                    var
                                        selection = document.getSelection(),
                                        focused = document.getSelection()
                                            .focusNode,
                                        target = $(e.target);

                                    if (focused.constructor === Text) {
                                        focused = focused.parentElement;
                                    }

                                    if (targetWasListFound(target)) {
                                        nodeListFound.hide();
                                    }

                                });

                                referenceNode.on("focus", function () {
                                    if (nodeListFound.childElements().any()) {
                                        nodeListFound.show();
                                    }
                                });

                                marginBottom = referenceNode
                                    .css("margin-bottom");
                                width = referenceNode.width();
                                borderBottom = referenceNode
                                    .css("border-bottom");
                                paddingLeft = referenceNode.css("padding-left");
                                paddingRight = referenceNode
                                    .css("padding-right");
                                marginLeft = referenceNode.css("margin-left");
                                marginRight = referenceNode.css("margin-right");
                                border = referenceNode.css("border");

                                nodeListFound
                                    .css("margin-top", -marginBottom + "px");
                                nodeListFound
                                    .css("padding-left", paddingLeft + "px");
                                nodeListFound
                                    .css("padding-right", paddingRight + "px");
                                nodeListFound
                                    .css("margin-left", marginLeft + "px");
                                nodeListFound
                                    .css("margin-right", marginRight + "px");
                                if (width) {
                                    nodeListFound.css("position", "absolute");
                                    nodeListFound.width(width);
                                }
                                nodeListFound.insertAfter(referenceNode);
                            } else {
                                nodeListFound.insertAfter(referenceNode);
                            }

                            return nodeListFound;
                        };

                    if (!(this instanceof ConstructorReference)) {
                        return new ConstructorReference(searchTextBox,
                            originalList, options, callback);
                    }

                    if (originalList.constructor === Object) {
                        referenceNode = searchTextBox;
                        callback = options;
                        options = undefined;
                    } else {
                        referenceNode = originalList;
                    }

                    this.hide = function () {
                        nodeListFound.hide();
                    }

                    searchTextBox.autocomplete(originalList, options,
                    function (found) {
                        if (!created) {
                            created = true;
                            nodeListFound = create(referenceNode);
                        }

                        if (!callback || !callback instanceof Function) {
                            callback = function () {};
                        }

                        callback.call(self, show(found, nodeListFound));
                    });

                }

            }

        }

    });

})(esPhinx.ui);
<commit_msg>comment for implementation<commit_after>"use strict";

var
    esPhinx,
    Constructor;

(function ($module) {

    const
        CSS_CLASS = "esphinx ui",
        CSS_CLASS_QUERY = "." + CSS_CLASS.replace(/ +/g, ".");

    var
        $ = esPhinx;

    $module.extend({

        panels: {

            autocomplete: {

                new: function (searchTextBox, originalList, options = {},
                    callback) {

                    var
                        ConstructorReference = $module.panels.autocomplete.new,
                        self = this,
                        nodeListFound,
                        referenceNode,
                        created = false,

                        show = function (autocompletedList, nodeListFound) {
                            nodeListFound.deflate();

                            if (searchTextBox.value()) {
                                if (originalList instanceof $) {
                                    originalList.hide();
                                }
                                autocompletedList.each(function (li) {
                                    nodeListFound.append(li);
                                });
                                nodeListFound.show();
                            } else {
                                if (originalList instanceof $) {
                                    originalList.show();
                                }
                                nodeListFound.hide();
                            }

                            return nodeListFound.childElements();
                        },

                        create = function (referenceNode) {
                            var
                                nodeListFound = $("

")
                                    .addClass("originalList-built-found"),
                                marginBottom,
                                width,
                                borderBottom,
                                paddingLeft,
                                paddingRight,
                                marginLeft,
                                marginRight,
                                border,

                                targetWasListFound = function (target) {
                                    if (!target
                                        .is(nodeListFound.childElements())
                                        && !target.is(referenceNode)) {
                                        return true;
                                    }
                                    return false;
                                };

                            if (referenceNode.instanceOf(HTMLInputElement)) {
                                // solution, listening tab
                                // relatedTarget still doesn't work in FF
                                // referenceNode.on("blur", function (e) {
                                //     var
                                //         selection = document.getSelection();
                                //     debugger
                                //     // focused = document.getSelection().focusNode
                                //     // self.hide();
                                // });

                                // talvez seja interessante remover da lista depois de selecionado sem intervenção do usuário
                                $(document).on("mouseup", function (e) {
                                    var
                                        selection = document.getSelection(),
                                        focused = document.getSelection()
                                            .focusNode,
                                        target = $(e.target);

                                    if (focused.constructor === Text) {
                                        focused = focused.parentElement;
                                    }

                                    if (targetWasListFound(target)) {
                                        nodeListFound.hide();
                                    }

                                });

                                referenceNode.on("focus", function () {
                                    if (nodeListFound.childElements().any()) {
                                        nodeListFound.show();
                                    }
                                });

                                marginBottom = referenceNode
                                    .css("margin-bottom");
                                width = referenceNode.width();
                                borderBottom = referenceNode
                                    .css("border-bottom");
                                paddingLeft = referenceNode.css("padding-left");
                                paddingRight = referenceNode
                                    .css("padding-right");
                                marginLeft = referenceNode.css("margin-left");
                                marginRight = referenceNode.css("margin-right");
                                border = referenceNode.css("border");

                                nodeListFound
                                    .css("margin-top", -marginBottom + "px");
                                nodeListFound
                                    .css("padding-left", paddingLeft + "px");
                                nodeListFound
                                    .css("padding-right", paddingRight + "px");
                                nodeListFound
                                    .css("margin-left", marginLeft + "px");
                                nodeListFound
                                    .css("margin-right", marginRight + "px");
                                if (width) {
                                    nodeListFound.css("position", "absolute");
                                    nodeListFound.width(width);
                                }
                                nodeListFound.insertAfter(referenceNode);
                            } else {
                                nodeListFound.insertAfter(referenceNode);
                            }

                            return nodeListFound;
                        };

                    if (!(this instanceof ConstructorReference)) {
                        return new ConstructorReference(searchTextBox,
                            originalList, options, callback);
                    }

                    if (originalList.constructor === Object) {
                        referenceNode = searchTextBox;
                        callback = options;
                        options = undefined;
                    } else {
                        referenceNode = originalList;
                    }

                    this.hide = function () {
                        nodeListFound.hide();
                    }

                    searchTextBox.autocomplete(originalList, options,
                    function (found) {
                        if (!created) {
                            created = true;
                            nodeListFound = create(referenceNode);
                        }

                        if (!callback || !callback instanceof Function) {
                            callback = function () {};
                        }

                        callback.call(self, show(found, nodeListFound));
                    });

                }

            }

        }

    });

})(esPhinx.ui);
<|endoftext|>


<commit_before>
var app = {

    initialize: function($root) {
        $root.html([
            '
',
                'Dependencies are loaded, app is initialized, we\'re safe to start...',
            '
'
        ].join(""));

        this.$fooButton = $([
            '<button disabled>',
                '...in the meantime we\'re still waiting for Foo',
            '</button>'
        ].join(""))
            .appendTo($root);

        // this is critical to our foo example
        appCallbackStack.push('foo', this.onFooInit.bind(this));
    },

    onFooInit: function() {
        this.$fooButton
            .on('click', function(){ alert('bar') })
            .prop('disabled', false)
            .html('Foo ready!');
    }

};
<commit_msg>onFooInit -> onFooReady (better illustrates the point)<commit_after>
var app = {

    initialize: function($root) {
        $root.html([
            '
',
                'Dependencies are loaded, app is initialized, we\'re safe to start...',
            '
'
        ].join(""));

        this.$fooButton = $([
            '<button disabled>',
                '...in the meantime we\'re still waiting for Foo',
            '</button>'
        ].join(""))
            .appendTo($root);

        // this is critical to our foo example
        appCallbackStack.push('foo', this.onFooReady.bind(this));
    },

    onFooReady: function() {
        this.$fooButton
            .on('click', function(){ alert('bar') })
            .prop('disabled', false)
            .html('Foo ready!');
    }

};
<|endoftext|>


<commit_before>import { readFileSync, statSync } from 'fs';
import { resolve } from 'path';

import test from 'ava';
import webpack from 'webpack';

test('basic usage', async t => {
	await new Promise((resolve, reject) => {
		webpack({
			entry: resolve(__dirname, 'src/main.js'),
			bail: true,
			output: {
				path: resolve(__dirname, 'dist'),
				filename: 'main.bundle.js'
			},
			module: {
				loaders: [
					{ test: /\.entry\.js$/, loader: resolve(__dirname, '../index.js'), query: { name: '[name].spawned.js' } }
				]
			}
		}, (err, stats) => {
			err ? reject(err) : resolve(stats);
		});
	});

	t.ok(statSync(resolve(__dirname, 'dist/main.bundle.js')), 'main bundle exists');
	t.ok(statSync(resolve(__dirname, 'dist/other.entry.spawned.js')), 'second entry bundle exists');
});

test.after(t => {
	rimraf(resolve(__dirname, 'dist'));
});
<commit_msg>basic tests for existence of output chunks and the prelude in the spawned entry chunk<commit_after>import { readFileSync, statSync } from 'fs';
import { join } from 'path';

import test from 'ava';
import webpack from 'webpack';
import rimraf from 'rimraf';

test('basic usage', async t => {
	await new Promise((resolve, reject) => {
		webpack({
			entry: join(__dirname, 'src/main.js'),
			bail: true,
			output: {
				path: join(__dirname, 'dist'),
				filename: 'main.bundle.js'
			},
			module: {
				loaders: [
					{ test: /\.entry\.js$/, loader: join(__dirname, '../index.js'), query: { name: '[name].spawned.js' } }
				]
			}
		}, (err, stats) => {
			err ? reject(err) : resolve(stats);
		});
	});

	t.ok(statSync(join(__dirname, 'dist/main.bundle.js')), 'main bundle exists');
	t.ok(statSync(join(__dirname, 'dist/other.entry.spawned.js')), 'second entry bundle exists');

	t.regex(readFileSync(join(__dirname, 'dist/main.bundle.js')), /"other\.entry\.spawned\.js"/, 'references spawned module');
	t.regex(readFileSync(join(__dirname, 'dist/other.entry.spawned.js')), /\bfunction __webpack_require__\b/, 'has prelude');
});

test.after(t => {
	rimraf.sync(join(__dirname, 'dist'));
});
<|endoftext|>


<commit_before>'use strict';

var vc;

module.exports = function(v4) {
    v4.version = 4;
    vc = v4.constants;
    v4.layers.forEach(convertLayer);
    return v4;
};

function convertLayer(layer) {
    // convert linear/exponential functions to stop functions
    // decrement zoom level of functions by 1 for map tileSize (512) change
    for (var classname in layer) {
        if (layer[classname]['text-max-angle']) {
            layer[classname]['text-max-angle'] = Number((layer[classname]['text-max-angle'] * 180 / Math.PI).toFixed(2));
        }
        if (classname.indexOf('style') === -1) continue;
        var style = layer[classname];
        for (var propname in style) {
            if (!style[propname].fn) continue;
            var oldfn = style[propname];
            var newfn;
            if (oldfn.fn === 'stops') {
                newfn = { stops: oldfn.stops };
            // @TODO convert linear/exponential functions into stops functions.
            } else if (oldfn.fn === 'linear') {
                newfn = { stops: [] };
            } else if (oldfn.fn === 'exponential') {
                newfn = { stops: [] };
            }
            // Decrement zoom levels by 1.
            newfn.stops = newfn.stops.map(deczoom);
            style[propname] = newfn;
        }
    }

    function deczoom(pair) {
        return [Math.max(0, pair[0] - 1), pair[1]];
    }
}
<commit_msg>add function migration<commit_after>'use strict';

var vc;

module.exports = function(v4) {
    v4.version = 4;
    vc = v4.constants;
    v4.layers.forEach(convertLayer);
    return v4;
};

function convertLayer(layer) {
    // convert linear/exponential functions to stop functions
    // decrement zoom level of functions by 1 for map tileSize (512) change
    for (var classname in layer) {
        if (layer[classname]['text-max-angle']) {
            layer[classname]['text-max-angle'] = Number((layer[classname]['text-max-angle'] * 180 / Math.PI).toFixed(2));
        }
        if (classname.indexOf('style') === -1) continue;
        var style = layer[classname];
        for (var propname in style) {
            if (!style[propname].fn) continue;
            var oldfn = style[propname];
            var newfn;
            if (oldfn.fn === 'stops') {
                newfn = { stops: oldfn.stops };
            } else if (oldfn.fn === 'linear' || oldfn.fn === 'exponential') {
                newfn = migrateFn(oldfn);
            }
            // Decrement zoom levels by 1.
            newfn.stops = newfn.stops.map(deczoom);
            style[propname] = newfn;
        }
    }

    if (layer.layers) layer.layers.forEach(convertLayer);

    function deczoom(pair) {
        return [Math.max(0, pair[0] - 1), pair[1]];
    }
}

function migrateFn(params) {
    var newparams = {};
    var minZoom = 0;
    var maxZoom = 20;
    var fn;
    if (params.fn === 'exponential') {
        fn = exponential(params);
        if (params.base) newparams.base = params.base;
        if (params.min !== undefined) minZoom = reverseExponential(params, Math.max(params.min, params.val));
        if (params.max !== undefined) maxZoom = reverseExponential(params, params.max);
        newparams.stops = [
            [minZoom, fn(minZoom)],
            [maxZoom, fn(maxZoom)]
        ];
    } else if (params.fn === 'linear') {
        fn = linear(params);
        newparams.base = 1.01;
        if (params.min !== undefined) minZoom = reverseLinear(params, params.min);
        if (params.max !== undefined) maxZoom = reverseLinear(params, params.max);
        newparams.stops = [
            [minZoom, fn(minZoom)],
            [maxZoom, fn(maxZoom)]
        ];
    }

    return newparams;
}

function reverseExponential(params, value) {
    var z_base = +params.z || 0,
        val = +params.val || 0,
        slope = +params.slope || 0,
        base = +params.base || 1.75;
    return Math.log(((value - val) || 0.01) / slope) / Math.log(base) + z_base;
}

function reverseLinear(params, value) {
    var z_base = +params.z || 0,
        val = +params.val || 0,
        slope = +params.slope || 0;
    return (value - val) / slope + z_base;
}

function linear(params) {
    var z_base = +params.z || 0,
        val = +params.val || 0,
        slope = +params.slope || 0,
        min = +params.min || 0,
        max = +params.max || Infinity;
    return function(z) {
        return Math.min(Math.max(min, val + (z - z_base) * slope), max);
    };
}

function exponential(params) {
    var z_base = +params.z || 0,
        val = +params.val || 0,
        slope = +params.slope || 0,
        min = +params.min || 0,
        max = +params.max || Infinity,
        base = +params.base || 1.75;
    return function(z) {
        return Math.min(Math.max(min, val + Math.pow(base, (z - z_base)) * slope), max);
    };
}
<|endoftext|>


<commit_before>/**
 * 设置 url 的 query 中参数的键值
 * @param {String} key   query 中的键
 * @param {String} value query 中的值
 * @param {String} url   url 字符串，默认 location.href
 */
export function setParam(key, value, url = location.href) {
  let reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
  let result = reg.exec(url);
  if (result) {
    return url.replace(result[0], `${key}=${value}`);
  } else {
    reg = /\?(.*)#?(.*)/gi;
    let search = reg.exec(url);
    if (search !== null) {
      return url.replace(search[1], `${search[1]}&${key}=${value}`);
    } else {
      return '';
    }
  }
}

/**
 * 获取 url 的 query 中参数 key 的值
 * @param  {String} key query 中的键
 * @param  {String} url url 字符串，默认 location.href
 * @return {String}     key 对应的值
 */
export function getParam(key, url = location.href) {
  let reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
  let result = reg.exec(url);
  return result ? result[2] : ''
}

/**
 * html 转义，预防 xss
 * @param  {String} htm htm 字符串
 * @return {String}     转义后的字符串
 */
function encodeHTML (htm) {
  return String(htm)
    .replace(/&/g, "&")
    .replace(/</g, "<")
    .replace(/>/g, ">")
    .replace(/"/g, """)
    .replace(/'/g, "'");
}

export function isAndroid() {
  return window.navigator.userAgent.indexOf('Android') > -1 || window.navigator.userAgent.indexOf('Adr') > -1;
}

export function isIOS() {
  return !!window.navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
}

export function isWechat() {
  return navigator.userAgent.indexOf('MicroMessenger') > -1;
}

export function isMobile() {
  return !!navigator.userAgent.match(/AppleWebKit.*Mobile.*/);
}

export const Cookie = {
  get(key) {
    var arr,
      reg = new RegExp("(^| )" + key + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg)) {
      return unescape(arr[2]);
    } else {
      return null;
    }
  },
  set(name, value, hour, domain) {
    var domain = domain ? domain : document.location.host;
    if (hour) {
      var expireDate = new Date(new Date().getTime() + hour * 3600 * 1000);
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain + "; expires=" + expireDate.toGMTString();
    } else {
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain;
    }
  },
  delete(name) {
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval = this.get(name);
    if (cval != null) {
      document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
    }
  },
  clear() {
    var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
    if (keys) {
      for (var i = keys.length; i--;) {
        document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
      }
    }
  }
};

/**
 * 获取元素的实际样式
 * @param  {String} $e   元素的 DOM
 * @param  {String} name 样式键名
 * @return {String}      样式值
 */
export function getRealStyle($e, name) {
  return window.getComputedStyle($e).getPropertyValue(name);
}

/**
* 将数字千分化
* 到万的显示'xxxx万'
* 到亿的显示'xxxx亿'
* 到万亿的显示'xxxx万亿'
*/
export function formatCoin(num, digits = 2) {
  digits = Math.pow(10, digits) // 保留小数位数

  // 千分化
  function toThousands(num) {
    let itg = parseInt(num) // 取整数部分
    let itg_length = itg.toString().length
    let length = num.toString().length
    let dec = num.toString().slice(itg_length, length) // 取小数部分
    // 整数部分千分，小数部分保留2位附加
    return (itg || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') + (parseInt(dec * digits) / digits).toString().slice(1);
  }

  num = parseFloat(num)
  if (isNaN(num)) {
    throw new TypeError('parameter must be a number')
  }
  if (num < 1e4) {
    return toThousands(num)
  } else if (num >= 1e4 && num < 1e8) {
    return toThousands(num / 1e4) + '万'
  } else if (num >= 1e8 && num < 1e12) {
    return toThousands(num / 1e8) + '亿'
  } else {
    return toThousands(num / 1e12) + '万亿'
  }
}

/**
 * 字符编码数值对应的存储长度：
 * UCS-2编码(16进制) UTF-8 字节流(二进制)
 * 0000 - 007F       0xxxxxxx （1字节）
 * 0080 - 07FF       110xxxxx 10xxxxxx （2字节）
 * 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx （3字节）
 */
export function getBytesLength: function(string) {
  var totalLength = 0;
  var charCode;
  for (var i = 0; i < string.length; i++) {
    charCode = string.charCodeAt(i);
    if (charCode < 0x007f) {
      totalLength++;
    } else if ((0x0080 <= charCode) && (charCode <= 0x07ff)) {
      totalLength += 2;
    } else if ((0x0800 <= charCode) && (charCode <= 0xffff)) {
      totalLength += 3;
    } else {
      totalLength += 4;
    }
  }
  return totalLength;
}

/**
 * 倒计时
 * @param  {Number}   seconds  倒计时时间
 * @param  {Function} callback(times) 倒计时的 loop
 * @param  {times}  day   倒计时的天数
 * @param  {times}  hour  倒计时的小时数
 * @param  {times}  min   倒计时的分钟数
 * @param  {times}  sec   倒计时的秒数
 */
export function countdown(seconds, callback) {
  var timer
  // fix floating seconds
  seconds = Math.round(seconds)

  function prefix(n) {
    return n > 9 ? `${n}` : `0${n}`
  }

  function format(seconds) {
    let day = 0
    let hour = 0
    let min = 0
    let sec = 0
    let Day = 24 * 60 * 60
    let Hour = 60 * 60
    let Min = 60
    if (seconds > Day) {
      day = Math.floor(seconds / Day)
      seconds = seconds % Day
    }
    hour = Math.floor(seconds / Hour)
    seconds = seconds % Hour
    min = Math.floor(seconds / Min)
    sec = seconds % Min
    return { day: prefix(day), hour: prefix(hour), min: prefix(min), sec: prefix(sec) }
  }

  function down() {
    seconds--;
    callback(format(seconds))
    !seconds && clearInterval(timer)
  }
  if (seconds > 0) {
    timer = setInterval(down, 1000)
    down()
  } else {
    callback(format(0))
  }
}

// unicode & 汉字 转换
export const converter = {
  ToUnicode: function(str) {
    return escape(str).toLocaleLowerCase().replace(/%u/gi, '\\u');
  },
  ToGB2312: function(str) {
    return unescape(str.replace(/\\u/gi, '%u'));
  }
};

/**
 * 常用语手机号转星，身份证号转星
 * 前 start 位，后 end 位中间的字符串，替换为'*'
 * @param  {String} [string=''] 字符串
 * @param  {Number} [start=0]   不需要被替换的位数，从前开始计算
 * @param  {Number} [end=0]     不需要被替换的位数，从后开始计算
 * @return {String}             替换后的字符串
 */
export function string2star(string = '', start = 0, end = 0) {
  if (!string) {
    return '';
  }
  if (start + end > string.length) {
    throw new Error('字符串长度小于start和end之和，请检查参数。')
  }
  let matches = string.match(new RegExp('^(.{' + start + '})(.*)(.{' + end + '})$'))
  let middle = matches[2].replace(/./g, s => '*')
  let ret = matches[1] + middle + matches[3]
  return `${matches[1]}${middle}${matches[3]}`
}

export function isMobileDevice() {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
        navigator.userAgent
    )
}

export function isMac() {
  return navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i)
}

// 获取今天剩余时间
export function todayLeft() {
    var tomarrow = new Date(new Date().getTime() + 3600 * 24 * 1000).toDateString()
    return new Date(tomarrow).getTime() - new Date().getTime()
}
<commit_msg>add isElementInViewport<commit_after>/**
 * 设置 url 的 query 中参数的键值
 * @param {String} key   query 中的键
 * @param {String} value query 中的值
 * @param {String} url   url 字符串，默认 location.href
 */
export function setParam(key, value, url = location.href) {
  let reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
  let result = reg.exec(url);
  if (result) {
    return url.replace(result[0], `${key}=${value}`);
  } else {
    reg = /\?(.*)#?(.*)/gi;
    let search = reg.exec(url);
    if (search !== null) {
      return url.replace(search[1], `${search[1]}&${key}=${value}`);
    } else {
      return '';
    }
  }
}

/**
 * 获取 url 的 query 中参数 key 的值
 * @param  {String} key query 中的键
 * @param  {String} url url 字符串，默认 location.href
 * @return {String}     key 对应的值
 */
export function getParam(key, url = location.href) {
  let reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
  let result = reg.exec(url);
  return result ? result[2] : ''
}

/**
 * html 转义，预防 xss
 * @param  {String} htm htm 字符串
 * @return {String}     转义后的字符串
 */
function encodeHTML (htm) {
  return String(htm)
    .replace(/&/g, "&")
    .replace(/</g, "<")
    .replace(/>/g, ">")
    .replace(/"/g, """)
    .replace(/'/g, "'");
}

export function isAndroid() {
  return window.navigator.userAgent.indexOf('Android') > -1 || window.navigator.userAgent.indexOf('Adr') > -1;
}

export function isIOS() {
  return !!window.navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
}

export function isWechat() {
  return navigator.userAgent.indexOf('MicroMessenger') > -1;
}

export function isMobile() {
  return !!navigator.userAgent.match(/AppleWebKit.*Mobile.*/);
}

export const Cookie = {
  get(key) {
    var arr,
      reg = new RegExp("(^| )" + key + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg)) {
      return unescape(arr[2]);
    } else {
      return null;
    }
  },
  set(name, value, hour, domain) {
    var domain = domain ? domain : document.location.host;
    if (hour) {
      var expireDate = new Date(new Date().getTime() + hour * 3600 * 1000);
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain + "; expires=" + expireDate.toGMTString();
    } else {
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain;
    }
  },
  delete(name) {
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval = this.get(name);
    if (cval != null) {
      document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
    }
  },
  clear() {
    var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
    if (keys) {
      for (var i = keys.length; i--;) {
        document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
      }
    }
  }
};

/**
 * 获取元素的实际样式
 * @param  {String} $e   元素的 DOM
 * @param  {String} name 样式键名
 * @return {String}      样式值
 */
export function getRealStyle($e, name) {
  return window.getComputedStyle($e).getPropertyValue(name);
}

/**
* 将数字千分化
* 到万的显示'xxxx万'
* 到亿的显示'xxxx亿'
* 到万亿的显示'xxxx万亿'
*/
export function formatCoin(num, digits = 2) {
  digits = Math.pow(10, digits) // 保留小数位数

  // 千分化
  function toThousands(num) {
    let itg = parseInt(num) // 取整数部分
    let itg_length = itg.toString().length
    let length = num.toString().length
    let dec = num.toString().slice(itg_length, length) // 取小数部分
    // 整数部分千分，小数部分保留2位附加
    return (itg || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') + (parseInt(dec * digits) / digits).toString().slice(1);
  }

  num = parseFloat(num)
  if (isNaN(num)) {
    throw new TypeError('parameter must be a number')
  }
  if (num < 1e4) {
    return toThousands(num)
  } else if (num >= 1e4 && num < 1e8) {
    return toThousands(num / 1e4) + '万'
  } else if (num >= 1e8 && num < 1e12) {
    return toThousands(num / 1e8) + '亿'
  } else {
    return toThousands(num / 1e12) + '万亿'
  }
}

/**
 * 字符编码数值对应的存储长度：
 * UCS-2编码(16进制) UTF-8 字节流(二进制)
 * 0000 - 007F       0xxxxxxx （1字节）
 * 0080 - 07FF       110xxxxx 10xxxxxx （2字节）
 * 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx （3字节）
 */
export function getBytesLength: function(string) {
  var totalLength = 0;
  var charCode;
  for (var i = 0; i < string.length; i++) {
    charCode = string.charCodeAt(i);
    if (charCode < 0x007f) {
      totalLength++;
    } else if ((0x0080 <= charCode) && (charCode <= 0x07ff)) {
      totalLength += 2;
    } else if ((0x0800 <= charCode) && (charCode <= 0xffff)) {
      totalLength += 3;
    } else {
      totalLength += 4;
    }
  }
  return totalLength;
}

/**
 * 倒计时
 * @param  {Number}   seconds  倒计时时间
 * @param  {Function} callback(times) 倒计时的 loop
 * @param  {times}  day   倒计时的天数
 * @param  {times}  hour  倒计时的小时数
 * @param  {times}  min   倒计时的分钟数
 * @param  {times}  sec   倒计时的秒数
 */
export function countdown(seconds, callback) {
  var timer
  // fix floating seconds
  seconds = Math.round(seconds)

  function prefix(n) {
    return n > 9 ? `${n}` : `0${n}`
  }

  function format(seconds) {
    let day = 0
    let hour = 0
    let min = 0
    let sec = 0
    let Day = 24 * 60 * 60
    let Hour = 60 * 60
    let Min = 60
    if (seconds > Day) {
      day = Math.floor(seconds / Day)
      seconds = seconds % Day
    }
    hour = Math.floor(seconds / Hour)
    seconds = seconds % Hour
    min = Math.floor(seconds / Min)
    sec = seconds % Min
    return { day: prefix(day), hour: prefix(hour), min: prefix(min), sec: prefix(sec) }
  }

  function down() {
    seconds--;
    callback(format(seconds))
    !seconds && clearInterval(timer)
  }
  if (seconds > 0) {
    timer = setInterval(down, 1000)
    down()
  } else {
    callback(format(0))
  }
}

// unicode & 汉字 转换
export const converter = {
  ToUnicode: function(str) {
    return escape(str).toLocaleLowerCase().replace(/%u/gi, '\\u');
  },
  ToGB2312: function(str) {
    return unescape(str.replace(/\\u/gi, '%u'));
  }
};

/**
 * 常用语手机号转星，身份证号转星
 * 前 start 位，后 end 位中间的字符串，替换为'*'
 * @param  {String} [string=''] 字符串
 * @param  {Number} [start=0]   不需要被替换的位数，从前开始计算
 * @param  {Number} [end=0]     不需要被替换的位数，从后开始计算
 * @return {String}             替换后的字符串
 */
export function string2star(string = '', start = 0, end = 0) {
  if (!string) {
    return '';
  }
  if (start + end > string.length) {
    throw new Error('字符串长度小于start和end之和，请检查参数。')
  }
  let matches = string.match(new RegExp('^(.{' + start + '})(.*)(.{' + end + '})$'))
  let middle = matches[2].replace(/./g, s => '*')
  let ret = matches[1] + middle + matches[3]
  return `${matches[1]}${middle}${matches[3]}`
}

export function isMobileDevice() {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
        navigator.userAgent
    )
}

export function isMac() {
  return navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i)
}

// 获取今天剩余时间
export function todayLeft() {
    var tomarrow = new Date(new Date().getTime() + 3600 * 24 * 1000).toDateString()
    return new Date(tomarrow).getTime() - new Date().getTime()
}

// https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
export function isElementInViewport (el) {
    var rect = el.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
    );
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var Emitter = require('events').EventEmitter
  , path = require('path')
  , dirname = path.dirname
  , basename = path.basename
  , extname = path.extname
  , join = path.join
  , mkdir = require('mkdirp').mkdirp
  , request = require('superagent')
  , debug = require('debug')('component:installer')
  , Batch = require('batch')
  , http = require('http')
  , url = require('url')
  , fs = require('fs');

/**
 * In-flight requests.
 */

var inFlight = {};

/**
 * Expose installer.
 */

module.exports = Package;

/**
 * Initialize a new `Package` with
 * the given `pkg` name and `version`.
 *
 * Options:
 *
 *  - `dest` destination directory
 *  - `force` installation when previously installed
 *  - `remote` remote url defaulting to "https://raw.github.com"
 *
 * @param {String} pkg
 * @param {String} version
 * @param {Object} options
 * @api private
 */

function Package(pkg, version, options) {
  options = options || {};
  if ('*' == version) version = 'master';
  debug('installing %s@%s %j', pkg, version, options);
  if (!pkg) throw new Error('pkg required');
  if (!version) throw new Error('version required');
  this.name = pkg;
  this.slug = pkg + '@' + version;
  this.dest = options.dest || 'components';
  this.remotes = options.remotes || ['https://raw.github.com'];
  this.auth = options.auth;
  this.force = !! options.force;
  this.version = version;
  if (inFlight[this.slug]) this.install = function(){};
  inFlight[this.slug] = true;
}

/**
 * Inherit from `Emitter.prototype`.
 */

Package.prototype.__proto__ = Emitter.prototype;

/**
 * Return dirname for this package.
 * For example "component/dialog"
 * becomes "component-dialog".
 *
 * @return {String}
 * @api private
 */

Package.prototype.dirname = function(){
  return join(this.dest, this.name.split('/').join('-'));
};

/**
 * Join `path` to this package's dirname.
 *
 * @param {String} path
 * @return {String}
 * @api private
 */

Package.prototype.join = function(path){
  return join(this.dirname(), path);
};

/**
 * Return URL to `file`.
 *
 * @param {String} file
 * @return {String}
 * @api private
 */

Package.prototype.url = function(file){
  return this.remote.href + '/' + this.name + '/' + this.version + '/' + file;
};

/**
 * Conditionaly mkdir `dir` unless we've
 * already done so previously.
 *
 * @param {String} dir
 * @param {Function} fn
 * @api private
 */

Package.prototype.mkdir = function(dir, fn){
  this.dirs = this.dirs || {};
  if (this.dirs[dir]) return fn();
  mkdir(dir, fn);
};

/**
 * Get local json if the component is installed
 * and callback `fn(err, obj)`.
 *
 * @param {Function} fn
 * @api private
 */

Package.prototype.getLocalJSON = function(fn){
  var path = this.join('component.json');
  fs.readFile(path, 'utf8', function(err, json){
    if (err) return fn(err);
    try {
      json = JSON.parse(json);
    } catch (err) {
      err.message += ' in ' + path;
      return fn(err);
    }
    fn(null, json);
  });
};

/**
 * Get component.json and callback `fn(err, obj)`.
 *
 * @param {Function} fn
 * @api private
 */

Package.prototype.getJSON = function(fn){
  var self = this;
  var url = this.url('component.json');

  debug('fetching %s', url);
  var req = request.get(url);
  req.set('Accept-Encoding', 'gzip');

  req.end(function(res){
    if (res.ok) {
      debug('got %s', url);
      try {
        var json = JSON.parse(res.text);
      } catch (err) {
        err.message += ' in ' + url;
        return fn(err);
      }
      fn(null, json);
    } else {
      fn(error(res, url));
    }
  });

  req.on('error', function(err){
    if ('getaddrinfo' == err.syscall) err.message = 'dns lookup failed';
    fn(err);
  });
};

/**
 * Fetch `files` and write them to disk and callback `fn(err)`.
 *
 * @param {Array} files
 * @param {Function} fn
 * @api private
 */

Package.prototype.getFiles = function(files, fn){
  var self = this;
  var batch = new Batch;

  files.forEach(function(file){
    batch.push(function(done){
      var url = self.url(file);
      debug('fetching %s', url);
      self.emit('file', file, url);
      var dst = self.join(file);

      // mkdir
      self.mkdir(dirname(dst), function(err){
        if (err) return fn(err);

        // pipe file
        var req = request.get(url);
        req.set('Accept-Encoding', 'gzip');
        req.buffer(false);

        if (self.auth) req.auth(self.auth.user, self.auth.pass);

        req.end(function(res){
          if (res.error) return done(error(res, url));
          res.pipe(fs.createWriteStream(dst));
          res.on('error', done);
          res.on('end', done);
        });
      });
    });
  });

  batch.end(fn);
};

/**
 * Write `file` with `str` contents to disk and callback `fn(err)`.
 *
 * @param {String} file
 * @param {String} str
 * @param {Function} fn
 * @api private
 */

Package.prototype.writeFile = function(file, str, fn){
  file = this.join(file);
  debug('write %s', file);
  fs.writeFile(file, str, fn);
};

/**
 * Install `deps` and callback `fn()`.
 *
 * @param {Array} deps
 * @param {Function} fn
 * @api private
 */

Package.prototype.getDependencies = function(deps, fn){
  var self = this;
  var batch = new Batch;

  Object.keys(deps).forEach(function(name){
    var version = deps[name];
    debug('dep %s@%s', name, version);
    batch.push(function(done){
      var pkg = new Package(name, version, {
        dest: self.dest,
        force: self.force,
        remotes: self.remotes
      });
      self.emit('dep', pkg);
      pkg.on('end', done);
      pkg.on('exists', function() { done(); });
      pkg.install();
    });
  });

  batch.end(fn);
};

/**
 * Check if the component exists already,
 * otherwise install it for realllll.
 *
 * @api public
 */

Package.prototype.install = function(){
  var self = this;
  var name = this.name;

  if (!~name.indexOf('/')) {
    return this.emit('error', new Error('invalid component name "' + name + '"'));
  }

  this.getLocalJSON(function(err, json){
    if (err && err.code == 'ENOENT') {
      self.reallyInstall();
    } else if (err) {
      self.emit('error', err);
    } else if (!self.force) {
      self.emit('exists', self);
    } else {
      self.reallyInstall();
    }
  });
};

/**
 * Really install the component.
 *
 * @api public
 */

Package.prototype.reallyInstall = function(){
  var self = this;
  var i = 0;
  var batch;
  var last;

  next();

  function next() {
    self.remote = self.remotes[i++];
    if (!self.remote) return self.emit('error', new Error('can\'t find remote for "' + self.name + '"'));

    // parse remote
    last = i == self.remotes.length - 1;
    self.remote = url.parse(self.remote);

    // strip trailing /
    self.remote.href = self.remote.href.slice(0, -1);

    // only error on the last remote otherwise
    // we assume it may be fetchable
    self.once('error', next);

    // kick off installation
    batch = new Batch;
    self.getJSON(function(err, json){
      if (err) {
        err.fatal = !last;
        return self.emit('error', err);
      }

      var files = [];
      if (json.scripts) files = files.concat(json.scripts);
      if (json.styles) files = files.concat(json.styles);
      if (json.templates) files = files.concat(json.templates);
      if (json.files) files = files.concat(json.files);
      if (json.images) files = files.concat(json.images);
      if (json.fonts) files = files.concat(json.fonts);
      json.repo = json.repo || self.remote.href + '/' + self.name;

      if (json.dependencies) {
        batch.push(function(done){
          self.getDependencies(json.dependencies, done);
        });
      }

      batch.push(function(done){
        self.mkdir(self.dirname(), function(err){
          json = JSON.stringify(json, null, 2);
          self.writeFile('component.json', json, done);
        });
      });

      batch.push(function(done){
        self.mkdir(self.dirname(), function(err){
          self.getFiles(files, done);
        });
      });

      batch.end(function(err){
        if (err) {
          err.fatal = !last;
          return self.emit('error', err);
        }
        self.emit('end');
      });
    });
  }
};

/**
 * Return an error for `res` / `url`.
 *
 * @param {Response} res
 * @param {String} url
 * @return {Error}
 * @api private
 */

function error(res, url) {
  var name = http.STATUS_CODES[res.status];
  var err = new Error('failed to fetch ' + url + ', got ' + res.status + ' "' + name + '"');
  err.status = res.status;
  return err;
}
<commit_msg>inFlight components do not emit `end` events<commit_after>
/**
 * Module dependencies.
 */

var Emitter = require('events').EventEmitter
  , path = require('path')
  , dirname = path.dirname
  , basename = path.basename
  , extname = path.extname
  , join = path.join
  , mkdir = require('mkdirp').mkdirp
  , request = require('superagent')
  , debug = require('debug')('component:installer')
  , Batch = require('batch')
  , http = require('http')
  , url = require('url')
  , fs = require('fs');

/**
 * In-flight requests.
 */

var inFlight = {};

/**
 * Expose installer.
 */

module.exports = Package;

/**
 * Initialize a new `Package` with
 * the given `pkg` name and `version`.
 *
 * Options:
 *
 *  - `dest` destination directory
 *  - `force` installation when previously installed
 *  - `remote` remote url defaulting to "https://raw.github.com"
 *
 * @param {String} pkg
 * @param {String} version
 * @param {Object} options
 * @api private
 */

function Package(pkg, version, options) {
  options = options || {};
  if ('*' == version) version = 'master';
  debug('installing %s@%s %j', pkg, version, options);
  if (!pkg) throw new Error('pkg required');
  if (!version) throw new Error('version required');
  this.name = pkg;
  this.slug = pkg + '@' + version;
  this.dest = options.dest || 'components';
  this.remotes = options.remotes || ['https://raw.github.com'];
  this.auth = options.auth;
  this.force = !! options.force;
  this.version = version;
  if (inFlight[this.slug]) this.install = function(){
    this.emit('end');
  };
  inFlight[this.slug] = true;
}

/**
 * Inherit from `Emitter.prototype`.
 */

Package.prototype.__proto__ = Emitter.prototype;

/**
 * Return dirname for this package.
 * For example "component/dialog"
 * becomes "component-dialog".
 *
 * @return {String}
 * @api private
 */

Package.prototype.dirname = function(){
  return join(this.dest, this.name.split('/').join('-'));
};

/**
 * Join `path` to this package's dirname.
 *
 * @param {String} path
 * @return {String}
 * @api private
 */

Package.prototype.join = function(path){
  return join(this.dirname(), path);
};

/**
 * Return URL to `file`.
 *
 * @param {String} file
 * @return {String}
 * @api private
 */

Package.prototype.url = function(file){
  return this.remote.href + '/' + this.name + '/' + this.version + '/' + file;
};

/**
 * Conditionaly mkdir `dir` unless we've
 * already done so previously.
 *
 * @param {String} dir
 * @param {Function} fn
 * @api private
 */

Package.prototype.mkdir = function(dir, fn){
  this.dirs = this.dirs || {};
  if (this.dirs[dir]) return fn();
  mkdir(dir, fn);
};

/**
 * Get local json if the component is installed
 * and callback `fn(err, obj)`.
 *
 * @param {Function} fn
 * @api private
 */

Package.prototype.getLocalJSON = function(fn){
  var path = this.join('component.json');
  fs.readFile(path, 'utf8', function(err, json){
    if (err) return fn(err);
    try {
      json = JSON.parse(json);
    } catch (err) {
      err.message += ' in ' + path;
      return fn(err);
    }
    fn(null, json);
  });
};

/**
 * Get component.json and callback `fn(err, obj)`.
 *
 * @param {Function} fn
 * @api private
 */

Package.prototype.getJSON = function(fn){
  var self = this;
  var url = this.url('component.json');

  debug('fetching %s', url);
  var req = request.get(url);
  req.set('Accept-Encoding', 'gzip');

  req.end(function(res){
    if (res.ok) {
      debug('got %s', url);
      try {
        var json = JSON.parse(res.text);
      } catch (err) {
        err.message += ' in ' + url;
        return fn(err);
      }
      fn(null, json);
    } else {
      fn(error(res, url));
    }
  });

  req.on('error', function(err){
    if ('getaddrinfo' == err.syscall) err.message = 'dns lookup failed';
    fn(err);
  });
};

/**
 * Fetch `files` and write them to disk and callback `fn(err)`.
 *
 * @param {Array} files
 * @param {Function} fn
 * @api private
 */

Package.prototype.getFiles = function(files, fn){
  var self = this;
  var batch = new Batch;

  files.forEach(function(file){
    batch.push(function(done){
      var url = self.url(file);
      debug('fetching %s', url);
      self.emit('file', file, url);
      var dst = self.join(file);

      // mkdir
      self.mkdir(dirname(dst), function(err){
        if (err) return fn(err);

        // pipe file
        var req = request.get(url);
        req.set('Accept-Encoding', 'gzip');
        req.buffer(false);

        if (self.auth) req.auth(self.auth.user, self.auth.pass);

        req.end(function(res){
          if (res.error) return done(error(res, url));
          res.pipe(fs.createWriteStream(dst));
          res.on('error', done);
          res.on('end', done);
        });
      });
    });
  });

  batch.end(fn);
};

/**
 * Write `file` with `str` contents to disk and callback `fn(err)`.
 *
 * @param {String} file
 * @param {String} str
 * @param {Function} fn
 * @api private
 */

Package.prototype.writeFile = function(file, str, fn){
  file = this.join(file);
  debug('write %s', file);
  fs.writeFile(file, str, fn);
};

/**
 * Install `deps` and callback `fn()`.
 *
 * @param {Array} deps
 * @param {Function} fn
 * @api private
 */

Package.prototype.getDependencies = function(deps, fn){
  var self = this;
  var batch = new Batch;

  Object.keys(deps).forEach(function(name){
    var version = deps[name];
    debug('dep %s@%s', name, version);
    batch.push(function(done){
      var pkg = new Package(name, version, {
        dest: self.dest,
        force: self.force,
        remotes: self.remotes
      });
      self.emit('dep', pkg);
      pkg.on('end', done);
      pkg.on('exists', function() { done(); });
      pkg.install();
    });
  });

  batch.end(fn);
};

/**
 * Check if the component exists already,
 * otherwise install it for realllll.
 *
 * @api public
 */

Package.prototype.install = function(){
  var self = this;
  var name = this.name;

  if (!~name.indexOf('/')) {
    return this.emit('error', new Error('invalid component name "' + name + '"'));
  }

  this.getLocalJSON(function(err, json){
    if (err && err.code == 'ENOENT') {
      self.reallyInstall();
    } else if (err) {
      self.emit('error', err);
    } else if (!self.force) {
      self.emit('exists', self);
    } else {
      self.reallyInstall();
    }
  });
};

/**
 * Really install the component.
 *
 * @api public
 */

Package.prototype.reallyInstall = function(){
  var self = this;
  var i = 0;
  var batch;
  var last;

  next();

  function next() {
    self.remote = self.remotes[i++];
    if (!self.remote) return self.emit('error', new Error('can\'t find remote for "' + self.name + '"'));

    // parse remote
    last = i == self.remotes.length - 1;
    self.remote = url.parse(self.remote);

    // strip trailing /
    self.remote.href = self.remote.href.slice(0, -1);

    // only error on the last remote otherwise
    // we assume it may be fetchable
    self.once('error', next);

    // kick off installation
    batch = new Batch;
    self.getJSON(function(err, json){
      if (err) {
        err.fatal = !last;
        return self.emit('error', err);
      }

      var files = [];
      if (json.scripts) files = files.concat(json.scripts);
      if (json.styles) files = files.concat(json.styles);
      if (json.templates) files = files.concat(json.templates);
      if (json.files) files = files.concat(json.files);
      if (json.images) files = files.concat(json.images);
      if (json.fonts) files = files.concat(json.fonts);
      json.repo = json.repo || self.remote.href + '/' + self.name;

      if (json.dependencies) {
        batch.push(function(done){
          self.getDependencies(json.dependencies, done);
        });
      }

      batch.push(function(done){
        self.mkdir(self.dirname(), function(err){
          json = JSON.stringify(json, null, 2);
          self.writeFile('component.json', json, done);
        });
      });

      batch.push(function(done){
        self.mkdir(self.dirname(), function(err){
          self.getFiles(files, done);
        });
      });

      batch.end(function(err){
        if (err) {
          err.fatal = !last;
          return self.emit('error', err);
        }
        self.emit('end');
      });
    });
  }
};

/**
 * Return an error for `res` / `url`.
 *
 * @param {Response} res
 * @param {String} url
 * @return {Error}
 * @api private
 */

function error(res, url) {
  var name = http.STATUS_CODES[res.status];
  var err = new Error('failed to fetch ' + url + ', got ' + res.status + ' "' + name + '"');
  err.status = res.status;
  return err;
}
<|endoftext|>


<commit_before>import styled from 'styled-components'

import Icon from '../narrative/icon'
import SaveTripButton from './save-trip-button'

const IssueButton = styled.button`
  background-color: #ECBE03;
  border: none;
  border-radius: 5px;
  display: inline-block;
  font-size: 12px;
  padding: 4px;

  span {
    margin-left: 4px;
  }
`

export default function NarrativeItinerariesHeader ({
  errors,
  itineraries,
  itineraryIsExpanded,
  onSortChange,
  onSortDirChange,
  onToggleShowErrors,
  onViewAllOptions,
  pending,
  showingErrors,
  sort
}) {
  let resultText, titleText
  if (pending) {
    resultText = 'Finding your options...'
    titleText = 'Finding your options...'
  } else {
    const itineraryPlural = itineraries.length === 1
      ? 'itinerary'
      : 'itineraries'
    const issuePlural = errors.length === 1
      ? 'issue'
      : 'issues'
    resultText = `${itineraries.length} ${itineraryPlural} found.`
    titleText = errors.length > 0
      ? `${itineraries.length} ${itineraryPlural} (and ${errors.length} ${issuePlural}) found`
      : resultText
  }

  return (

      {(itineraryIsExpanded || showingErrors)
        ? <>
          <button
            className='clear-button-formatting'
            onClick={onViewAllOptions}
          >
            <Icon type='arrow-left' /> View all options
          </button>

          {itineraryIsExpanded && <SaveTripButton />}
        </>
        : <>

              {resultText}

            {errors.length > 0 && (
              <IssueButton onClick={onToggleShowErrors}>
                <Icon type='warning' />
                {errors.length} issues
              </IssueButton>
            )}

            <button
              className='clear-button-formatting'
              onClick={onSortDirChange}
              style={{marginRight: '5px'}}
            >
              <Icon type={`sort-amount-${sort.direction.toLowerCase()}`} />
            </button>
            <select
              onBlur={onSortChange}
              onChange={onSortChange}
              value={sort.value}
            >
              <option value='BEST'>Best option</option>
              <option value='DURATION'>Duration</option>
              <option value='ARRIVALTIME'>Arrival time</option>
              <option value='DEPARTURETIME'>Departure time</option>
              <option value='WALKTIME'>Walk time</option>
              <option value='COST'>Cost</option>
            </select>

        </>
      }

  )
}
<commit_msg>refactor: improve styling in narrative itineraries header<commit_after>import styled from 'styled-components'

import Icon from '../narrative/icon'
import SaveTripButton from './save-trip-button'

const IssueButton = styled.button`
  background-color: #ECBE03;
  border: none;
  border-radius: 5px;
  display: inline-block;
  font-size: 12px;
  padding: 2px 4px;
`

export default function NarrativeItinerariesHeader ({
  errors,
  itineraries,
  itineraryIsExpanded,
  onSortChange,
  onSortDirChange,
  onToggleShowErrors,
  onViewAllOptions,
  pending,
  showingErrors,
  sort
}) {
  let resultText, titleText
  if (pending) {
    resultText = 'Finding your options...'
    titleText = 'Finding your options...'
  } else {
    const itineraryPlural = itineraries.length === 1
      ? 'itinerary'
      : 'itineraries'
    const issuePlural = errors.length === 1
      ? 'issue'
      : 'issues'
    resultText = `${itineraries.length} ${itineraryPlural} found.`
    titleText = errors.length > 0
      ? `${itineraries.length} ${itineraryPlural} (and ${errors.length} ${issuePlural}) found`
      : resultText
  }

  return (

      {(itineraryIsExpanded || showingErrors)
        ? <>
          <button
            className='clear-button-formatting'
            onClick={onViewAllOptions}
          >
            <Icon type='arrow-left' /> View all options
          </button>

          {itineraryIsExpanded && (
            // marginLeft: auto is a way of making something "float right"
            // within a flex container
            // see https://stackoverflow.com/a/36182782/269834

              <SaveTripButton />

          )}
        </>
        : <>

              {resultText}

            {errors.length > 0 && (
              <IssueButton onClick={onToggleShowErrors}>
                <Icon style={{fontSize: 11, marginRight: 2}} type='warning' />
                {errors.length} issues
              </IssueButton>
            )}

            <button
              className='clear-button-formatting'
              onClick={onSortDirChange}
              style={{marginRight: '5px'}}
            >
              <Icon type={`sort-amount-${sort.direction.toLowerCase()}`} />
            </button>
            <select
              onBlur={onSortChange}
              onChange={onSortChange}
              value={sort.value}
            >
              <option value='BEST'>Best option</option>
              <option value='DURATION'>Duration</option>
              <option value='ARRIVALTIME'>Arrival time</option>
              <option value='DEPARTURETIME'>Departure time</option>
              <option value='WALKTIME'>Walk time</option>
              <option value='COST'>Cost</option>
            </select>

        </>
      }

  )
}
<|endoftext|>


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

    var module = angular.module('app', ['ngChartist']);

    module.controller('ChartistExampleCtrl', ['$scope', '$interval',
        function($scope, $interval) {

            this.events = {
                draw: function() {
                    console.log('called');
                }
            };

            // bar chart
            this.barData = {
                labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
                series: [
                    [5, 4, 3, 7, 5, 10, 3, 4, 8, 10, 6, 8],
                    [3, 2, 9, 5, 4, 6, 4, 6, 7, 8, 7, 4]
                ]
            };

            this.barOptions = {
                seriesBarDistance: 15
            };

            this.barResponsiveOptions = [
                ['screen and (min-width: 641px) and (max-width: 1024px)', {
                    seriesBarDistance: 10,
                    axisX: {
                        labelInterpolationFnc: function(value) {
                            return value;
                        }
                    }
                }],
                ['screen and (max-width: 640px)', {
                    seriesBarDistance: 5,
                    axisX: {
                        labelInterpolationFnc: function(value) {
                            return value[0];
                        }
                    }
                }]
            ];

            function getRandomInt(min, max) {
                return Math.floor(Math.random() * (max - min)) + min;
            }

            // line chart
            this.lineData = {
                labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
                series: [
                    [0, 1, 2, 4, 7, 6, 9, 10, 8, 10, 14, 13, 16, 14, 17, 19, 20, 31, 32, 26, 36, 28, 31, 40, 26, 26, 43, 47, 55, 30],
                    [0, 1, 2, 4, 4, 6, 6, 13, 9, 10, 16, 18, 21, 16, 16, 16, 31, 17, 27, 23, 31, 29, 35, 39, 30, 32, 26, 43, 51, 46],
                    [0, 1, 3, 4, 6, 5, 11, 9, 11, 11, 13, 15, 14, 22, 20, 15, 31, 27, 25, 25, 36, 30, 37, 29, 29, 39, 40, 49, 34, 35],
                    [0, 1, 3, 5, 7, 5, 9, 9, 10, 17, 13, 21, 14, 16, 23, 23, 25, 17, 24, 34, 27, 39, 33, 45, 47, 32, 40, 36, 49, 32],
                    [0, 1, 3, 3, 7, 5, 8, 11, 12, 13, 16, 17, 20, 24, 27, 15, 22, 33, 35, 24, 32, 35, 41, 39, 24, 31, 51, 29, 45, 50]
                ]
            };

            this.lineOptions = {
                axisX: {
                    labelInterpolationFnc: function(value) {
                        return value;
                    }
                }
            };

            // pie chart
            this.pieData = {
                series: [20, 10, 30, 40]
            };

            // donut chart
            this.donutOptions = {
                donut: true
            };

            function pushLimit(arr, elem, limit) {
                arr.push(elem);
                if (arr.length > limit) {
                    arr.splice(0, 1);
                }
            }

            // Use $interval to update bar chart data
            var barUpdatePromise = $interval(function() {
                var time = new Date();

                pushLimit(this.barData.labels, [
                    time.getHours(),
                    time.getMinutes(),
                    time.getSeconds()
                ].join(':'), 12);

                this.barData.series.forEach(function(series) {
                    pushLimit(series, getRandomInt(0, 10), 12);
                });
            }.bind(this), 1000);

            // Cancel interval once scope is destroyed
            $scope.$on('$destroy', function() {
                $interval.cancel(barUpdatePromise);
            });
        }
    ]);

})(angular);
<commit_msg>chore(example): update event example<commit_after>/* global angular */
(function(angular) {
    'use strict';

    var module = angular.module('app', ['ngChartist']);

    module.controller('ChartistExampleCtrl', ['$scope', '$interval',
        function($scope, $interval) {

            this.events = {
                draw: function(obj) {
                    // do stuff
                }
            };

            // bar chart
            this.barData = {
                labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
                series: [
                    [5, 4, 3, 7, 5, 10, 3, 4, 8, 10, 6, 8],
                    [3, 2, 9, 5, 4, 6, 4, 6, 7, 8, 7, 4]
                ]
            };

            this.barOptions = {
                seriesBarDistance: 15
            };

            this.barResponsiveOptions = [
                ['screen and (min-width: 641px) and (max-width: 1024px)', {
                    seriesBarDistance: 10,
                    axisX: {
                        labelInterpolationFnc: function(value) {
                            return value;
                        }
                    }
                }],
                ['screen and (max-width: 640px)', {
                    seriesBarDistance: 5,
                    axisX: {
                        labelInterpolationFnc: function(value) {
                            return value[0];
                        }
                    }
                }]
            ];

            function getRandomInt(min, max) {
                return Math.floor(Math.random() * (max - min)) + min;
            }

            // line chart
            this.lineData = {
                labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
                series: [
                    [0, 1, 2, 4, 7, 6, 9, 10, 8, 10, 14, 13, 16, 14, 17, 19, 20, 31, 32, 26, 36, 28, 31, 40, 26, 26, 43, 47, 55, 30],
                    [0, 1, 2, 4, 4, 6, 6, 13, 9, 10, 16, 18, 21, 16, 16, 16, 31, 17, 27, 23, 31, 29, 35, 39, 30, 32, 26, 43, 51, 46],
                    [0, 1, 3, 4, 6, 5, 11, 9, 11, 11, 13, 15, 14, 22, 20, 15, 31, 27, 25, 25, 36, 30, 37, 29, 29, 39, 40, 49, 34, 35],
                    [0, 1, 3, 5, 7, 5, 9, 9, 10, 17, 13, 21, 14, 16, 23, 23, 25, 17, 24, 34, 27, 39, 33, 45, 47, 32, 40, 36, 49, 32],
                    [0, 1, 3, 3, 7, 5, 8, 11, 12, 13, 16, 17, 20, 24, 27, 15, 22, 33, 35, 24, 32, 35, 41, 39, 24, 31, 51, 29, 45, 50]
                ]
            };

            this.lineOptions = {
                axisX: {
                    labelInterpolationFnc: function(value) {
                        return value;
                    }
                }
            };

            // pie chart
            this.pieData = {
                series: [20, 10, 30, 40]
            };

            // donut chart
            this.donutOptions = {
                donut: true
            };

            function pushLimit(arr, elem, limit) {
                arr.push(elem);
                if (arr.length > limit) {
                    arr.splice(0, 1);
                }
            }

            // Use $interval to update bar chart data
            var barUpdatePromise = $interval(function() {
                var time = new Date();

                pushLimit(this.barData.labels, [
                    time.getHours(),
                    time.getMinutes(),
                    time.getSeconds()
                ].join(':'), 12);

                this.barData.series.forEach(function(series) {
                    pushLimit(series, getRandomInt(0, 10), 12);
                });
            }.bind(this), 1000);

            // Cancel interval once scope is destroyed
            $scope.$on('$destroy', function() {
                $interval.cancel(barUpdatePromise);
            });
        }
    ]);

})(angular);
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var test = require( 'tape' );
var ln = require( './../lib' );

// TESTS //

test( 'main export is a function', function test( t ) {
	t.ok( typeof ln === 'function', 'main export is a function' );
	t.end();
});

test( 'the function computes the natural logarithm of a nonnegative number', function test( t ) {
	// Tested on Wolfram Alpha...
	t.equal( ln( 4 ), 1.3862943611198906188344642429163531361510002687205105, 'equals ~1.386' );
	t.equal( ln( 9 ), 2.1972245773362193827904904738450514092949811156454989, 'equals ~2.197' );
	t.end();
});

test( 'the function returns `-infinity` if provided `0`', function test( t ) {
	t.equal( ln( 0 ), Number.NEGATIVE_INFINITY, 'equals -infinity' );
	t.end();
});

test( 'the function returns `+infinity` if provided `+infinity`', function test( t ) {
	t.equal( ln( Number.POSITIVE_INFINITY ), Number.POSITIVE_INFINITY, 'equals +infinity' );
	t.end();
});

test( 'the function returns `NaN` if provide a negative number', function test( t ) {
	var val = ln( -1 );
	t.ok( val !== val, 'returns NaN' );
	t.end();
});
<commit_msg>Fix grammar<commit_after>'use strict';

// MODULES //

var test = require( 'tape' );
var ln = require( './../lib' );

// TESTS //

test( 'main export is a function', function test( t ) {
	t.ok( typeof ln === 'function', 'main export is a function' );
	t.end();
});

test( 'the function computes the natural logarithm of a nonnegative number', function test( t ) {
	// Tested on Wolfram Alpha...
	t.equal( ln( 4 ), 1.3862943611198906188344642429163531361510002687205105, 'equals ~1.386' );
	t.equal( ln( 9 ), 2.1972245773362193827904904738450514092949811156454989, 'equals ~2.197' );
	t.end();
});

test( 'the function returns `-infinity` if provided `0`', function test( t ) {
	t.equal( ln( 0 ), Number.NEGATIVE_INFINITY, 'equals -infinity' );
	t.end();
});

test( 'the function returns `+infinity` if provided `+infinity`', function test( t ) {
	t.equal( ln( Number.POSITIVE_INFINITY ), Number.POSITIVE_INFINITY, 'equals +infinity' );
	t.end();
});

test( 'the function returns `NaN` if provided a negative number', function test( t ) {
	var val = ln( -1 );
	t.ok( val !== val, 'returns NaN' );
	t.end();
});
<|endoftext|>