<commit_before>(function() {

  /* _FROM_SVG_START_ */
  function getColorStop(el) {
    var style = el.getAttribute('style'),
        offset = el.getAttribute('offset'),
        color, colorAlpha, opacity;

    // convert percents to absolute values
    offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);

    if (style) {
      var keyValuePairs = style.split(/\s*;\s*/);

      if (keyValuePairs[keyValuePairs.length - 1] === '') {
        keyValuePairs.pop();
      }

      for (var i = keyValuePairs.length; i--; ) {

        var split = keyValuePairs[i].split(/\s*:\s*/),
            key = split[0].trim(),
            value = split[1].trim();

        if (key === 'stop-color') {
          color = value;
        }
        else if (key === 'stop-opacity') {
          opacity = value;
        }
      }
    }

    if (!color) {
      color = el.getAttribute('stop-color') || 'rgb(0,0,0)';
    }
    if (!opacity) {
      opacity = el.getAttribute('stop-opacity');
    }

    color = new fabric.Color(color);
    colorAlpha = color.getAlpha();
    color = color.toRgb();
    opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);
    opacity *= colorAlpha;

    return {
      offset: offset,
      color: color,
      opacity: opacity
    };
  }

  function getLinearCoords(el) {
    return {
      x1: el.getAttribute('x1') || 0,
      y1: el.getAttribute('y1') || 0,
      x2: el.getAttribute('x2') || '100%',
      y2: el.getAttribute('y2') || 0
    };
  }

  function getRadialCoords(el) {
    return {
      x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',
      y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',
      r1: 0,
      x2: el.getAttribute('cx') || '50%',
      y2: el.getAttribute('cy') || '50%',
      r2: el.getAttribute('r') || '50%'
    };
  }
  /* _FROM_SVG_END_ */

  /**
   * Gradient class
   * @class fabric.Gradient
   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#gradients}
   * @see {@link fabric.Gradient#initialize} for constructor definition
   */
  fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {
    /*
     * Stores the original position of the gradient when we convert from % to fixed values, for objectBoundingBox case.
     * @type Number
     * @default 0
     */
    origX: 0,

    /*
     * Stores the original position of the gradient when we convert from % to fixed values, for objectBoundingBox case.
     * @type Number
     * @default 0
     */
    origY: 0,

    /**
     * Constructor
     * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops
     * @return {fabric.Gradient} thisArg
     */
    initialize: function(options) {
      options || (options = { });

      var coords = { };

      this.id = fabric.Object.__uid++;
      this.type = options.type || 'linear';

      coords = {
        x1: options.coords.x1 || 0,
        y1: options.coords.y1 || 0,
        x2: options.coords.x2 || 0,
        y2: options.coords.y2 || 0
      };

      if (this.type === 'radial') {
        coords.r1 = options.coords.r1 || 0;
        coords.r2 = options.coords.r2 || 0;
      }

      this.coords = coords;
      this.gradientUnits = options.gradientUnits || 'objectBoundingBox';
      this.colorStops = options.colorStops.slice();
      if (options.gradientTransform) {
        this.gradientTransform = options.gradientTransform;
      }
      this.origX = options.left || this.origX;
      this.origY = options.top || this.origY;
    },

    /**
     * Adds another colorStop
     * @param {Object} colorStop Object with offset and color
     * @return {fabric.Gradient} thisArg
     */
    addColorStop: function(colorStop) {
      for (var position in colorStop) {
        var color = new fabric.Color(colorStop[position]);
        this.colorStops.push({
          offset: position,
          color: color.toRgb(),
          opacity: color.getAlpha()
        });
      }
      return this;
    },

    /**
     * Returns object representation of a gradient
     * @return {Object}
     */
    toObject: function() {
      return {
        type: this.type,
        coords: this.coords,
        gradientUnits: this.gradientUnits,
        colorStops: this.colorStops
      };
    },

    /* _TO_SVG_START_ */
    /**
     * Returns SVG representation of an gradient
     * @param {Object} object Object to create a gradient for
     * @param {Boolean} normalize Whether coords should be normalized
     * @return {String} SVG representation of an gradient (linear/radial)
     */
    toSVG: function(object, normalize) {
      var coords = fabric.util.object.clone(this.coords),
          markup, commonAttributes;

      // colorStops must be sorted ascending
      this.colorStops.sort(function(a, b) {
        return a.offset - b.offset;
      });

      if (normalize && this.gradientUnits === 'userSpaceOnUse') {
        coords.x1 += object.width / 2;
        coords.y1 += object.height / 2;
        coords.x2 += object.width / 2;
        coords.y2 += object.height / 2;
      }
      else if (this.gradientUnits === 'objectBoundingBox') {
        _convertValuesToPercentUnits(object, coords);
      }
      commonAttributes = 'id="SVGID_' + this.id +
                     '" gradientUnits="' + this.gradientUnits + '"';
      if (this.gradientTransform) {
        commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" ';
      }
      if (this.type === 'linear') {
        markup = [
          //jscs:disable validateIndentation
          '<linearGradient ',
            commonAttributes,
            ' x1="', coords.x1,
            '" y1="', coords.y1,
            '" x2="', coords.x2,
            '" y2="', coords.y2,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }
      else if (this.type === 'radial') {
        markup = [
          //jscs:disable validateIndentation
          '<radialGradient ',
            commonAttributes,
            ' cx="', coords.x2,
            '" cy="', coords.y2,
            '" r="', coords.r2,
            '" fx="', coords.x1,
            '" fy="', coords.y1,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }

      for (var i = 0; i < this.colorStops.length; i++) {
        markup.push(
          //jscs:disable validateIndentation
          '<stop ',
            'offset="', (this.colorStops[i].offset * 100) + '%',
            '" style="stop-color:', this.colorStops[i].color,
            (this.colorStops[i].opacity != null ? ';stop-opacity: ' + this.colorStops[i].opacity : ';'),
          '"/>\n'
          //jscs:enable validateIndentation
        );
      }

      markup.push((this.type === 'linear' ? '</linearGradient>\n' : '</radialGradient>\n'));

      return markup.join('');
    },
    /* _TO_SVG_END_ */

    /**
     * Returns an instance of CanvasGradient
     * @param {CanvasRenderingContext2D} ctx Context to render on
     * @return {CanvasGradient}
     */
    toLive: function(ctx) {
      var gradient;

      if (!this.type) {
        return;
      }

      if (this.type === 'linear') {
        gradient = ctx.createLinearGradient(
          this.coords.x1, this.coords.y1, this.coords.x2, this.coords.y2);
      }
      else if (this.type === 'radial') {
        gradient = ctx.createRadialGradient(
          this.coords.x1, this.coords.y1, this.coords.r1, this.coords.x2, this.coords.y2, this.coords.r2);
      }

      for (var i = 0, len = this.colorStops.length; i < len; i++) {
        var color = this.colorStops[i].color,
            opacity = this.colorStops[i].opacity,
            offset = this.colorStops[i].offset;

        if (typeof opacity !== 'undefined') {
          color = new fabric.Color(color).setAlpha(opacity).toRgba();
        }
        gradient.addColorStop(parseFloat(offset), color);
      }

      return gradient;
    }
  });

  fabric.util.object.extend(fabric.Gradient, {

    /* _FROM_SVG_START_ */
    /**
     * Returns {@link fabric.Gradient} instance from an SVG element
     * @static
     * @memberof fabric.Gradient
     * @param {SVGGradientElement} el SVG gradient element
     * @param {fabric.Object} instance
     * @return {fabric.Gradient} Gradient instance
     * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement
     * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
     */
    fromElement: function(el, instance) {

      /**
       *  @example:
       *
       *  <linearGradient id="linearGrad1">
       *    <stop offset="0%" stop-color="white"/>
       *    <stop offset="100%" stop-color="black"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <linearGradient id="linearGrad2">
       *    <stop offset="0" style="stop-color:rgb(255,255,255)"/>
       *    <stop offset="1" style="stop-color:rgb(0,0,0)"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad1">
       *    <stop offset="0%" stop-color="white" stop-opacity="1" />
       *    <stop offset="50%" stop-color="black" stop-opacity="0.5" />
       *    <stop offset="100%" stop-color="white" stop-opacity="1" />
       *  </radialGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad2">
       *    <stop offset="0" stop-color="rgb(255,255,255)" />
       *    <stop offset="0.5" stop-color="rgb(0,0,0)" />
       *    <stop offset="1" stop-color="rgb(255,255,255)" />
       *  </radialGradient>
       *
       */

      var colorStopEls = el.getElementsByTagName('stop'),
          type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'),
          gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',
          gradientTransform = el.getAttribute('gradientTransform'),
          colorStops = [],
          coords = { };

      if (type === 'linear') {
        coords = getLinearCoords(el);
      }
      else if (type === 'radial') {
        coords = getRadialCoords(el);
      }

      for (var i = colorStopEls.length; i--; ) {
        colorStops.push(getColorStop(colorStopEls[i]));
      }

      _convertPercentUnitsToValues(instance, coords);

      var gradient = new fabric.Gradient({
        type: type,
        coords: coords,
        gradientUnits: gradientUnits,
        colorStops: colorStops
      });

      if (gradientTransform) {
        gradient.gradientTransform = fabric.parseTransformAttribute(gradientTransform);
      }

      return gradient;
    },
    /* _FROM_SVG_END_ */

    /**
     * Returns {@link fabric.Gradient} instance from its object representation
     * @static
     * @memberof fabric.Gradient
     * @param {Object} obj
     * @param {Object} [options] Options object
     */
    forObject: function(obj, options) {
      options || (options = { });
      _convertPercentUnitsToValues(obj, options);
      return new fabric.Gradient(options);
    }
  });

  /**
   * @private
   */
  function _convertPercentUnitsToValues(object, options) {
    for (var prop in options) {
      if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) {
        var percents = parseFloat(options[prop], 10);
        if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
          options[prop] = fabric.util.toFixed(object.width * percents / 100, 2)  + object.left;
        }
        else if (prop === 'y1' || prop === 'y2') {
          options[prop] = fabric.util.toFixed(object.height * percents / 100, 2) + object.top;
        }
      }
    }
  }

  /* _TO_SVG_START_ */
  /**
   * @private
   */
  function _convertValuesToPercentUnits(object, options) {
    for (var prop in options) {
      //convert to percent units
      if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.fill.origX) / object.width * 100, 2) + '%';
      }
      else if (prop === 'y1' || prop === 'y2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.fill.origY) / object.height * 100, 2) + '%';
      }
    }
  }
  /* _TO_SVG_END_ */

})();
<commit_msg>Update gradient.class.js<commit_after>(function() {

  /* _FROM_SVG_START_ */
  function getColorStop(el) {
    var style = el.getAttribute('style'),
        offset = el.getAttribute('offset'),
        color, colorAlpha, opacity;

    // convert percents to absolute values
    offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);

    if (style) {
      var keyValuePairs = style.split(/\s*;\s*/);

      if (keyValuePairs[keyValuePairs.length - 1] === '') {
        keyValuePairs.pop();
      }

      for (var i = keyValuePairs.length; i--; ) {

        var split = keyValuePairs[i].split(/\s*:\s*/),
            key = split[0].trim(),
            value = split[1].trim();

        if (key === 'stop-color') {
          color = value;
        }
        else if (key === 'stop-opacity') {
          opacity = value;
        }
      }
    }

    if (!color) {
      color = el.getAttribute('stop-color') || 'rgb(0,0,0)';
    }
    if (!opacity) {
      opacity = el.getAttribute('stop-opacity');
    }

    color = new fabric.Color(color);
    colorAlpha = color.getAlpha();
    opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);
    opacity *= colorAlpha;

    return {
      offset: offset,
      color: color.toRgb(),
      opacity: opacity
    };
  }

  function getLinearCoords(el) {
    return {
      x1: el.getAttribute('x1') || 0,
      y1: el.getAttribute('y1') || 0,
      x2: el.getAttribute('x2') || '100%',
      y2: el.getAttribute('y2') || 0
    };
  }

  function getRadialCoords(el) {
    return {
      x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',
      y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',
      r1: 0,
      x2: el.getAttribute('cx') || '50%',
      y2: el.getAttribute('cy') || '50%',
      r2: el.getAttribute('r') || '50%'
    };
  }
  /* _FROM_SVG_END_ */

  /**
   * Gradient class
   * @class fabric.Gradient
   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#gradients}
   * @see {@link fabric.Gradient#initialize} for constructor definition
   */
  fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {
    /*
     * Stores the original position of the gradient when we convert from % to fixed values, for objectBoundingBox case.
     * @type Number
     * @default 0
     */
    origX: 0,

    /*
     * Stores the original position of the gradient when we convert from % to fixed values, for objectBoundingBox case.
     * @type Number
     * @default 0
     */
    origY: 0,

    /**
     * Constructor
     * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops
     * @return {fabric.Gradient} thisArg
     */
    initialize: function(options) {
      options || (options = { });

      var coords = { };

      this.id = fabric.Object.__uid++;
      this.type = options.type || 'linear';

      coords = {
        x1: options.coords.x1 || 0,
        y1: options.coords.y1 || 0,
        x2: options.coords.x2 || 0,
        y2: options.coords.y2 || 0
      };

      if (this.type === 'radial') {
        coords.r1 = options.coords.r1 || 0;
        coords.r2 = options.coords.r2 || 0;
      }

      this.coords = coords;
      this.gradientUnits = options.gradientUnits || 'objectBoundingBox';
      this.colorStops = options.colorStops.slice();
      if (options.gradientTransform) {
        this.gradientTransform = options.gradientTransform;
      }
      this.origX = options.left || this.origX;
      this.origY = options.top || this.origY;
    },

    /**
     * Adds another colorStop
     * @param {Object} colorStop Object with offset and color
     * @return {fabric.Gradient} thisArg
     */
    addColorStop: function(colorStop) {
      for (var position in colorStop) {
        var color = new fabric.Color(colorStop[position]);
        this.colorStops.push({
          offset: position,
          color: color.toRgb(),
          opacity: color.getAlpha()
        });
      }
      return this;
    },

    /**
     * Returns object representation of a gradient
     * @return {Object}
     */
    toObject: function() {
      return {
        type: this.type,
        coords: this.coords,
        gradientUnits: this.gradientUnits,
        colorStops: this.colorStops
      };
    },

    /* _TO_SVG_START_ */
    /**
     * Returns SVG representation of an gradient
     * @param {Object} object Object to create a gradient for
     * @param {Boolean} normalize Whether coords should be normalized
     * @return {String} SVG representation of an gradient (linear/radial)
     */
    toSVG: function(object, normalize) {
      var coords = fabric.util.object.clone(this.coords),
          markup, commonAttributes;

      // colorStops must be sorted ascending
      this.colorStops.sort(function(a, b) {
        return a.offset - b.offset;
      });

      if (normalize && this.gradientUnits === 'userSpaceOnUse') {
        coords.x1 += object.width / 2;
        coords.y1 += object.height / 2;
        coords.x2 += object.width / 2;
        coords.y2 += object.height / 2;
      }
      else if (this.gradientUnits === 'objectBoundingBox') {
        _convertValuesToPercentUnits(object, coords);
      }
      commonAttributes = 'id="SVGID_' + this.id +
                     '" gradientUnits="' + this.gradientUnits + '"';
      if (this.gradientTransform) {
        commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" ';
      }
      if (this.type === 'linear') {
        markup = [
          //jscs:disable validateIndentation
          '<linearGradient ',
            commonAttributes,
            ' x1="', coords.x1,
            '" y1="', coords.y1,
            '" x2="', coords.x2,
            '" y2="', coords.y2,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }
      else if (this.type === 'radial') {
        markup = [
          //jscs:disable validateIndentation
          '<radialGradient ',
            commonAttributes,
            ' cx="', coords.x2,
            '" cy="', coords.y2,
            '" r="', coords.r2,
            '" fx="', coords.x1,
            '" fy="', coords.y1,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }

      for (var i = 0; i < this.colorStops.length; i++) {
        markup.push(
          //jscs:disable validateIndentation
          '<stop ',
            'offset="', (this.colorStops[i].offset * 100) + '%',
            '" style="stop-color:', this.colorStops[i].color,
            (this.colorStops[i].opacity != null ? ';stop-opacity: ' + this.colorStops[i].opacity : ';'),
          '"/>\n'
          //jscs:enable validateIndentation
        );
      }

      markup.push((this.type === 'linear' ? '</linearGradient>\n' : '</radialGradient>\n'));

      return markup.join('');
    },
    /* _TO_SVG_END_ */

    /**
     * Returns an instance of CanvasGradient
     * @param {CanvasRenderingContext2D} ctx Context to render on
     * @return {CanvasGradient}
     */
    toLive: function(ctx) {
      var gradient;

      if (!this.type) {
        return;
      }

      if (this.type === 'linear') {
        gradient = ctx.createLinearGradient(
          this.coords.x1, this.coords.y1, this.coords.x2, this.coords.y2);
      }
      else if (this.type === 'radial') {
        gradient = ctx.createRadialGradient(
          this.coords.x1, this.coords.y1, this.coords.r1, this.coords.x2, this.coords.y2, this.coords.r2);
      }

      for (var i = 0, len = this.colorStops.length; i < len; i++) {
        var color = this.colorStops[i].color,
            opacity = this.colorStops[i].opacity,
            offset = this.colorStops[i].offset;

        if (typeof opacity !== 'undefined') {
          color = new fabric.Color(color).setAlpha(opacity).toRgba();
        }
        gradient.addColorStop(parseFloat(offset), color);
      }

      return gradient;
    }
  });

  fabric.util.object.extend(fabric.Gradient, {

    /* _FROM_SVG_START_ */
    /**
     * Returns {@link fabric.Gradient} instance from an SVG element
     * @static
     * @memberof fabric.Gradient
     * @param {SVGGradientElement} el SVG gradient element
     * @param {fabric.Object} instance
     * @return {fabric.Gradient} Gradient instance
     * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement
     * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
     */
    fromElement: function(el, instance) {

      /**
       *  @example:
       *
       *  <linearGradient id="linearGrad1">
       *    <stop offset="0%" stop-color="white"/>
       *    <stop offset="100%" stop-color="black"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <linearGradient id="linearGrad2">
       *    <stop offset="0" style="stop-color:rgb(255,255,255)"/>
       *    <stop offset="1" style="stop-color:rgb(0,0,0)"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad1">
       *    <stop offset="0%" stop-color="white" stop-opacity="1" />
       *    <stop offset="50%" stop-color="black" stop-opacity="0.5" />
       *    <stop offset="100%" stop-color="white" stop-opacity="1" />
       *  </radialGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad2">
       *    <stop offset="0" stop-color="rgb(255,255,255)" />
       *    <stop offset="0.5" stop-color="rgb(0,0,0)" />
       *    <stop offset="1" stop-color="rgb(255,255,255)" />
       *  </radialGradient>
       *
       */

      var colorStopEls = el.getElementsByTagName('stop'),
          type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'),
          gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',
          gradientTransform = el.getAttribute('gradientTransform'),
          colorStops = [],
          coords = { };

      if (type === 'linear') {
        coords = getLinearCoords(el);
      }
      else if (type === 'radial') {
        coords = getRadialCoords(el);
      }

      for (var i = colorStopEls.length; i--; ) {
        colorStops.push(getColorStop(colorStopEls[i]));
      }

      _convertPercentUnitsToValues(instance, coords);

      var gradient = new fabric.Gradient({
        type: type,
        coords: coords,
        gradientUnits: gradientUnits,
        colorStops: colorStops
      });

      if (gradientTransform) {
        gradient.gradientTransform = fabric.parseTransformAttribute(gradientTransform);
      }

      return gradient;
    },
    /* _FROM_SVG_END_ */

    /**
     * Returns {@link fabric.Gradient} instance from its object representation
     * @static
     * @memberof fabric.Gradient
     * @param {Object} obj
     * @param {Object} [options] Options object
     */
    forObject: function(obj, options) {
      options || (options = { });
      _convertPercentUnitsToValues(obj, options);
      return new fabric.Gradient(options);
    }
  });

  /**
   * @private
   */
  function _convertPercentUnitsToValues(object, options) {
    for (var prop in options) {
      if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) {
        var percents = parseFloat(options[prop], 10);
        if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
          options[prop] = fabric.util.toFixed(object.width * percents / 100, 2)  + object.left;
        }
        else if (prop === 'y1' || prop === 'y2') {
          options[prop] = fabric.util.toFixed(object.height * percents / 100, 2) + object.top;
        }
      }
    }
  }

  /* _TO_SVG_START_ */
  /**
   * @private
   */
  function _convertValuesToPercentUnits(object, options) {
    for (var prop in options) {
      //convert to percent units
      if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.fill.origX) / object.width * 100, 2) + '%';
      }
      else if (prop === 'y1' || prop === 'y2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.fill.origY) / object.height * 100, 2) + '%';
      }
    }
  }
  /* _TO_SVG_END_ */

})();
<|endoftext|>


<commit_before>define(function(require) {

  var test = require('../../test')
  var assert = test.assert

  assert(seajs.log('seajs.log test', 'group') === undefined, 'group')

  assert(seajs.log('a') === undefined, 'log')
  assert(seajs.log('a ' + 1) === undefined, 'log')

  assert(seajs.log('a', 'warn') === undefined, 'warn')
  assert(seajs.log('a', 'info') === undefined, 'info')
  assert(seajs.log('a', 'error') === undefined, 'error')
  assert(seajs.log('a', 'time') === undefined, 'time')
  assert(seajs.log('a', 'timeEnd') === undefined, 'timeEnd')

  assert(seajs.log('a', 'dir') === undefined, 'dir')
  assert(seajs.log({ name: 'a' }, 'dir') === undefined, 'dir')

  assert(seajs.log('seajs.log test', 'groupEnd') === undefined, 'groupEnd')

  test.next()

});

<commit_msg>Update test specs according to code modification<commit_after>define(function(require) {

  var test = require('../../test')
  var assert = test.assert

  //assert(seajs.log('seajs.log test', 'group') === undefined, 'group')

  assert(seajs.log('a') === undefined, 'log')
  assert(seajs.log('a ' + 1) === undefined, 'log')

  assert(seajs.log('a', 'warn') === undefined, 'warn')
  assert(seajs.log('a', 'info') === undefined, 'info')
  assert(seajs.log('a', 'error') === undefined, 'error')
  //assert(seajs.log('a', 'time') === undefined, 'time')
  //assert(seajs.log('a', 'timeEnd') === undefined, 'timeEnd')

  assert(seajs.log('a', 'dir') === undefined, 'dir')
  assert(seajs.log({ name: 'a' }, 'dir') === undefined, 'dir')

  //assert(seajs.log('seajs.log test', 'groupEnd') === undefined, 'groupEnd')

  test.next()

});

<|endoftext|>


<commit_before>var email = require('../index');
var assert = require('assert');

//parsing good
var parsegood = email.parse("niceandsimple@example.com");
assert.equal(parsegood['user'], 'niceandsimple');
assert.equal(parsegood['domain'], 'example.com');

parsegood = email.parse('"@somethingsomething"@example.com');
assert.equal(parsegood['user'], '"@somethingsomething"');
assert.equal(parsegood['domain'], 'example.com');

//parsing bad
var parsebad = email.parse("badip@[827.750.304.001]");
assert.equal(parsebad, false);
assert.equal(typeof parsebad['user'], 'undefined');
assert.equal(typeof parsebad['domain'], 'undefined');

parsebad = email.parse("a@");
assert.equal(parsebad, false);
assert.equal(typeof parsebad['user'], 'undefined');
assert.equal(typeof parsebad['domain'], 'undefined');

//good
assert.ok(email.valid('email@example.com'));
assert.ok(email.valid('email@example'));
assert.ok(email.valid('email+sometag@example.com'));
assert.ok(email.valid('"@somethingsomething"@example.com'));
assert.equal(email.valid('"email@example.com'), false);
assert.ok(email.valid('one.two@one-two.com'));

//bad
assert.equal(email.valid('badip@[827.750.304.001]'), false);
assert.equal(email.valid('badip@[827.750.304.001'), false);
assert.equal(email.valid('bad@ThisHostAddressSpaceIsGreaterThanSixtyThreeCharactersLetsSeeHowManyICanFitInHereWithoutDestroyingTheWorld.com'), false);
assert.equal(email.valid('bad@ThisAddressIsGreaterThanTwoHundredAndFiftyThreeCharactersLetsSeeHowManyICanFitInHereWithoutDestroyingTheWorld.com.Unfortunatly.we.were.not.quite.there.yet.but.we.getting.closer.by.the.minute.I.assure.you.we.are.almost.there.dot.some.new.top.level.domain.com.us.tz.kosher'), false);
assert.equal(email.valid('one.two@-one-two.com'), false);
assert.equal(email.valid('a@'), false);

//shamelessly copied from http://en.wikipedia.org/wiki/Email_address
assert.ok(email.valid('niceandsimple@example.com'));
assert.ok(email.valid('very.common@example.com'));
assert.ok(email.valid('a.little.lengthy.but.fine@dept.example.com'));
assert.ok(email.valid('disposable.style.email.with+symbol@example.com'));
assert.ok(email.valid('user@[2001:db8:1ff::a0b:dbd0]'));
assert.ok(email.valid('"much.more unusual"@example.com'));
assert.ok(email.valid('"very.unusual.@.unusual.com"@example.com'));
assert.ok(email.valid('"very.(),:;<>[]\\".VERY.\\"very@\\\\ \\"very\\".unusual"@strange.example.com'));
assert.ok(email.valid('postbox@com'));
assert.ok(email.valid('admin@mailserver1'));
assert.ok(email.valid('!#$%&\'*+-/=?^_`{}|~@example.org'));
assert.ok(email.valid('"()<>[]:,;@\\"!#$%&\'*+-/=?^_`{}| ~.a"@example.org'));
assert.ok(email.valid('" "@example.org'));

assert.equal(email.valid("Abc.example.com"), false);
assert.equal(email.valid("A@b@c@example.com"), false);
assert.equal(email.valid('a"b(c)d,e:f;g<h>i[j\k]l@example.com'), false);
assert.equal(email.valid('just"not"right@example.com'), false);
assert.equal(email.valid('this is"not\allowed@example.com'), false);
assert.equal(email.valid('this\ still\"not\\allowed@example.com'), false);
<commit_msg>Add failing tests for '@a'<commit_after>var email = require('../index');
var assert = require('assert');

//parsing good
var parsegood = email.parse("niceandsimple@example.com");
assert.equal(parsegood['user'], 'niceandsimple');
assert.equal(parsegood['domain'], 'example.com');

parsegood = email.parse('"@somethingsomething"@example.com');
assert.equal(parsegood['user'], '"@somethingsomething"');
assert.equal(parsegood['domain'], 'example.com');

//parsing bad
var parsebad = email.parse("badip@[827.750.304.001]");
assert.equal(parsebad, false);
assert.equal(typeof parsebad['user'], 'undefined');
assert.equal(typeof parsebad['domain'], 'undefined');

parsebad = email.parse("a@");
assert.equal(parsebad, false);
assert.equal(typeof parsebad['user'], 'undefined');
assert.equal(typeof parsebad['domain'], 'undefined');

parsebad = email.parse("@a");
assert.equal(parsebad, false);
assert.equal(typeof parsebad['user'], 'undefined');
assert.equal(typeof parsebad['domain'], 'undefined');

//good
assert.ok(email.valid('email@example.com'));
assert.ok(email.valid('email@example'));
assert.ok(email.valid('email+sometag@example.com'));
assert.ok(email.valid('"@somethingsomething"@example.com'));
assert.equal(email.valid('"email@example.com'), false);
assert.ok(email.valid('one.two@one-two.com'));

//bad
assert.equal(email.valid('badip@[827.750.304.001]'), false);
assert.equal(email.valid('badip@[827.750.304.001'), false);
assert.equal(email.valid('bad@ThisHostAddressSpaceIsGreaterThanSixtyThreeCharactersLetsSeeHowManyICanFitInHereWithoutDestroyingTheWorld.com'), false);
assert.equal(email.valid('bad@ThisAddressIsGreaterThanTwoHundredAndFiftyThreeCharactersLetsSeeHowManyICanFitInHereWithoutDestroyingTheWorld.com.Unfortunatly.we.were.not.quite.there.yet.but.we.getting.closer.by.the.minute.I.assure.you.we.are.almost.there.dot.some.new.top.level.domain.com.us.tz.kosher'), false);
assert.equal(email.valid('one.two@-one-two.com'), false);
assert.equal(email.valid('a@'), false);

//shamelessly copied from http://en.wikipedia.org/wiki/Email_address
assert.ok(email.valid('niceandsimple@example.com'));
assert.ok(email.valid('very.common@example.com'));
assert.ok(email.valid('a.little.lengthy.but.fine@dept.example.com'));
assert.ok(email.valid('disposable.style.email.with+symbol@example.com'));
assert.ok(email.valid('user@[2001:db8:1ff::a0b:dbd0]'));
assert.ok(email.valid('"much.more unusual"@example.com'));
assert.ok(email.valid('"very.unusual.@.unusual.com"@example.com'));
assert.ok(email.valid('"very.(),:;<>[]\\".VERY.\\"very@\\\\ \\"very\\".unusual"@strange.example.com'));
assert.ok(email.valid('postbox@com'));
assert.ok(email.valid('admin@mailserver1'));
assert.ok(email.valid('!#$%&\'*+-/=?^_`{}|~@example.org'));
assert.ok(email.valid('"()<>[]:,;@\\"!#$%&\'*+-/=?^_`{}| ~.a"@example.org'));
assert.ok(email.valid('" "@example.org'));

assert.equal(email.valid("Abc.example.com"), false);
assert.equal(email.valid("A@b@c@example.com"), false);
assert.equal(email.valid('a"b(c)d,e:f;g<h>i[j\k]l@example.com'), false);
assert.equal(email.valid('just"not"right@example.com'), false);
assert.equal(email.valid('this is"not\allowed@example.com'), false);
assert.equal(email.valid('this\ still\"not\\allowed@example.com'), false);
<|endoftext|>


<commit_before>"use strict";
const request = require("superagent");

const RequestResults = require("../constants/RequestResults");
const Utils = require("../utils/Utils");

const CONTENT_TYPE = "application/json";

const _DEFAULT_TIMEOUT = 10000;
const _DEFAULT_URL_BASE = "https://api.iobeam.com/v1";

let _urlBase = _DEFAULT_URL_BASE;
let _timeout = _DEFAULT_TIMEOUT;

module.exports = {

    /**
     * Setup configuration parameters of this requester object.
     * @param {string} urlBase - Base portion of the URL endpoints for this API
     * (default: https://api.iobeam.com/v1").
     * @param {number} timeout - Milliseconds to wait before timing out a request
     * (default: 10000).
     */
    initialize: function(urlBase, timeout) {
        if (urlBase) {
            _urlBase = urlBase;
        }
        if (timeout) {
            _timeout = timeout;
        }
    },

    /**
     * Execute a superagent HTTP request.
     * @param {object} req - superagent request
     * @param {function} callback - Function to call after the request with status
     * @param {object} context - Related information about this call to pass to callback
     */
    execute: function(req, callback, context) {
        callback(RequestResults.PENDING, null, null);
        //const key = req.req.path;

        req.end(function(err, res) {
            let result = null;
            if ((err && err.timeout === _timeout) || typeof(res) === "undefined") {
                result = RequestResults.TIMEOUT;
            } else {
                result = Utils.statusCodeToResult(res.status);
            }
            //console.log("API Response: " + key + ": " + result + " [" +
            //            res.status +"]");
            callback(result, res, context);
        });
    },

    /**
     * Creates full URL given an endpoint suffix.
     * @param {string} endpoint - Endpoint suffice to append to base URL.
     * @returns {string} Full URL of an API endpoint
     */
    getFullEndpoint: function(endpoint) {
        return _urlBase + endpoint;
    },

    /**
     * Create a GET superagent request for a given url and (optionally) token.
     * @param {string} url - URL of the request
     * @param {string} token - Token to use as a Bearer auth token
     * @returns {object} superagent GET request aimed at url
     */
    getRequest: function(url, token) {
        const ret = request
            .get(url)
            .timeout(_timeout);
        if (token !== null && typeof(token) === "string") {
            const tokenStr = "Bearer " + token;
            ret.set("Authorization", tokenStr);
        }
        return ret;
    },

    /**
     * Create a POST superagent request for a given url, body, and (optionally) token.
     * @param {string} url - URL of the request
     * @param {object} body - JSON formatted body for the request
     * @param {string} token - Token to use as a Bearer auth token
     * @returns {object} superagent POST request aimed at url
     */
    postRequest: function(url, body, token) {
        const ret = request
            .post(url)
            .set("Accept", CONTENT_TYPE)
            .set("Content-Type", CONTENT_TYPE)
            .timeout(_timeout);

        if (token !== null && typeof(token) === "string") {
            const tokenStr = "Bearer " + token;
            ret.set("Authorization", tokenStr);
        }

        if (body !== null && typeof(body) !== "undefined") {
            ret.send(body);
        }

        return ret;
    }
};
<commit_msg>Enable persistent connections for HTTP calls.<commit_after>"use strict";
const request = require("superagent");
const Agent = require("https").Agent;

const RequestResults = require("../constants/RequestResults");
const Utils = require("../utils/Utils");

const CONTENT_TYPE = "application/json";

const _DEFAULT_TIMEOUT = 10000;
const _DEFAULT_URL_BASE = "https://api.iobeam.com/v1";

let _urlBase = _DEFAULT_URL_BASE;
let _timeout = _DEFAULT_TIMEOUT;

const _agent = new Agent({
    keepAlive: true,
    keepAliveMsecs: 15000
});

module.exports = {

    /**
     * Setup configuration parameters of this requester object.
     * @param {string} urlBase - Base portion of the URL endpoints for this API
     * (default: https://api.iobeam.com/v1").
     * @param {number} timeout - Milliseconds to wait before timing out a request
     * (default: 10000).
     */
    initialize: function(urlBase, timeout) {
        if (urlBase) {
            _urlBase = urlBase;
        }
        if (timeout) {
            _timeout = timeout;
        }
    },

    /**
     * Execute a superagent HTTP request.
     * @param {object} req - superagent request
     * @param {function} callback - Function to call after the request with status
     * @param {object} context - Related information about this call to pass to callback
     */
    execute: function(req, callback, context) {
        callback(RequestResults.PENDING, null, null);

        req.set("Connection", "keep-alive").agent(_agent).end(function(err, res) {
            let result = null;
            if ((err && err.timeout === _timeout) || typeof(res) === "undefined") {
                result = RequestResults.TIMEOUT;
            } else {
                result = Utils.statusCodeToResult(res.status);
            }
            //console.log("API Response: " + key + ": " + result + " [" +
            //            res.status +"]");
            callback(result, res, context);
        });
    },

    /**
     * Creates full URL given an endpoint suffix.
     * @param {string} endpoint - Endpoint suffice to append to base URL.
     * @returns {string} Full URL of an API endpoint
     */
    getFullEndpoint: function(endpoint) {
        return _urlBase + endpoint;
    },

    /**
     * Create a GET superagent request for a given url and (optionally) token.
     * @param {string} url - URL of the request
     * @param {string} token - Token to use as a Bearer auth token
     * @returns {object} superagent GET request aimed at url
     */
    getRequest: function(url, token) {
        const ret = request
            .get(url)
            .timeout(_timeout);
        if (token !== null && typeof(token) === "string") {
            const tokenStr = "Bearer " + token;
            ret.set("Authorization", tokenStr);
        }
        return ret;
    },

    /**
     * Create a POST superagent request for a given url, body, and (optionally) token.
     * @param {string} url - URL of the request
     * @param {object} body - JSON formatted body for the request
     * @param {string} token - Token to use as a Bearer auth token
     * @returns {object} superagent POST request aimed at url
     */
    postRequest: function(url, body, token) {
        const ret = request
            .post(url)
            .set("Accept", CONTENT_TYPE)
            .set("Content-Type", CONTENT_TYPE)
            .timeout(_timeout);

        if (token !== null && typeof(token) === "string") {
            const tokenStr = "Bearer " + token;
            ret.set("Authorization", tokenStr);
        }

        if (body !== null && typeof(body) !== "undefined") {
            ret.send(body);
        }

        return ret;
    }
};
<|endoftext|>


<commit_before>export const APP_LOCALES = {
  'en-US': 'English',
  ca: 'Català',
  'zh-HANT': '中文 (Chinese Traditional)',
  cs: 'Čeština',
  nl: 'Nederlands',
  fr: 'Français',
  ka: 'ქართული (Georgian)',
  de: 'Deutsch',
  hu: 'Magyar',
  id: 'Bahasa Indonesia',
  ga: 'Gaeilge',
  it: 'Italiano',
  ja: '日本語 (Japanese)',
  pl: 'Polski',
  pt: 'Português',
  'pt-BR': 'Português (Brazil)',
  ru: 'Русский (Russian)',
  sk: 'Slovenčina',
  uk: 'Українська (Ukrainian)',
  'nl-BE': 'Vlaams',
  el: 'ελληνικά (Greek)',
  hr: 'Hrvatski',
  sr: 'Srpski',
  tr: 'Türkçe',
  'zh-TW': '台語 (Chinese Taiwan)',
  es: 'Español',
};

// Hunspell compatible keys
export const SPELLCHECKER_LOCALES = {
  'bg-bg': 'български език',
  'ca-es': 'Català',
  'cs-cz': 'Čeština',
  'da-dk': 'Dansk',
  'de-de': 'Deutsch',
  'el-gr': 'ελληνικά (Greek)',
  'en-us': 'English',
  'es-es': 'Español',
  'et-ee': 'Estonian',
  'fa-ir': 'فارسی (Persian)',
  'fo-fo': 'Faroese',
  'fr-fr': 'Français',
  'he-il': 'עברית (Hebrew)',
  'hr-hr': 'Hrvatski jezik',
  'hu-hu': 'Magyar',
  'it-it': 'Italiano',
  ko: 'Korean',
  'lt-lt': 'Lietuvių kalba',
  'lv-lv': 'Latviešu valoda',
  'nb-no': 'Norsk bokmål',
  'nl-nl': 'Nederlands',
  'pl-pl': 'Język polski',
  'pt-br': 'Português (Brazil)',
  'pt-pt': 'Português',
  'ro-ro': 'Limba română',
  'ru-ru': 'Русский (Russian)',
  'sk-sk': 'Slovenčina',
  'sl-si': 'Slovenski jezik',
  sr: 'Српски језик (Serbian)',
  'sv-se': 'Svenska',
  'ta-in': 'தமிழ் (Tamil)',
  'tg-tg': 'Тоҷикӣ (Tajik)',
  tr: 'Türkçe',
  'uk-ua': 'Українська (Ukrainian)',
  vi: 'Tiếng Việt',
};

export default APP_LOCALES;
<commit_msg>feat(Spell check): Add en-gb spell check languages (#1306)<commit_after>export const APP_LOCALES = {
  'en-US': 'English',
  ca: 'Català',
  'zh-HANT': '中文 (Chinese Traditional)',
  cs: 'Čeština',
  nl: 'Nederlands',
  fr: 'Français',
  ka: 'ქართული (Georgian)',
  de: 'Deutsch',
  hu: 'Magyar',
  id: 'Bahasa Indonesia',
  ga: 'Gaeilge',
  it: 'Italiano',
  ja: '日本語 (Japanese)',
  pl: 'Polski',
  pt: 'Português',
  'pt-BR': 'Português (Brazil)',
  ru: 'Русский (Russian)',
  sk: 'Slovenčina',
  uk: 'Українська (Ukrainian)',
  'nl-BE': 'Vlaams',
  el: 'ελληνικά (Greek)',
  hr: 'Hrvatski',
  sr: 'Srpski',
  tr: 'Türkçe',
  'zh-TW': '台語 (Chinese Taiwan)',
  es: 'Español',
};

// Hunspell compatible keys
export const SPELLCHECKER_LOCALES = {
  'bg-bg': 'български език',
  'ca-es': 'Català',
  'cs-cz': 'Čeština',
  'da-dk': 'Dansk',
  'de-de': 'Deutsch',
  'el-gr': 'ελληνικά (Greek)',
  'en-gb': 'English (GB)',
  'en-us': 'English (US)',
  'es-es': 'Español',
  'et-ee': 'Estonian',
  'fa-ir': 'فارسی (Persian)',
  'fo-fo': 'Faroese',
  'fr-fr': 'Français',
  'he-il': 'עברית (Hebrew)',
  'hr-hr': 'Hrvatski jezik',
  'hu-hu': 'Magyar',
  'it-it': 'Italiano',
  ko: 'Korean',
  'lt-lt': 'Lietuvių kalba',
  'lv-lv': 'Latviešu valoda',
  'nb-no': 'Norsk bokmål',
  'nl-nl': 'Nederlands',
  'pl-pl': 'Język polski',
  'pt-br': 'Português (Brazil)',
  'pt-pt': 'Português',
  'ro-ro': 'Limba română',
  'ru-ru': 'Русский (Russian)',
  'sk-sk': 'Slovenčina',
  'sl-si': 'Slovenski jezik',
  sr: 'Српски језик (Serbian)',
  'sv-se': 'Svenska',
  'ta-in': 'தமிழ் (Tamil)',
  'tg-tg': 'Тоҷикӣ (Tajik)',
  tr: 'Türkçe',
  'uk-ua': 'Українська (Ukrainian)',
  vi: 'Tiếng Việt',
};

export default APP_LOCALES;
<|endoftext|>


<commit_before>new function() {
	var keys = ['windingRule', 'resolution', 'strokeColor',
		'strokeWidth', 'strokeCap', 'strokeJoin', 'dashOffset','dashArray',
		'miterLimit', 'strokeOverprint', 'fillColor', 'fillOverprint'];

	PathStyle = Base.extend({
		initialize: function(item, style) {
			this.item = item;
			if(style) {
				for (var i = 0, l = keys.length; i < l; i++) {
					var key = keys[i];
					if(style[key])
						this[key] = style[key];
				}
			}
		},

		_setChildrenStyle: function(name, value) {
			for (var i = 0, l = this.item.children.length; i < l; i++) {
				this.item.children[i].style[name] = value;
			}
		},

		_getChildrenStyle: function(name) {
			var style;
			for (var i = 0, l = this.item.children.length; i < l; i++) {
				if(!style) {
					style = this.item.children[i].style[name];
				} else if(style != this.item.children[i].style[name]) {
					// If there is another item with a different style:
					return null;
				}
			}
			return style;
		}
	});

	var pathStyleProps = { beans: true };
	var itemProps = { beans: true };

	function addStyleBean(key) {
		pathStyleProps['set' + key.capitalize()] = function(value) {
			if(this.item && this.item.children) {
				this._setChildrenStyle(key, value);
			} else {
				this['_' + key] = value;
			}
		};
		pathStyleProps['get' + key.capitalize()] = function() {
			if(this.item && this.item.children) {
				return this._getChildrenStyle(key);
			} else {
				return this['_' + key];
			}
		};
	}

	function addItemBean(key) {
		itemProps['set' + key.capitalize()] = function(value) {
			this.style[key] = value;
		};
		itemProps['get' + key.capitalize()] = function() {
			return this.style[key];
		};
	}

	for (var i = 0, l = keys.length; i < l; i++) {
		var key = keys[i];
		addStyleBean(key);
		addItemBean(key);
	}
	PathStyle.inject(pathStyleProps);
	Item.inject(itemProps);
};<commit_msg>Use the same simplifications in PathStyle as in CompoundPath, and rely on Base.each as well to provide the scope for closure injection.<commit_after>PathStyle = Base.extend(new function() {
	var keys = ['windingRule', 'resolution', 'strokeColor', 'strokeWidth',
			'strokeCap', 'strokeJoin', 'dashOffset','dashArray', 'miterLimit',
			'strokeOverprint', 'fillColor', 'fillOverprint'];

	var fields = {
		beans: true,

		initialize: function(item, style) {
			this.item = item;
			if(style) {
				for (var i = 0, l = keys.length; i < l; i++) {
					var key = keys[i];
					if(style[key])
						this[key] = style[key];
				}
			}
		},

		_setChildrenStyle: function(name, value) {
			for (var i = 0, l = this.item.children.length; i < l; i++) {
				this.item.children[i].style[name] = value;
			}
		},

		_getChildrenStyle: function(name) {
			var style;
			for (var i = 0, l = this.item.children.length; i < l; i++) {
				if(!style) {
					style = this.item.children[i].style[name];
				} else if(style != this.item.children[i].style[name]) {
					// If there is another item with a different style:
					return null;
				}
			}
			return style;
		}
	}

	var itemProps = { beans: true };

	Base.each(keys, function(key) {

		fields['set' + key.capitalize()] = function(value) {
			if(this.item && this.item.children) {
				this._setChildrenStyle(key, value);
			} else {
				this['_' + key] = value;
			}
		};

		fields['get' + key.capitalize()] = function() {
			if(this.item && this.item.children) {
				return this._getChildrenStyle(key);
			} else {
				return this['_' + key];
			}
		};

		itemProps['set' + key.capitalize()] = function(value) {
			this.style[key] = value;
		};

		itemProps['get' + key.capitalize()] = function() {
			return this.style[key];
		};
	});

	Item.inject(itemProps);

	return fields;
});<|endoftext|>


<commit_before>Ext.define("team-dependency-board", {
    extend: 'Rally.app.App',
    componentCls: 'app',
    logger: new Rally.technicalservices.Logger(),
    defaults: { margin: 10 },
    items: [
        {xtype:'container',itemId:'criteria_box', layout: {type: 'hbox'}},
        {xtype:'container',itemId:'display_box'},
        {xtype:'tsinfolink'}
    ],
    dependencyTag: 'Dependency',
    acceptedDependencyTag: 'Agreed to Dependency',
    tagsOfInterest: ['Dependency','Impediment','Blocker','Agreed to Dependency'],
    giveTagPattern: 'Issuer:',

    tagRefs: {},
    /**
     * controls
     */
    cbRelease: null,

    launch: function() {
        this._getTagRefs();

    },
    _getTagRefs: function(){

        var filters=  Ext.create('Rally.data.wsapi.Filter',{
            property: 'Name',
            value: this.dependencyTag
        });
        filters = filters.or(Ext.create('Rally.data.wsapi.Filter',{
            property: 'Name',
            value: this.acceptedDependencyTag
        }));

        var store = Ext.create('Rally.data.wsapi.Store',{
            model: 'Tag',
            fetch: ['Name','_ref'],
            filters: filters
        });
        store.load({
            scope: this,
            callback: function(records, operation, success){
                this.logger.log('tags fetched',success,records,operation);
                _.each(records, function(r){
                   this.tagRefs[r.get('Name')] = r.get('_ref');
                }, this);

                if (!this.tagRefs[this.acceptedDependencyTag] || !this.tagRefs[this.dependencyTag]){
                    this.add({
                        xtype: 'container',
                        html: Ext.String.format('Please verify the necessary tags for this app have been created or change them in the configuration in the code:

{0}

{1}
',
                            this.acceptedDependencyTag, this.dependencyTag)
                    });
                } else {
                    this._initApp();
                }
                this.logger.log('Tag refs: ',this.tagRefs);
            }
        });
    },
    _createTags: function(tagsToCreate){
        var deferred = Ext.create('Deft.Deferred');
        this.logger.log('_createTags',tagsToCreate);

        Rally.data.ModelFactory.getModel({
            type: 'Tag',
            scope: this,
            success: function(model) {
                this.logger.log('Tag model fetched');

                var promises = [];
                _.each(tagsToCreate, function(tag){
                    var record = Ext.create(model, {
                        Name: tag
                    });
                    promises.push(record.save({
                        callback: function(result, operation) {
                            console.log('tag save returned',operation);
                            var deferred = Ext.create('Deft.Deferred');
                            if(operation.wasSuccessful()) {
                                deferred.resolve(result);
                            } else {
                                deferred.reject(operation);
                            }
                            return deferred;
                        }
                    }));
                });
                Deft.Promise.all(promises).then({
                    success: function(results){
                        deferred.resolve(results);
                    },
                    failure: function(operation){
                        deferred.reject(operation);
                    }
                });
            }
        });
        return deferred;
    },
     _initApp: function(){
        this.cbRelease= this.down('#criteria_box').add({
            xtype: 'rallyreleasecombobox',
            stateful: true,
            stateId: this.getContext().getScopedStateId('cb-release'),
            listeners: {
                scope: this,
                select: this._releaseSelected,
                ready: this._releaseSelected
            }
        });
         this.down('#criteria_box').add({
             xtype: 'rallybutton',
             text: 'Print Cards',
             listeners: {
                 scope: this,
                 click: this._print
             }
         });
    },
    _openPrintWindow:function(store, records, success){
        var giverPattern = new RegExp("^" + this.giveTagPattern,"i");
        var giveTagPrefix = this.giveTagPattern;
        var fields =[{
            dataIndex: 'FormattedID',
            cls: 'cardUpperLeft'
        },
            {
                dataIndex: 'Iteration',
                cls: 'cardUpperRight',
                renderer: function(value,meta_data,record){
                    var iteration = record.get('Iteration');
                    var iteration_name = "Unscheduled";
                    if ( iteration ) {
                        iteration_name = iteration.Name;
                    }

                    return iteration_name;
                }
            },
            {
                dataIndex: 'PlanEstimate',
                cls: 'cardLowerRight',
                renderer: function(value,meta_data,record){
                    if (value){
                        return Ext.String.format('({0})',value);
                    }
                    return '(--)';
                }
            },
            {
                dataIndex: 'Project',
                cls: 'cardLowerLeft',
                renderer: function(value,meta_data,record){
                    var project = record.get('Project');
                    var project_name = "";
                    if (project){
                        project_name = project.Name;
                    }
                    var tags = record.get('Tags');
                    var giver = "";
                    if (tags && tags._tagsNameArray){

                        Ext.each(tags._tagsNameArray, function(tag){
                            if (giverPattern.test(tag.Name)){
                                giver += tag.Name + "
";
                            }
                        });
                    }
                    if (giver.length == 0){
                        giver = giveTagPrefix + " (Not tagged)
";
                    }
                    return Ext.String.format("{0}Receiver: {1}",giver, project_name);
                }
            },
            {
                dataIndex: 'Name',
                maxLength: 100,
                cls: 'cardTitle'

            },{
                dataIndex: 'Feature',
                cls: 'cardSubtitle',
                renderer: function(value,meta_data,record){
                    var feature = 'No Feature';
                    if (record.get('Feature')){
                        feature = Ext.String.format('Feature {0}: {1}',record.get('Feature').FormattedID, record.get('Feature').Name);
                    }
                    return feature;

                }
            }];

        var win = Ext.create('Rally.technicalservices.window.PrintCards',{
            records: records,
            displayFields: fields,
            currentDocument: Ext.getDoc()
        });
        win.show();

    },
    _print: function(){
        var releaseName = this.cbRelease.getRecord().get(this.cbRelease.displayField);

        Ext.create('Rally.data.wsapi.Store',{
            fetch: ['FormattedID','Iteration','Project','Name','Tags','PlanEstimate','Feature'],
            model: 'HierarchicalRequirement',
            filters:  this._getFilters(releaseName),
            autoLoad: true,
            listeners: {
                scope: this,
                load: this._openPrintWindow
            }
        });
    },
    _releaseSelected: function(cb){
        var releaseName = cb.getRecord().get(cb.displayField);
        this._updateCardboard(releaseName);
    },
    _getIterationNameFilter: function(releaseName){
        var iterationNameFilter = null;
        if (releaseName){
            var match = /Release ([\d]*)/.exec(releaseName);
            if (match && match.length > 1){
                return 'R' + match[1];
            }
        }
        return iterationNameFilter;
    },
    _updateCardboard: function(releaseName){
        this.logger.log('_updateCardboard for release ', releaseName);

        if (this.down('#rally-board')){
            this.down('#rally-board').destroy();
        }
        var tagsToFilter = ['^' + this.giveTagPattern].concat(this.tagsOfInterest);
        this.down('#display_box').add({
            itemId: 'rally-board',
            xtype: 'rallycardboard',
            attribute: 'Iteration',
            context: this.getContext(),
            selectedRelease: this.cbRelease.getRecord(),
            iterationNameFilter: this._getIterationNameFilter(releaseName),
            enableRanking: false,
            enableCrossColumnRanking: false,
            columnConfig: {
                enableCrossRowDragging: false,
                dropControllerConfig: false,
                plugins: ['rallycardboardcollapsiblecolumns']
            },
            rowConfig: {
                field: 'Project'
            },
            cardConfig: {
                fields: ['Name','Feature','Tags','PlanEstimate'],
                showPlusIcon: false,
                showRankMenuItems: false,
                showSplitMenuItem: false,
                showColorIcon: true,
                showReadyIcon: false,
                showBlockedIcon: false,
                showAddChildMenuItem: false,
                showCopyTasksFrom: false,
                showDependencyStatus: true,
                tagDependencyRef: this.tagRefs[this.dependencyTag],
                tagAcceptedRef: this.tagRefs[this.acceptedDependencyTag],
                tagsToFilter: tagsToFilter
            },
            storeConfig: {
                filters: this._getFilters(releaseName)
            }
        });
    },
    _getFilters: function(releaseName){
        var filters = [];
        Ext.each(this.tagsOfInterest, function(tag){
            filters.push(Ext.create('Rally.data.wsapi.Filter', {
                property: 'Tags.Name',
                operator: 'contains',
                value: tag
            }));
        });
        filters = Rally.data.wsapi.Filter.or(filters);
        filters = filters.and(Ext.create('Rally.data.wsapi.Filter',{
            property: 'Release.Name',
            value: releaseName
        }));
        return filters;
    }
});
<commit_msg>commiting changes<commit_after>Ext.define("team-dependency-board", {
    extend: 'Rally.app.App',
    componentCls: 'app',
    logger: new Rally.technicalservices.Logger(),
    defaults: { margin: 10 },
    items: [
        {xtype:'container',itemId:'criteria_box', layout: {type: 'hbox'}},
        {xtype:'container',itemId:'display_box'},
        {xtype:'tsinfolink'}
    ],
    dependencyTag: 'Dependency',
    acceptedDependencyTag: 'Agreed to Dependency',
    tagsOfInterest: ['Dependency','Impediment','Blocker','Agreed to Dependency'],
    giveTagPattern: 'Issuer:',

    tagRefs: {},
    /**
     * controls
     */
    cbRelease: null,

    launch: function() {
        this._getTagRefs();

    },
    _getTagRefs: function(){

        var filters=  Ext.create('Rally.data.wsapi.Filter',{
            property: 'Name',
            value: this.dependencyTag
        });
        filters = filters.or(Ext.create('Rally.data.wsapi.Filter',{
            property: 'Name',
            value: this.acceptedDependencyTag
        }));

        var store = Ext.create('Rally.data.wsapi.Store',{
            model: 'Tag',
            fetch: ['Name','_ref'],
            filters: filters
        });
        store.load({
            scope: this,
            callback: function(records, operation, success){
                this.logger.log('tags fetched',success,records,operation);
                _.each(records, function(r){
                   this.tagRefs[r.get('Name')] = r.get('_ref');
                }, this);

                if (!this.tagRefs[this.acceptedDependencyTag] || !this.tagRefs[this.dependencyTag]){
                    this.add({
                        xtype: 'container',
                        html: Ext.String.format('Please verify the necessary tags for this app have been created or change them in the configuration in the code:

{0}

{1}
',
                            this.acceptedDependencyTag, this.dependencyTag)
                    });
                } else {
                    this._initApp();
                }
                this.logger.log('Tag refs: ',this.tagRefs);
            }
        });
    },
    _createTags: function(tagsToCreate){
        var deferred = Ext.create('Deft.Deferred');
        this.logger.log('_createTags',tagsToCreate);

        Rally.data.ModelFactory.getModel({
            type: 'Tag',
            scope: this,
            success: function(model) {
                this.logger.log('Tag model fetched');

                var promises = [];
                _.each(tagsToCreate, function(tag){
                    var record = Ext.create(model, {
                        Name: tag
                    });
                    promises.push(record.save({
                        callback: function(result, operation) {
                            var deferred = Ext.create('Deft.Deferred');
                            if(operation.wasSuccessful()) {
                                deferred.resolve(result);
                            } else {
                                deferred.reject(operation);
                            }
                            return deferred;
                        }
                    }));
                });
                Deft.Promise.all(promises).then({
                    success: function(results){
                        deferred.resolve(results);
                    },
                    failure: function(operation){
                        deferred.reject(operation);
                    }
                });
            }
        });
        return deferred;
    },
     _initApp: function(){
        this.cbRelease= this.down('#criteria_box').add({
            xtype: 'rallyreleasecombobox',
            stateful: true,
            stateId: this.getContext().getScopedStateId('cb-release'),
            listeners: {
                scope: this,
                select: this._releaseSelected,
                ready: this._releaseSelected
            }
        });
         this.down('#criteria_box').add({
             xtype: 'rallybutton',
             text: 'Print Cards',
             listeners: {
                 scope: this,
                 click: this._print
             }
         });
    },
    _openPrintWindow:function(store, records, success){
        var giverPattern = new RegExp("^" + this.giveTagPattern,"i");
        var giveTagPrefix = this.giveTagPattern;
        var fields =[{
            dataIndex: 'FormattedID',
            cls: 'cardUpperLeft'
        },
            {
                dataIndex: 'Iteration',
                cls: 'cardUpperRight',
                renderer: function(value,meta_data,record){
                    var iteration = record.get('Iteration');
                    var iteration_name = "Unscheduled";
                    if ( iteration ) {
                        iteration_name = iteration.Name;
                    }

                    return iteration_name;
                }
            },
            {
                dataIndex: 'PlanEstimate',
                cls: 'cardLowerRight',
                renderer: function(value,meta_data,record){
                    if (value){
                        return Ext.String.format('({0})',value);
                    }
                    return '(--)';
                }
            },
            {
                dataIndex: 'Project',
                cls: 'cardLowerLeft',
                renderer: function(value,meta_data,record){
                    var project = record.get('Project');
                    var project_name = "";
                    if (project){
                        project_name = project.Name;
                    }
                    var tags = record.get('Tags');
                    var giver = "";
                    if (tags && tags._tagsNameArray){

                        Ext.each(tags._tagsNameArray, function(tag){
                            if (giverPattern.test(tag.Name)){
                                giver += tag.Name + "
";
                            }
                        });
                    }
                    if (giver.length == 0){
                        giver = giveTagPrefix + " (Not tagged)
";
                    }
                    return Ext.String.format("{0}Receiver: {1}",giver, project_name);
                }
            },
            {
                dataIndex: 'Name',
                maxLength: 100,
                cls: 'cardTitle'

            },{
                dataIndex: 'Feature',
                cls: 'cardSubtitle',
                renderer: function(value,meta_data,record){
                    var feature = 'No Feature';
                    if (record.get('Feature')){
                        feature = Ext.String.format('Feature {0}: {1}',record.get('Feature').FormattedID, record.get('Feature').Name);
                    }
                    return feature;

                }
            }];

        var win = Ext.create('Rally.technicalservices.window.PrintCards',{
            records: records,
            displayFields: fields,
            currentDocument: Ext.getDoc()
        });
        win.show();

    },
    _print: function(){
        var releaseName = this.cbRelease.getRecord().get(this.cbRelease.displayField);

        Ext.create('Rally.data.wsapi.Store',{
            fetch: ['FormattedID','Iteration','Project','Name','Tags','PlanEstimate','Feature','c_BlockerResolutionDate'],
            model: 'HierarchicalRequirement',
            filters:  this._getFilters(releaseName),
            autoLoad: true,
            listeners: {
                scope: this,
                load: this._openPrintWindow
            }
        });
    },
    _releaseSelected: function(cb){
        var releaseName = cb.getRecord().get(cb.displayField);
        this._updateCardboard(releaseName);
    },
    _getIterationNameFilter: function(releaseName){
        var iterationNameFilter = null;
        if (releaseName){
            var match = /Release ([\d]*)/.exec(releaseName);
            if (match && match.length > 1){
                return 'R' + match[1];
            }
        }
        return iterationNameFilter;
    },
    _updateCardboard: function(releaseName){
        this.logger.log('_updateCardboard for release ', releaseName);

        if (this.down('#rally-board')){
            this.down('#rally-board').destroy();
        }
        var tagsToFilter = ['^' + this.giveTagPattern].concat(this.tagsOfInterest);
        this.down('#display_box').add({
            itemId: 'rally-board',
            xtype: 'rallycardboard',
            attribute: 'Iteration',
            context: this.getContext(),
            selectedRelease: this.cbRelease.getRecord(),
            iterationNameFilter: this._getIterationNameFilter(releaseName),
            enableRanking: false,
            enableCrossColumnRanking: false,
            columnConfig: {
                enableCrossRowDragging: false,
                dropControllerConfig: false,
                plugins: ['rallycardboardcollapsiblecolumns']
            },
            rowConfig: {
                field: 'Project'
            },
            cardConfig: {
                fields: ['Name','Feature','Tags','PlanEstimate'],
                showPlusIcon: false,
                showRankMenuItems: false,
                showSplitMenuItem: false,
                showColorIcon: true,
                showReadyIcon: false,
                showBlockedIcon: false,
                showAddChildMenuItem: false,
                showCopyTasksFrom: false,
                showDependencyStatus: true,
                tagDependencyRef: this.tagRefs[this.dependencyTag],
                tagAcceptedRef: this.tagRefs[this.acceptedDependencyTag],
                tagsToFilter: tagsToFilter
            },
            storeConfig: {
                filters: this._getFilters(releaseName)
            }
        });
    },
    _getFilters: function(releaseName){
        var filters = [];
        Ext.each(this.tagsOfInterest, function(tag){
            filters.push(Ext.create('Rally.data.wsapi.Filter', {
                property: 'Tags.Name',
                operator: 'contains',
                value: tag
            }));
        });
        filters = Rally.data.wsapi.Filter.or(filters);
        filters = filters.and(Ext.create('Rally.data.wsapi.Filter',{
            property: 'Release.Name',
            value: releaseName
        }));
        return filters;
    }
});
<|endoftext|>


<commit_before>
var fs = require("fs"),
    util = require('util')

function Configuratr() {
	this.options = {}
	this.read = function(filename) {
		var contents = fs.readFileSync(filename,'utf8').replace(/(\s*#.*|\s*)$/gm,""),
		    lines = contents.split("\n"),
			kv
		for (var i = 0; i < lines.length; i++) {
			kv = lines[i].split(/\s*=\s*/)
			if (kv.length == 2) {
				if (this.options[kv[0]]) {
					if (typeof(this.options[kv[0]]) == "string" || typeof(this.options[kv[0]]) == "number" ) {
						this.options[kv[0]] = new Array(this.options[kv[0]],kv[1])
					} else {
						this.options[kv[0]].push(kv[1])
					}
				} else {
					this.options[kv[0]] = kv[1]
				}
			}
		};
	}
	this.getString = function (key) {
		var tmp = this.options[key]
		if (typeof(tmp) == "string") {
			return tmp
		} else if (typeof(tmp) == "object") {
			return tmp.pop()
		} else {
			console.log(typeof(tmp))
		}
	}

	this.getNumber = function (key) {
		var tmp = this.options[key]
		if (typeof(tmp) == "string") {
			return parseInt(tmp)
		} else if (typeof(tmp) == "number") {
			return tmp
		} else if (typeof(tmp) == "object") {
			return parseInt(tmp.pop())
		} else {
			console.log(typeof(tmp))
		}
	}

	this.getArray = function(key) {
		var tmp = this.options[key]
		if (util.isArray(tmp)) {
            return tmp
        } else {
            return new Array(tmp)
        }
	}

}

// var cf = new Configuratr()

module.exports = Configuratr
<commit_msg>sections [...] in config file<commit_after>
var fs = require("fs"),
    util = require('util')

function Configuratr() {
	this.options = {}
	this.read = function(filename) {
		var current_section = "options"
		var contents = fs.readFileSync(filename,'utf8').replace(/(\s*#.*|\s*)$/gm,""),
		    lines = contents.split("\n"),
			kv
		for (var i = 0; i < lines.length; i++) {
			var is_new_section = lines[i].match(/\[(.*)\]/)
			if (is_new_section) {
				current_section = is_new_section[1]
				this[current_section] = {}
			}
			kv = lines[i].split(/\s*=\s*/)
			if (kv.length == 2) {
				if (this[current_section][kv[0]]) {
					if (typeof(this[current_section][kv[0]]) == "string" || typeof(this[current_section][kv[0]]) == "number" ) {
						this[current_section][kv[0]] = new Array(this[current_section][kv[0]],kv[1])
					} else {
						this[current_section][kv[0]].push(kv[1])
					}
				} else {
					this[current_section][kv[0]] = kv[1]
				}
			}
		};
	}
	this.getString = function (key,section) {
		var current_section = typeof(section) == "undefined" ?  "options" : section
		var tmp = this[current_section][key]
		if (typeof(tmp) == "string") {
			return tmp
		} else if (typeof(tmp) == "object") {
			return tmp.pop()
		} else {
			console.log(typeof(tmp))
		}
	}

	this.getNumber = function (key,section) {
		var current_section = typeof(section) == "undefined" ?  "options" : section
		var tmp = this[current_section][key]
		if (typeof(tmp) == "string") {
			return parseInt(tmp)
		} else if (typeof(tmp) == "number") {
			return tmp
		} else if (typeof(tmp) == "object") {
			return parseInt(tmp.pop())
		} else {
			console.log(typeof(tmp))
		}
	}

	this.getArray = function(key,section) {
		var current_section = typeof(section) == "undefined" ?  "options" : section
		var tmp = this[current_section][key]
		if (util.isArray(tmp)) {
            return tmp
        } else {
            return new Array(tmp)
        }
	}

}

// var cf = new Configuratr()

module.exports = Configuratr
<|endoftext|>


<commit_before>import { active } from './drop';
import Class from '../mixin/class';
import Container from '../mixin/container';
import {
    $,
    $$,
    addClass,
    after,
    css,
    findIndex,
    hasAttr,
    hasClass,
    height,
    includes,
    isRtl,
    matches,
    noop,
    observeResize,
    offset,
    once,
    parent,
    query,
    remove,
    selFocusable,
    toFloat,
    Transition,
    within,
} from 'uikit-util';

export default {
    mixins: [Class, Container],

    props: {
        dropdown: String,
        mode: 'list',
        align: String,
        offset: Number,
        boundary: Boolean,
        boundaryAlign: Boolean,
        clsDrop: String,
        delayShow: Number,
        delayHide: Number,
        dropbar: Boolean,
        dropbarAnchor: Boolean,
        duration: Number,
    },

    data: {
        dropdown: '.uk-navbar-nav > li > a, .uk-navbar-item, .uk-navbar-toggle',
        align: isRtl ? 'right' : 'left',
        clsDrop: 'uk-navbar-dropdown',
        mode: undefined,
        offset: undefined,
        delayShow: undefined,
        delayHide: undefined,
        boundaryAlign: undefined,
        flip: 'x',
        boundary: true,
        dropbar: false,
        dropbarAnchor: false,
        duration: 200,
        container: false,
    },

    computed: {
        boundary({ boundary }, $el) {
            return boundary === true ? $el : boundary;
        },

        dropbarAnchor({ dropbarAnchor }, $el) {
            return query(dropbarAnchor, $el);
        },

        pos({ align }) {
            return `bottom-${align}`;
        },

        dropbar: {
            get({ dropbar }) {
                if (!dropbar) {
                    return null;
                }

                dropbar =
                    this._dropbar ||
                    query(dropbar, this.$el) ||
                    $('+ .uk-navbar-dropbar', this.$el);

                return dropbar ? dropbar : (this._dropbar = $('

'));
            },

            watch(dropbar) {
                addClass(dropbar, 'uk-navbar-dropbar');
            },

            immediate: true,
        },

        dropContainer(_, $el) {
            return this.container || $el;
        },

        dropdowns: {
            get({ clsDrop }, $el) {
                const dropdowns = $$(`.${clsDrop}`, $el);

                if (this.dropContainer !== $el) {
                    for (const el of $$(`.${clsDrop}`, this.dropContainer)) {
                        const target = this.getDropdown(el)?.target;
                        if (!includes(dropdowns, el) && target && within(target, this.$el)) {
                            dropdowns.push(el);
                        }
                    }
                }

                return dropdowns;
            },

            watch(dropdowns) {
                this.$create(
                    'drop',
                    dropdowns.filter((el) => !this.getDropdown(el)),
                    {
                        ...this.$props,
                        boundary: this.boundary,
                        pos: this.pos,
                        offset: this.dropbar || this.offset,
                    }
                );
            },

            immediate: true,
        },

        toggles: {
            get({ dropdown }, $el) {
                return $$(dropdown, $el);
            },

            watch() {
                const justify = hasClass(this.$el, 'uk-navbar-justify');
                for (const container of $$(
                    '.uk-navbar-nav, .uk-navbar-left, .uk-navbar-right',
                    this.$el
                )) {
                    css(container, 'flexGrow', justify ? $$(this.dropdown, container).length : '');
                }
            },

            immediate: true,
        },
    },

    disconnected() {
        this.dropbar && remove(this.dropbar);
        delete this._dropbar;
    },

    events: [
        {
            name: 'mouseover focusin',

            delegate() {
                return this.dropdown;
            },

            handler({ current }) {
                const active = this.getActive();
                if (
                    active &&
                    includes(active.mode, 'hover') &&
                    active.target &&
                    !within(active.target, current) &&
                    !active.isDelaying
                ) {
                    active.hide(false);
                }
            },
        },

        {
            name: 'keydown',

            delegate() {
                return this.dropdown;
            },

            handler(e) {
                const { current, keyCode } = e;
                const active = this.getActive();

                if (keyCode === keyMap.DOWN && hasAttr(current, 'aria-expanded')) {
                    e.preventDefault();

                    if (!active || active.target !== current) {
                        current.click();
                        once(this.dropContainer, 'show', ({ target }) =>
                            focusFirstFocusableElement(target)
                        );
                    } else {
                        focusFirstFocusableElement(active.$el);
                    }
                }

                handleNavItemNavigation(e, this.toggles, active);
            },
        },

        {
            name: 'keydown',

            el() {
                return this.dropContainer;
            },

            delegate() {
                return `.${this.clsDrop}`;
            },

            handler(e) {
                const { current, keyCode } = e;

                if (!includes(this.dropdowns, current)) {
                    return;
                }

                const active = this.getActive();
                const elements = $$(selFocusable, current);
                const i = findIndex(elements, (el) => matches(el, ':focus'));

                if (keyCode === keyMap.UP) {
                    e.preventDefault();
                    if (i > 0) {
                        elements[i - 1].focus();
                    }
                }

                if (keyCode === keyMap.DOWN) {
                    e.preventDefault();
                    if (i < elements.length - 1) {
                        elements[i + 1].focus();
                    }
                }

                if (keyCode === keyMap.ESC) {
                    active?.target?.focus();
                }

                handleNavItemNavigation(e, this.toggles, active);
            },
        },

        {
            name: 'mouseleave',

            el() {
                return this.dropbar;
            },

            filter() {
                return this.dropbar;
            },

            handler() {
                const active = this.getActive();

                if (
                    active &&
                    includes(active.mode, 'hover') &&
                    !this.dropdowns.some((el) => matches(el, ':hover'))
                ) {
                    active.hide();
                }
            },
        },

        {
            name: 'beforeshow',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(_, { $el }) {
                if (!hasClass($el, this.clsDrop)) {
                    return;
                }

                if (!parent(this.dropbar)) {
                    after(this.dropbarAnchor || this.$el, this.dropbar);
                }

                addClass($el, `${this.clsDrop}-dropbar`);
            },
        },

        {
            name: 'show',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(_, { $el }) {
                if (!hasClass($el, this.clsDrop)) {
                    return;
                }

                this._observer = observeResize($el, () =>
                    this.transitionTo(
                        offset($el).bottom -
                            offset(this.dropbar).top +
                            toFloat(css($el, 'marginBottom')),
                        $el
                    )
                );
            },
        },

        {
            name: 'beforehide',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(e, { $el }) {
                const active = this.getActive();

                if (
                    matches(this.dropbar, ':hover') &&
                    active?.$el === $el &&
                    !this.toggles.some((el) => active.target !== el && matches(el, ':focus'))
                ) {
                    e.preventDefault();
                }
            },
        },

        {
            name: 'hide',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(_, { $el }) {
                if (!hasClass($el, this.clsDrop)) {
                    return;
                }

                this._observer.disconnect();

                const active = this.getActive();

                if (!active || active?.$el === $el) {
                    this.transitionTo(0);
                }
            },
        },
    ],

    methods: {
        getActive() {
            return active && within(active.target, this.$el) && active;
        },

        transitionTo(newHeight, el) {
            const { dropbar } = this;
            const oldHeight = height(dropbar);

            el = oldHeight < newHeight && el;

            css(el, 'clip', `rect(0,${el.offsetWidth}px,${oldHeight}px,0)`);

            height(dropbar, oldHeight);

            Transition.cancel([el, dropbar]);
            Promise.all([
                Transition.start(dropbar, { height: newHeight }, this.duration),
                Transition.start(
                    el,
                    { clip: `rect(0,${el.offsetWidth}px,${newHeight}px,0)` },
                    this.duration
                ),
            ])
                .catch(noop)
                .then(() => css(el, { clip: '' }));
        },

        getDropdown(el) {
            return this.$getComponent(el, 'drop') || this.$getComponent(el, 'dropdown');
        },
    },
};

function handleNavItemNavigation(e, toggles, active) {
    const { current, keyCode } = e;
    const target = active?.target || current;
    const i = toggles.indexOf(target);

    // Left
    if (keyCode === keyMap.LEFT && i > 0) {
        active?.hide(false);
        toggles[i - 1].focus();
    }

    // Right
    if (keyCode === keyMap.RIGHT && i < toggles.length - 1) {
        active?.hide(false);
        toggles[i + 1].focus();
    }

    if (keyCode === keyMap.TAB) {
        target.focus();
        active?.hide(false);
    }
}

function focusFirstFocusableElement(el) {
    if (!$(':focus', el)) {
        $(selFocusable, el)?.focus();
    }
}

const keyMap = {
    TAB: 9,
    ESC: 27,
    LEFT: 37,
    UP: 38,
    RIGHT: 39,
    DOWN: 40,
};
<commit_msg>fix: prevent dropbar when alignment ist set to 'stretch'<commit_after>import { active } from './drop';
import Class from '../mixin/class';
import Container from '../mixin/container';
import {
    $,
    $$,
    addClass,
    after,
    css,
    findIndex,
    hasAttr,
    hasClass,
    height,
    includes,
    isRtl,
    matches,
    noop,
    observeResize,
    offset,
    once,
    parent,
    query,
    remove,
    selFocusable,
    toFloat,
    Transition,
    within,
} from 'uikit-util';

export default {
    mixins: [Class, Container],

    props: {
        dropdown: String,
        mode: 'list',
        align: String,
        offset: Number,
        boundary: Boolean,
        boundaryAlign: Boolean,
        clsDrop: String,
        delayShow: Number,
        delayHide: Number,
        dropbar: Boolean,
        dropbarAnchor: Boolean,
        duration: Number,
    },

    data: {
        dropdown: '.uk-navbar-nav > li > a, .uk-navbar-item, .uk-navbar-toggle',
        align: isRtl ? 'right' : 'left',
        clsDrop: 'uk-navbar-dropdown',
        mode: undefined,
        offset: undefined,
        delayShow: undefined,
        delayHide: undefined,
        boundaryAlign: undefined,
        flip: 'x',
        boundary: true,
        dropbar: false,
        dropbarAnchor: false,
        duration: 200,
        container: false,
    },

    computed: {
        boundary({ boundary }, $el) {
            return boundary === true ? $el : boundary;
        },

        dropbarAnchor({ dropbarAnchor }, $el) {
            return query(dropbarAnchor, $el);
        },

        pos({ align }) {
            return `bottom-${align}`;
        },

        dropbar: {
            get({ dropbar }) {
                if (!dropbar) {
                    return null;
                }

                dropbar =
                    this._dropbar ||
                    query(dropbar, this.$el) ||
                    $('+ .uk-navbar-dropbar', this.$el);

                return dropbar ? dropbar : (this._dropbar = $('

'));
            },

            watch(dropbar) {
                addClass(dropbar, 'uk-navbar-dropbar');
            },

            immediate: true,
        },

        dropContainer(_, $el) {
            return this.container || $el;
        },

        dropdowns: {
            get({ clsDrop }, $el) {
                const dropdowns = $$(`.${clsDrop}`, $el);

                if (this.dropContainer !== $el) {
                    for (const el of $$(`.${clsDrop}`, this.dropContainer)) {
                        const target = this.getDropdown(el)?.target;
                        if (!includes(dropdowns, el) && target && within(target, this.$el)) {
                            dropdowns.push(el);
                        }
                    }
                }

                return dropdowns;
            },

            watch(dropdowns) {
                this.$create(
                    'drop',
                    dropdowns.filter((el) => !this.getDropdown(el)),
                    {
                        ...this.$props,
                        boundary: this.boundary,
                        pos: this.pos,
                        offset: this.dropbar || this.offset,
                    }
                );
            },

            immediate: true,
        },

        toggles: {
            get({ dropdown }, $el) {
                return $$(dropdown, $el);
            },

            watch() {
                const justify = hasClass(this.$el, 'uk-navbar-justify');
                for (const container of $$(
                    '.uk-navbar-nav, .uk-navbar-left, .uk-navbar-right',
                    this.$el
                )) {
                    css(container, 'flexGrow', justify ? $$(this.dropdown, container).length : '');
                }
            },

            immediate: true,
        },
    },

    disconnected() {
        this.dropbar && remove(this.dropbar);
        delete this._dropbar;
    },

    events: [
        {
            name: 'mouseover focusin',

            delegate() {
                return this.dropdown;
            },

            handler({ current }) {
                const active = this.getActive();
                if (
                    active &&
                    includes(active.mode, 'hover') &&
                    active.target &&
                    !within(active.target, current) &&
                    !active.isDelaying
                ) {
                    active.hide(false);
                }
            },
        },

        {
            name: 'keydown',

            delegate() {
                return this.dropdown;
            },

            handler(e) {
                const { current, keyCode } = e;
                const active = this.getActive();

                if (keyCode === keyMap.DOWN && hasAttr(current, 'aria-expanded')) {
                    e.preventDefault();

                    if (!active || active.target !== current) {
                        current.click();
                        once(this.dropContainer, 'show', ({ target }) =>
                            focusFirstFocusableElement(target)
                        );
                    } else {
                        focusFirstFocusableElement(active.$el);
                    }
                }

                handleNavItemNavigation(e, this.toggles, active);
            },
        },

        {
            name: 'keydown',

            el() {
                return this.dropContainer;
            },

            delegate() {
                return `.${this.clsDrop}`;
            },

            handler(e) {
                const { current, keyCode } = e;

                if (!includes(this.dropdowns, current)) {
                    return;
                }

                const active = this.getActive();
                const elements = $$(selFocusable, current);
                const i = findIndex(elements, (el) => matches(el, ':focus'));

                if (keyCode === keyMap.UP) {
                    e.preventDefault();
                    if (i > 0) {
                        elements[i - 1].focus();
                    }
                }

                if (keyCode === keyMap.DOWN) {
                    e.preventDefault();
                    if (i < elements.length - 1) {
                        elements[i + 1].focus();
                    }
                }

                if (keyCode === keyMap.ESC) {
                    active?.target?.focus();
                }

                handleNavItemNavigation(e, this.toggles, active);
            },
        },

        {
            name: 'mouseleave',

            el() {
                return this.dropbar;
            },

            filter() {
                return this.dropbar;
            },

            handler() {
                const active = this.getActive();

                if (
                    active &&
                    includes(active.mode, 'hover') &&
                    !this.dropdowns.some((el) => matches(el, ':hover'))
                ) {
                    active.hide();
                }
            },
        },

        {
            name: 'beforeshow',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(_, { $el, align }) {
                if (!hasClass($el, this.clsDrop) || align === 'stretch') {
                    return;
                }

                if (!parent(this.dropbar)) {
                    after(this.dropbarAnchor || this.$el, this.dropbar);
                }

                addClass($el, `${this.clsDrop}-dropbar`);
            },
        },

        {
            name: 'show',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(_, { $el, align }) {
                if (!hasClass($el, this.clsDrop) || align === 'stretch') {
                    return;
                }

                this._observer = observeResize($el, () =>
                    this.transitionTo(
                        offset($el).bottom -
                            offset(this.dropbar).top +
                            toFloat(css($el, 'marginBottom')),
                        $el
                    )
                );
            },
        },

        {
            name: 'beforehide',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(e, { $el }) {
                const active = this.getActive();

                if (
                    matches(this.dropbar, ':hover') &&
                    active?.$el === $el &&
                    !this.toggles.some((el) => active.target !== el && matches(el, ':focus'))
                ) {
                    e.preventDefault();
                }
            },
        },

        {
            name: 'hide',

            el() {
                return this.dropContainer;
            },

            filter() {
                return this.dropbar;
            },

            handler(_, { $el, align }) {
                if (!hasClass($el, this.clsDrop) || align === 'stretch') {
                    return;
                }

                this._observer.disconnect();

                const active = this.getActive();

                if (!active || active?.$el === $el) {
                    this.transitionTo(0);
                }
            },
        },
    ],

    methods: {
        getActive() {
            return active && within(active.target, this.$el) && active;
        },

        transitionTo(newHeight, el) {
            const { dropbar } = this;
            const oldHeight = height(dropbar);

            el = oldHeight < newHeight && el;

            css(el, 'clip', `rect(0,${el.offsetWidth}px,${oldHeight}px,0)`);

            height(dropbar, oldHeight);

            Transition.cancel([el, dropbar]);
            Promise.all([
                Transition.start(dropbar, { height: newHeight }, this.duration),
                Transition.start(
                    el,
                    { clip: `rect(0,${el.offsetWidth}px,${newHeight}px,0)` },
                    this.duration
                ),
            ])
                .catch(noop)
                .then(() => css(el, { clip: '' }));
        },

        getDropdown(el) {
            return this.$getComponent(el, 'drop') || this.$getComponent(el, 'dropdown');
        },
    },
};

function handleNavItemNavigation(e, toggles, active) {
    const { current, keyCode } = e;
    const target = active?.target || current;
    const i = toggles.indexOf(target);

    // Left
    if (keyCode === keyMap.LEFT && i > 0) {
        active?.hide(false);
        toggles[i - 1].focus();
    }

    // Right
    if (keyCode === keyMap.RIGHT && i < toggles.length - 1) {
        active?.hide(false);
        toggles[i + 1].focus();
    }

    if (keyCode === keyMap.TAB) {
        target.focus();
        active?.hide(false);
    }
}

function focusFirstFocusableElement(el) {
    if (!$(':focus', el)) {
        $(selFocusable, el)?.focus();
    }
}

const keyMap = {
    TAB: 9,
    ESC: 27,
    LEFT: 37,
    UP: 38,
    RIGHT: 39,
    DOWN: 40,
};
<|endoftext|>