<commit_before>/*-------------------------------------------------
    PARSERS for files
    parser['.env']('DB_PASS=s1mpl3')
---------------------------------------------------*/
var parser = {
    // simple json
    '.json': JSON.parse.bind( JSON ),
    // parse env file
    '.env': function ( sourse ) {
        var res = {}, field, value, key = 0, lines = String( sourse ).split('\n');
        for ( ; key < lines.length; key ++ ) {
            field = lines[ key ].match(/^\s*([\w\.\-\$\@\#\*\!\~]+)\s*=+/)[1];
            value = lines[ key ].match(/=\s*(.*)\s*$/)[1].trim();
            if ( field ) res[ field ] = value.replace(/(^['"]|['"]$)/g, '').replace(/\s+/,' ');
        }
        return res;
    }
};

/**
* sync read file
*
* @param path: { String } - suorce path (required)
* @returns: { Object } - js object from file
*/
mapper['read'] = readFileSync;
function readFileSync ( src ) {

    var root = path.dirname(process.mainModule.filename);
    var eval = parser[ path.extname(src) ];

    if ( !eval ) throw new Error('Source path must be specified correctly, with extension(.json .env)');

    return eval( fs.readFileSync( path.join(root, src), 'utf8', 'r') );
}

<commit_msg>* documentation  -- fix variables name (var eval in "use strict" )<commit_after>/*-------------------------------------------------
    PARSERS for files
    parser['.env']('DB_PASS=s1mpl3')
---------------------------------------------------*/
var parser = {
    // simple json
    '.json': JSON.parse.bind( JSON ),
    // parse env file
    '.env': function ( sourse ) {
        var res = {}, field, value, key = 0, lines = String( sourse ).split('\n');
        for ( ; key < lines.length; key ++ ) {
            field = lines[ key ].match(/^\s*([\w\.\-\$\@\#\*\!\~]+)\s*=+/)[1];
            value = lines[ key ].match(/=\s*(.*)\s*$/)[1].trim();
            if ( field ) res[ field ] = value.replace(/(^['"]|['"]$)/g, '').replace(/\s+/,' ');
        }
        return res;
    }
};

/**
* sync read file
*
* @param path: { String } - suorce path (required)
* @returns: { Object } - js object from file
*/
mapper['read'] = readFileSync;
function readFileSync ( src ) {

    var root = path.dirname(process.mainModule.filename);
    var parse = parser[ path.extname(src) ];

    if ( !parse ) throw new Error('Source path must be specified correctly, with extension(.json .env)');

    return parse( fs.readFileSync( path.join(root, src), 'utf8', 'r') );
}

<|endoftext|>


<commit_before>'use strict';

var util = require( '../../../util' );
var math = require( '../../../math' );

var CRp = {};

CRp.eleTextBiggerThanMin = function( ele, scale ){
  if( !scale ){
    var zoom = ele.cy().zoom();
    var pxRatio = this.getPixelRatio();
    var lvl = Math.ceil( math.log2( zoom * pxRatio ) ); // the effective texture level

    scale = Math.pow( 2, lvl );
  }

  var computedSize = ele.pstyle( 'font-size' ).pfValue * scale;
  var minSize = ele.pstyle( 'min-zoomed-font-size' ).pfValue;

  if( computedSize < minSize ){
    return false;
  }

  return true;
};

CRp.drawElementText = function( context, ele, force ){
  var r = this;

  if( force === undefined ){
    if( !r.eleTextBiggerThanMin( ele ) ){ return; }
  } else {
    if( !force ){ return; }
  }

  if( ele.isNode() ){
    var label = ele.pstyle( 'label' );

    if( !label || !label.value ){ return; }

    var textHalign = ele.pstyle( 'text-halign' ).strValue;
    var textValign = ele.pstyle( 'text-valign' ).strValue;

    switch( textHalign ){
      case 'left':
        context.textAlign = 'right';
        break;

      case 'right':
        context.textAlign = 'left';
        break;

      default: // e.g. center
        context.textAlign = 'center';
    }

    context.textBaseline = 'bottom';
  } else {
    var label = ele.pstyle( 'label' );
    var srcLabel = ele.pstyle( 'source-label' );
    var tgtLabel = ele.pstyle( 'target-label' );

    if(
      ( !label || !label.value )
      && ( !srcLabel || !srcLabel.value )
      && ( !tgtLabel || !tgtLabel.value )
    ){
      return;
    }

    context.textAlign = 'center';
    context.textBaseline = 'bottom';
  }

  r.drawText( context, ele );

  if( ele.isEdge() ){
    r.drawText( context, ele, 'source' );

    r.drawText( context, ele, 'target' );
  }
};

CRp.drawNodeText = CRp.drawEdgeText = CRp.drawElementText;

CRp.getFontCache = function( context ){
  var cache;

  this.fontCaches = this.fontCaches || [];

  for( var i = 0; i < this.fontCaches.length; i++ ){
    cache = this.fontCaches[ i ];

    if( cache.context === context ){
      return cache;
    }
  }

  cache = {
    context: context
  };
  this.fontCaches.push( cache );

  return cache;
};

// set up canvas context with font
// returns transformed text string
CRp.setupTextStyle = function( context, ele ){
  // Font style
  var parentOpacity = ele.effectiveOpacity();
  var labelStyle = ele.pstyle( 'font-style' ).strValue;
  var labelSize = ele.pstyle( 'font-size' ).pfValue + 'px';
  var labelFamily = ele.pstyle( 'font-family' ).strValue;
  var labelWeight = ele.pstyle( 'font-weight' ).strValue;
  var opacity = ele.pstyle( 'text-opacity' ).value * ele.pstyle( 'opacity' ).value * parentOpacity;
  var outlineOpacity = ele.pstyle( 'text-outline-opacity' ).value * opacity;
  var color = ele.pstyle( 'color' ).value;
  var outlineColor = ele.pstyle( 'text-outline-color' ).value;
  var shadowBlur = ele.pstyle( 'text-shadow-blur' ).pfValue;
  var shadowOpacity = ele.pstyle( 'text-shadow-opacity' ).value;
  var shadowColor = ele.pstyle( 'text-shadow-color' ).value;
  var shadowOffsetX = ele.pstyle( 'text-shadow-offset-x' ).pfValue;
  var shadowOffsetY = ele.pstyle( 'text-shadow-offset-y' ).pfValue;

  var fontCacheKey = ele._private.fontKey;
  var cache = this.getFontCache( context );

  if( cache.key !== fontCacheKey ){
    context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;

    cache.key = fontCacheKey;
  }

  // Calculate text draw position based on text alignment

  // so text outlines aren't jagged
  context.lineJoin = 'round';

  this.fillStyle( context, color[ 0 ], color[ 1 ], color[ 2 ], opacity );

  this.strokeStyle( context, outlineColor[ 0 ], outlineColor[ 1 ], outlineColor[ 2 ], outlineOpacity );

  this.shadowStyle( context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY );
};

function roundRect( ctx, x, y, width, height, radius ){
  var radius = radius || 5;
  ctx.beginPath();
  ctx.moveTo( x + radius, y );
  ctx.lineTo( x + width - radius, y );
  ctx.quadraticCurveTo( x + width, y, x + width, y + radius );
  ctx.lineTo( x + width, y + height - radius );
  ctx.quadraticCurveTo( x + width, y + height, x + width - radius, y + height );
  ctx.lineTo( x + radius, y + height );
  ctx.quadraticCurveTo( x, y + height, x, y + height - radius );
  ctx.lineTo( x, y + radius );
  ctx.quadraticCurveTo( x, y, x + radius, y );
  ctx.closePath();
  ctx.fill();
}

// Draw text
CRp.drawText = function( context, ele, prefix ){
  var _p = ele._private;
  var rscratch = _p.rscratch;
  var parentOpacity = ele.effectiveOpacity();
  if( parentOpacity === 0 || ele.pstyle( 'text-opacity' ).value === 0 ){
    return;
  }

  var textX = util.getPrefixedProperty( rscratch, 'labelX', prefix );
  var textY = util.getPrefixedProperty( rscratch, 'labelY', prefix );
  var text = this.getLabelText( ele, prefix );

  if( text != null && text !== '' && !isNaN( textX ) && !isNaN( textY ) ){
    this.setupTextStyle( context, ele );

    var pdash = prefix ? prefix + '-' : '';
    var textW = util.getPrefixedProperty( rscratch, 'labelWidth', prefix );
    var textH = util.getPrefixedProperty( rscratch, 'labelHeight', prefix );
    var textAngle = util.getPrefixedProperty( rscratch, 'labelAngle', prefix );
    var marginX = ele.pstyle( pdash + 'text-margin-x' ).pfValue;
    var marginY = ele.pstyle( pdash + 'text-margin-y' ).pfValue;

    var isEdge = ele.isEdge();
    var isNode = ele.isNode();

    var halign = ele.pstyle( 'text-halign' ).value;
    var valign = ele.pstyle( 'text-valign' ).value;

    if( isEdge ){
      halign = 'center';
      valign = 'center';
    }

    textX += marginX;
    textY += marginY;

    var rotation = ele.pstyle( 'text-rotation' );
    var theta;

    if( rotation.strValue === 'autorotate' ){
      theta = isEdge ? textAngle : 0;
    } else if( rotation.strValue === 'none' ){
      theta = 0;
    } else {
      theta = rotation.pfValue;
    }

    if( theta !== 0 ){
      var orgTextX = textX;
      var orgTextY = textY;

      context.translate( orgTextX, orgTextY );
      context.rotate( theta );

      textX = 0;
      textY = 0;
    }

    if( isNode ){
      var pLeft = ele.pstyle( 'padding-left' ).pfValue;
      var pRight = ele.pstyle( 'padding-right' ).pfValue;
      var pTop = ele.pstyle( 'padding-top' ).pfValue;
      var pBottom = ele.pstyle( 'padding-bottom' ).pfValue;

      textX += pLeft / 2;
      textX -= pRight / 2;

      textY += pTop / 2;
      textY -= pBottom / 2;
    }

    var backgroundOpacity = ele.pstyle( 'text-background-opacity' ).value;
    var borderOpacity = ele.pstyle( 'text-border-opacity' ).value;
    var textBorderWidth = ele.pstyle( 'text-border-width' ).pfValue;

    if( backgroundOpacity > 0 || ( textBorderWidth > 0 && borderOpacity > 0 ) ){
      var bgX = textX;

      switch( halign ){
        case 'left':
          bgX -= textW;
          break;
        case 'center':
          bgX -= textW / 2;
          break;
        case 'right':
          break;
      }

      var bgY = textY;

      switch( valign ){
        case 'top':
          bgY -= textH;
          break;
        case 'center':
          bgY -= textH / 2;
          textY += textH / 2;
          break;
        case 'bottom':
          textY += textH;
          break;
      }

      if( backgroundOpacity > 0 ){
        var textFill = context.fillStyle;
        var textBackgroundColor = ele.pstyle( 'text-background-color' ).value;

        context.fillStyle = 'rgba(' + textBackgroundColor[ 0 ] + ',' + textBackgroundColor[ 1 ] + ',' + textBackgroundColor[ 2 ] + ',' + backgroundOpacity * parentOpacity + ')';
        var styleShape = ele.pstyle( 'text-background-shape' ).strValue;
        if( styleShape == 'roundrectangle' ){
          roundRect( context, bgX, bgY, textW, textH, 2 );
        } else {
          context.fillRect( bgX, bgY, textW, textH );
        }
        context.fillStyle = textFill;
      }

      if( textBorderWidth > 0 && borderOpacity > 0 ){
        var textStroke = context.strokeStyle;
        var textLineWidth = context.lineWidth;
        var textBorderColor = ele.pstyle( 'text-border-color' ).value;
        var textBorderStyle = ele.pstyle( 'text-border-style' ).value;

        context.strokeStyle = 'rgba(' + textBorderColor[ 0 ] + ',' + textBorderColor[ 1 ] + ',' + textBorderColor[ 2 ] + ',' + borderOpacity * parentOpacity + ')';
        context.lineWidth = textBorderWidth;

        if( context.setLineDash ){ // for very outofdate browsers
          switch( textBorderStyle ){
            case 'dotted':
              context.setLineDash( [ 1, 1 ] );
              break;
            case 'dashed':
              context.setLineDash( [ 4, 2 ] );
              break;
            case 'double':
              context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders
              context.setLineDash( [] );
              break;
            case 'solid':
              context.setLineDash( [] );
              break;
          }
        }

        context.strokeRect( bgX, bgY, textW, textH );

        if( textBorderStyle === 'double' ){
          var whiteWidth = textBorderWidth / 2;

          context.strokeRect( bgX + whiteWidth, bgY + whiteWidth, textW - whiteWidth * 2, textH - whiteWidth * 2 );
        }

        if( context.setLineDash ){ // for very outofdate browsers
          context.setLineDash( [] );
        }
        context.lineWidth = textLineWidth;
        context.strokeStyle = textStroke;
      }

    }

    var lineWidth = 2 * ele.pstyle( 'text-outline-width' ).pfValue; // *2 b/c the stroke is drawn centred on the middle

    if( lineWidth > 0 ){
      context.lineWidth = lineWidth;
    }

    if( ele.pstyle( 'text-wrap' ).value === 'wrap' ){
      var lines = rscratch.labelWrapCachedLines;
      var lineHeight = textH / lines.length;

      switch( valign ){
        case 'top':
          textY -= ( lines.length - 1 ) * lineHeight;
          break;

        case 'bottom':
          // nothing required
          break;

        default:
        case 'center':
          textY -= ( lines.length - 1 ) * lineHeight / 2;
      }

      for( var l = 0; l < lines.length; l++ ){
        if( lineWidth > 0 ){
          context.strokeText( lines[ l ], textX, textY );
        }

        context.fillText( lines[ l ], textX, textY );

        textY += lineHeight;
      }

    } else {
      if( lineWidth > 0 ){
        context.strokeText( text, textX, textY );
      }

      context.fillText( text, textX, textY );
    }

    if( theta !== 0 ){
      context.rotate( -theta );
      context.translate( -orgTextX, -orgTextY );
    }

    this.shadowStyle( context, 'transparent', 0 ); // reset for next guy
  }
};

module.exports = CRp;
<commit_msg>valign fixed only for labels w/ a background; now fixed for all types #1490<commit_after>'use strict';

var util = require( '../../../util' );
var math = require( '../../../math' );

var CRp = {};

CRp.eleTextBiggerThanMin = function( ele, scale ){
  if( !scale ){
    var zoom = ele.cy().zoom();
    var pxRatio = this.getPixelRatio();
    var lvl = Math.ceil( math.log2( zoom * pxRatio ) ); // the effective texture level

    scale = Math.pow( 2, lvl );
  }

  var computedSize = ele.pstyle( 'font-size' ).pfValue * scale;
  var minSize = ele.pstyle( 'min-zoomed-font-size' ).pfValue;

  if( computedSize < minSize ){
    return false;
  }

  return true;
};

CRp.drawElementText = function( context, ele, force ){
  var r = this;

  if( force === undefined ){
    if( !r.eleTextBiggerThanMin( ele ) ){ return; }
  } else {
    if( !force ){ return; }
  }

  if( ele.isNode() ){
    var label = ele.pstyle( 'label' );

    if( !label || !label.value ){ return; }

    var textHalign = ele.pstyle( 'text-halign' ).strValue;
    var textValign = ele.pstyle( 'text-valign' ).strValue;

    switch( textHalign ){
      case 'left':
        context.textAlign = 'right';
        break;

      case 'right':
        context.textAlign = 'left';
        break;

      default: // e.g. center
        context.textAlign = 'center';
    }

    context.textBaseline = 'bottom';
  } else {
    var label = ele.pstyle( 'label' );
    var srcLabel = ele.pstyle( 'source-label' );
    var tgtLabel = ele.pstyle( 'target-label' );

    if(
      ( !label || !label.value )
      && ( !srcLabel || !srcLabel.value )
      && ( !tgtLabel || !tgtLabel.value )
    ){
      return;
    }

    context.textAlign = 'center';
    context.textBaseline = 'bottom';
  }

  r.drawText( context, ele );

  if( ele.isEdge() ){
    r.drawText( context, ele, 'source' );

    r.drawText( context, ele, 'target' );
  }
};

CRp.drawNodeText = CRp.drawEdgeText = CRp.drawElementText;

CRp.getFontCache = function( context ){
  var cache;

  this.fontCaches = this.fontCaches || [];

  for( var i = 0; i < this.fontCaches.length; i++ ){
    cache = this.fontCaches[ i ];

    if( cache.context === context ){
      return cache;
    }
  }

  cache = {
    context: context
  };
  this.fontCaches.push( cache );

  return cache;
};

// set up canvas context with font
// returns transformed text string
CRp.setupTextStyle = function( context, ele ){
  // Font style
  var parentOpacity = ele.effectiveOpacity();
  var labelStyle = ele.pstyle( 'font-style' ).strValue;
  var labelSize = ele.pstyle( 'font-size' ).pfValue + 'px';
  var labelFamily = ele.pstyle( 'font-family' ).strValue;
  var labelWeight = ele.pstyle( 'font-weight' ).strValue;
  var opacity = ele.pstyle( 'text-opacity' ).value * ele.pstyle( 'opacity' ).value * parentOpacity;
  var outlineOpacity = ele.pstyle( 'text-outline-opacity' ).value * opacity;
  var color = ele.pstyle( 'color' ).value;
  var outlineColor = ele.pstyle( 'text-outline-color' ).value;
  var shadowBlur = ele.pstyle( 'text-shadow-blur' ).pfValue;
  var shadowOpacity = ele.pstyle( 'text-shadow-opacity' ).value;
  var shadowColor = ele.pstyle( 'text-shadow-color' ).value;
  var shadowOffsetX = ele.pstyle( 'text-shadow-offset-x' ).pfValue;
  var shadowOffsetY = ele.pstyle( 'text-shadow-offset-y' ).pfValue;

  var fontCacheKey = ele._private.fontKey;
  var cache = this.getFontCache( context );

  if( cache.key !== fontCacheKey ){
    context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;

    cache.key = fontCacheKey;
  }

  // Calculate text draw position based on text alignment

  // so text outlines aren't jagged
  context.lineJoin = 'round';

  this.fillStyle( context, color[ 0 ], color[ 1 ], color[ 2 ], opacity );

  this.strokeStyle( context, outlineColor[ 0 ], outlineColor[ 1 ], outlineColor[ 2 ], outlineOpacity );

  this.shadowStyle( context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY );
};

function roundRect( ctx, x, y, width, height, radius ){
  var radius = radius || 5;
  ctx.beginPath();
  ctx.moveTo( x + radius, y );
  ctx.lineTo( x + width - radius, y );
  ctx.quadraticCurveTo( x + width, y, x + width, y + radius );
  ctx.lineTo( x + width, y + height - radius );
  ctx.quadraticCurveTo( x + width, y + height, x + width - radius, y + height );
  ctx.lineTo( x + radius, y + height );
  ctx.quadraticCurveTo( x, y + height, x, y + height - radius );
  ctx.lineTo( x, y + radius );
  ctx.quadraticCurveTo( x, y, x + radius, y );
  ctx.closePath();
  ctx.fill();
}

// Draw text
CRp.drawText = function( context, ele, prefix ){
  var _p = ele._private;
  var rscratch = _p.rscratch;
  var parentOpacity = ele.effectiveOpacity();
  if( parentOpacity === 0 || ele.pstyle( 'text-opacity' ).value === 0 ){
    return;
  }

  var textX = util.getPrefixedProperty( rscratch, 'labelX', prefix );
  var textY = util.getPrefixedProperty( rscratch, 'labelY', prefix );
  var text = this.getLabelText( ele, prefix );

  if( text != null && text !== '' && !isNaN( textX ) && !isNaN( textY ) ){
    this.setupTextStyle( context, ele );

    var pdash = prefix ? prefix + '-' : '';
    var textW = util.getPrefixedProperty( rscratch, 'labelWidth', prefix );
    var textH = util.getPrefixedProperty( rscratch, 'labelHeight', prefix );
    var textAngle = util.getPrefixedProperty( rscratch, 'labelAngle', prefix );
    var marginX = ele.pstyle( pdash + 'text-margin-x' ).pfValue;
    var marginY = ele.pstyle( pdash + 'text-margin-y' ).pfValue;

    var isEdge = ele.isEdge();
    var isNode = ele.isNode();

    var halign = ele.pstyle( 'text-halign' ).value;
    var valign = ele.pstyle( 'text-valign' ).value;

    if( isEdge ){
      halign = 'center';
      valign = 'center';
    }

    textX += marginX;
    textY += marginY;

    var rotation = ele.pstyle( 'text-rotation' );
    var theta;

    if( rotation.strValue === 'autorotate' ){
      theta = isEdge ? textAngle : 0;
    } else if( rotation.strValue === 'none' ){
      theta = 0;
    } else {
      theta = rotation.pfValue;
    }

    if( theta !== 0 ){
      var orgTextX = textX;
      var orgTextY = textY;

      context.translate( orgTextX, orgTextY );
      context.rotate( theta );

      textX = 0;
      textY = 0;
    }

    if( isNode ){
      var pLeft = ele.pstyle( 'padding-left' ).pfValue;
      var pRight = ele.pstyle( 'padding-right' ).pfValue;
      var pTop = ele.pstyle( 'padding-top' ).pfValue;
      var pBottom = ele.pstyle( 'padding-bottom' ).pfValue;

      textX += pLeft / 2;
      textX -= pRight / 2;

      textY += pTop / 2;
      textY -= pBottom / 2;
    }

    switch( valign ){
      case 'top':
        break;
      case 'center':
        textY += textH / 2;
        break;
      case 'bottom':
        textY += textH;
        break;
    }

    var backgroundOpacity = ele.pstyle( 'text-background-opacity' ).value;
    var borderOpacity = ele.pstyle( 'text-border-opacity' ).value;
    var textBorderWidth = ele.pstyle( 'text-border-width' ).pfValue;

    if( backgroundOpacity > 0 || ( textBorderWidth > 0 && borderOpacity > 0 ) ){
      var bgX = textX;

      switch( halign ){
        case 'left':
          bgX -= textW;
          break;
        case 'center':
          bgX -= textW / 2;
          break;
        case 'right':
          break;
      }

      var bgY = textY;

      switch( valign ){
        case 'top':
          bgY -= textH;
          break;
        case 'center':
          bgY -= textH / 2;
          break;
        case 'bottom':
          break;
      }

      if( backgroundOpacity > 0 ){
        var textFill = context.fillStyle;
        var textBackgroundColor = ele.pstyle( 'text-background-color' ).value;

        context.fillStyle = 'rgba(' + textBackgroundColor[ 0 ] + ',' + textBackgroundColor[ 1 ] + ',' + textBackgroundColor[ 2 ] + ',' + backgroundOpacity * parentOpacity + ')';
        var styleShape = ele.pstyle( 'text-background-shape' ).strValue;
        if( styleShape == 'roundrectangle' ){
          roundRect( context, bgX, bgY, textW, textH, 2 );
        } else {
          context.fillRect( bgX, bgY, textW, textH );
        }
        context.fillStyle = textFill;
      }

      if( textBorderWidth > 0 && borderOpacity > 0 ){
        var textStroke = context.strokeStyle;
        var textLineWidth = context.lineWidth;
        var textBorderColor = ele.pstyle( 'text-border-color' ).value;
        var textBorderStyle = ele.pstyle( 'text-border-style' ).value;

        context.strokeStyle = 'rgba(' + textBorderColor[ 0 ] + ',' + textBorderColor[ 1 ] + ',' + textBorderColor[ 2 ] + ',' + borderOpacity * parentOpacity + ')';
        context.lineWidth = textBorderWidth;

        if( context.setLineDash ){ // for very outofdate browsers
          switch( textBorderStyle ){
            case 'dotted':
              context.setLineDash( [ 1, 1 ] );
              break;
            case 'dashed':
              context.setLineDash( [ 4, 2 ] );
              break;
            case 'double':
              context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders
              context.setLineDash( [] );
              break;
            case 'solid':
              context.setLineDash( [] );
              break;
          }
        }

        context.strokeRect( bgX, bgY, textW, textH );

        if( textBorderStyle === 'double' ){
          var whiteWidth = textBorderWidth / 2;

          context.strokeRect( bgX + whiteWidth, bgY + whiteWidth, textW - whiteWidth * 2, textH - whiteWidth * 2 );
        }

        if( context.setLineDash ){ // for very outofdate browsers
          context.setLineDash( [] );
        }
        context.lineWidth = textLineWidth;
        context.strokeStyle = textStroke;
      }

    }

    var lineWidth = 2 * ele.pstyle( 'text-outline-width' ).pfValue; // *2 b/c the stroke is drawn centred on the middle

    if( lineWidth > 0 ){
      context.lineWidth = lineWidth;
    }

    if( ele.pstyle( 'text-wrap' ).value === 'wrap' ){
      var lines = rscratch.labelWrapCachedLines;
      var lineHeight = textH / lines.length;

      switch( valign ){
        case 'top':
          textY -= ( lines.length - 1 ) * lineHeight;
          break;

        case 'bottom':
          // nothing required
          break;

        default:
        case 'center':
          textY -= ( lines.length - 1 ) * lineHeight / 2;
      }

      for( var l = 0; l < lines.length; l++ ){
        if( lineWidth > 0 ){
          context.strokeText( lines[ l ], textX, textY );
        }

        context.fillText( lines[ l ], textX, textY );

        textY += lineHeight;
      }

    } else {
      if( lineWidth > 0 ){
        context.strokeText( text, textX, textY );
      }

      context.fillText( text, textX, textY );
    }

    if( theta !== 0 ){
      context.rotate( -theta );
      context.translate( -orgTextX, -orgTextY );
    }

    this.shadowStyle( context, 'transparent', 0 ); // reset for next guy
  }
};

module.exports = CRp;
<|endoftext|>


<commit_before><commit_msg>feat: contanst variable for api url - sierra<commit_after><|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');

var path = require('path');
var util = require('util');

var Q = require('q');
var openApp = require('open');
var shell = require('shelljs');
var nodemon = require('nodemon');
var strftime = require('strftime');

var $ = require('gulp-load-plugins')();

var gitRevision = shell.exec('git rev-parse --short HEAD', { silent:true }).output;

var environments = ['dev', 'www'<% if (useCordova) { %>, 'cordova'<% } %>];

var config = {
    pub: 'public',
    pkg: require('./package.json'),
    src: path.resolve('app'),
    app: path.resolve('app', 'public'),
    models: path.resolve('app', 'models'),
    dist: path.resolve('dist'),<% if (useCordova) { %>
    cordova: path.resolve('cordova/www/'),<% } %>
    buildEnvironment: environments[0],
    temp: path.resolve('.tmp'),
    test: path.resolve('test'),
    server: path.resolve('app', 'app.js'),
    hostname: 'localhost',
    port: 3000,
    baseUrl: '/',
    today: Date.now(),
    revision: (gitRevision.indexOf('fatal') > -1)?null:gitRevision.replace(/(\r\n|\n|\r)/gm, ''),
    version: require('./package.json').version
};

if (!config.revision) {
    $.util.log($.util.colors.yellow('Git repository missing.'), 'Consider running', $.util.colors.cyan('git init'));
}

// task names with underscore (_) prefix will be treated as private
// they will not be exposed as gulp tasks a user can directly run
var tasks = {
    clean: function (isBuild) {
        var glob = [config.temp];
        if (isBuild) {
            glob.push(path.join(config.dist, config.buildEnvironment));
        }
        $.util.log('Cleaning ', $.util.colors.magenta(glob));
        return gulp.src(glob, { read: false })
            .pipe($.rimraf({ force: true }));
    },<% if (useCordova) { %>
    _cleanCordova: function () {
        var glob = path.join(config.cordova, '*');
        $.util.log('Cleaning ', $.util.colors.magenta(glob));
        return gulp.src(glob, { read: false })
            .pipe($.rimraf({ force: true }));
    },<% } %>
    jshint: function () {
        $.util.log('Linting javascript files...');
        var glob = [
            'gulpfile.js',
            path.join(config.src, 'app.js'),
            path.join(config.src, 'routes.js'),
            path.join(config.models, '**/*.js'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js'),
            // exclude loopback services file, it fails miserably
            '!' + path.join(config.app, 'scripts/services/lbServices.js')
        ];
        return gulp.src(glob)
            .pipe($.jshint('.jshintrc'))
            .pipe($.jshint.reporter('jshint-stylish'));
    },
    jsonlint: function () {
        $.util.log('Linting JSON files...');
        var glob = [
            '*.json'
        ];
        return gulp.src(glob)
            .pipe($.jsonlint())
            .pipe($.jsonlint.reporter());
    },
    sass: function (isBuild) {
        $.util.log('Compiling SASS files...');
        var glob = path.join(config.app, 'styles/app.scss');
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.pub, 'styles'):path.join(config.temp, 'styles');
        return gulp.src(glob)
            // as the css is not 1-to-1, this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.css' }))
            .pipe($.rubySass({
                sourcemap: true,
                style: (isBuild && config.buildEnvironment !== 'dev')?'compressed':'expanded',
                precision: 10,
                lineNumbers: (isBuild)?false:true,
                debugInfo: (isBuild)?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    jade: function (isBuild) {
        $.util.log('Compiling Jade files...');
        var glob = [path.join(config.app, '**/*.jade'), path.join('!', config.app, '**/_*.jade')];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.pub):config.temp;
        var LOCALS = {
            DEBUG: (isBuild)?false:true,
            LOCAL: (isBuild)?false:true,
            ENV: (isBuild)?config.buildEnvironment:'local',<% if (useCordova) { %>
            CORDOVA: (config.buildEnvironment === 'cordova')?true:false,<% } %>
            GIT_REVISION: config.revision,
            VERSION: 'v' + config.pkg.version,
            DATE_STAMP: strftime('%B %d, %Y %H:%M:%S', new Date(config.today)),
            YEAR: new Date(config.today).getFullYear()
        };
        return gulp.src(glob)
            // as the jade files are not 1-to-1 this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.html' }))
            .pipe($.jade({
                locals: LOCALS,
                pretty: (isBuild === 'dist' && config.buildEnvironment !== 'dev')?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    image: function (isBuild) {
        $.util.log('Minifing image files...');
        var glob = [
            path.join(config.app, 'images/**/*.{png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{png,jpg,jpeg}'),
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.pub):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe($.imagemin())
            .pipe(gulp.dest(dest));
    },
    _usemin: function (isBuild) {
        $.util.log('Processing usemin js blocks in HTML files...');
        var glob = path.join(config.dist, config.buildEnvironment, config.pub, '*.html');
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.pub):config.temp;
        return gulp.src(glob)
            .pipe($.usemin({
                css: ['concat', $.rev()],
                angularJs: ['concat', $.ngAnnotate(), $.uglify(), $.rev()],
                js: ['concat', $.uglify(), $.rev()]
            }))
            .pipe(gulp.dest(dest));
    },
    _copyAssets: function (isBuild) {
        $.util.log('Copying front end assets into build destination...');
        // copy all assets relative to config.app
        var glob = [
            // copy gif files manually as they are not compressed
            path.join(config.app, 'images/**/*.gif'),
            path.join(config.app, 'styles/**/*.gif'),
            path.join(config.app, 'styles/fonts/**/*'),
            path.join(config.app, 'favicon.ico')
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.pub):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe(gulp.dest(dest));
    },
    _copyServer: function (isBuild) {
        $.util.log('Copying node assets into build destination...');
        // copy all assets relative to config.src
        var glob = [
            path.join(config.models, '**/*'),
            path.join(config.src, 'app.js'),
            path.join(config.src, 'app.json'),
            path.join(config.src, 'datasources.json'),
            path.join(config.src, 'models.json'),
            path.join(config.src, 'views/**/*')
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment):config.temp;
        return gulp.src(glob, { base: config.src })
            .pipe(gulp.dest(dest));
    },
    _copyPackage: function (isBuild) {
        $.util.log('Copying package.json into build destination...');
        // copy all assets relative to root
        var glob = 'package.json';
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment):config.temp;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },<% if (useCordova) { %>
    _copyCordova: function () {
        $.util.log('Copying Cordova build to destination...');
        // copy all assets relative to root
        var glob = path.join(config.dist, config.buildEnvironment, config.pub, '**/*');
        var dest = config.cordova;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },<% } %>
    _addBanner: function (isBuild) {
        $.util.log('Add debug header to files...');
        var glob = [
            path.join(config.dist, config.buildEnvironment, config.pub, '**/*.css'),
            path.join(config.dist, config.buildEnvironment, config.pub, '**/*.js')
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.pub):config.temp;
        var banner = [
            '/**',
            ' * <%%= pkg.title %> - <%%= pkg.description %>',
            ' * @version v<%%= pkg.version %>',
            ' * @link <%%= pkg.homepage %>',
            ' * @license <%%= pkg.license %>',
            ' * @revision <%%= revision %>',
            ' * @build <%%= build %>',
            ' */',
            ''
        ].join('\n');

        return gulp.src(glob)
            .pipe($.header(banner, {
                pkg : config.pkg,
                revision: config.revision,
                build: strftime('%B %d, %Y %H:%M:%S', new Date(config.today))
            }))
            .pipe(gulp.dest(dest));
    }
};

// taskify individual build and server tasks
var taskList = Object.keys(tasks);

taskList.forEach(function (taskName) {
    if (taskName.indexOf('_') === 0) {
        return;
    }
    gulp.task(taskName, function() {
        return tasks[taskName]();
    });
    environments.forEach(function (environment) {
        gulp.task(taskName + ':' + environment, function() {
            config.buildEnvironment = environment;
            return tasks[taskName](true);
        });
    });
});

function queItUp (taskList, isBuild) {
    var deferred = Q.defer();
    var queue = new Q();
    taskList.forEach(function (task) {
        queue = queue.then(function () {
            // cheap conversion of task stream to promise
            var taskDeferred = Q.defer();
            // call the task name with the task type dist|server
            tasks[task](isBuild)
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    taskDeferred.resolve();
                }));
            return taskDeferred.promise;
        });
    });
    queue = queue.then(function explode() {
        deferred.resolve();
    });
    return deferred.promise;
}

function buildProject () {
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade',
        'image',
        '_usemin',
        '_copyAssets',
        '_copyServer',
        '_copyPackage',
        '_addBanner'
    ];
    return queItUp(taskList, true);
}<% if (useCordova) { %>

function deployCordova () {
    // List of build task function names
    var taskList = [
        '_cleanCordova',
        '_copyCordova'
    ];
    return queItUp(taskList);
}<% } %>

function startServer () {
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade'
    ];
    return queItUp(taskList);
}

// Gulp Tasks

// use first environment as default build alias, should be dev
gulp.task('build', ['build:' + environments[0]]);
environments.forEach(function (environment) {
    gulp.task('build:' + environment, function() {
        config.buildEnvironment = environment;
        return buildProject(environment);
    });
});

// serve alias for server
gulp.task('serve', ['server']);
gulp.task('server', function() {
    var deferred = Q.defer();
    startServer().then(function () {
        var server = $.livereload();
        $.util.log('Starting local server...');
        gulp.watch(path.join(config.app, '**/*.{scss,sass}'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.sass()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));

        });
        gulp.watch(path.join(config.app, '**/*.jade'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.jade()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));
        });

        var livereloadGlob = [
            path.join(config.app, 'images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js')
        ];
        gulp.watch(livereloadGlob, function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            server.changed(file.path);
        });

        nodemon({
            script: config.server,
            args: [
                '--port=' + config.port,
                '--hostname=' + config.hostname,
                '--baseurl=' + config.baseUrl,
                '--local'
            ],
            stdout: false,
            watch: [
                config.server,
                config.models
            ]
        })
            .once('start', function () {
                // delay a second, express is not always immediately ready
                setTimeout(function() {
                    openApp('http://' + config.hostname + ':' + config.port + config.baseUrl);
                }, 1000);
            })
            .on('exit', function () {
                deferred.resolve();
            })
            .on('stdout', function (msg) {
                $.util.log('Server:', $.util.colors.magenta(msg));
            });
    });
    return deferred.promise;
});

gulp.task('config.sh', function () {
    var deferred = Q.defer();
    //make .config.sh from package.json for deploy.sh, remote.sh and tail-log.sh
    var fs = require('fs');
    var configFile = [
        '#Auto-generated by grunt build from values in package.json',
        util.format('BASEDOMAIN="%s";', config.pkg.edgeplate.domain),
        util.format('HOST="%s";', config.pkg.edgeplate.host),
        util.format('SSH_PORT="%d";', config.pkg.edgeplate.ports.ssh),
        util.format('DEV_PORT="%d";', config.pkg.edgeplate.ports.dev),
        util.format('WWW_PORT="%d";', config.pkg.edgeplate.ports.www),
        util.format('DIR="%s";', config.pkg.name)
    ].join('\n');
    fs.writeFile('.config.sh', configFile, function (err) {
        if(err) {
            $.util.beep();
            $.util.log($.util.colors.yellow('Config file creation failed:'), err);
        } else {
            $.util.log($.util.colors.cyan('Config file created successfully.'));
        }
        deferred.resolve();
    });
    return deferred.promise;
});<% if (useCordova) { %>

gulp.task('deploy:cordova', ['build:cordova'], function () {
    var deferred = Q.defer();
    config.buildEnvironment = 'cordova';
    $.util.log('Deploying Cordova build...');
    deployCordova(config.buildEnvironment).then(function () {
        process.chdir('cordova');
        var cordovaPrepare = shell.exec('cordova prepare', { silent:true }).output;
        if (cordovaPrepare.length) {
            // successfuly cordova prepare has no output, if we have output there was a problem
            $.util.beep();
            $.util.log($.util.colors.yellow('Cordova prepare failed:'), cordovaPrepare);
        }
        $.util.log($.util.colors.cyan('Cordova deployed successfully.'));
        process.chdir('../');
        deferred.resolve();
    });
    return deferred.promise;
});<% } %>
<commit_msg>Reconfigure gulp file to work with new project structure<commit_after>'use strict';

var gulp = require('gulp');

var path = require('path');
var util = require('util');

var Q = require('q');
var openApp = require('open');
var shell = require('shelljs');
var nodemon = require('nodemon');
var strftime = require('strftime');

var $ = require('gulp-load-plugins')();

var gitRevision = shell.exec('git rev-parse --short HEAD', { silent:true }).output;

var environments = ['dev', 'www', 'cordova'];

var config = {
    pkg: require('./package.json'),
    clientDir: 'app',
    app: path.resolve('app'),
    serverDir: 'server',
    server: path.resolve('server'),
    serverJs: path.resolve('server', 'server.js'),
    commonDir: 'common',
    common: path.resolve('common'),
    dist: path.resolve('dist'),
    cordova: path.resolve('cordova/www/'),
    buildEnvironment: environments[0],
    temp: path.resolve('.tmp'),
    test: path.resolve('test'),
    hostname: 'localhost',
    port: 3000,
    baseUrl: '/',
    today: Date.now(),
    revision: (gitRevision.indexOf('fatal') > -1)?null:gitRevision.replace(/(\r\n|\n|\r)/gm, ''),
    version: require('./package.json').version
};

if (!config.revision) {
    $.util.log($.util.colors.yellow('Git repository missing.'), 'Consider running', $.util.colors.cyan('git init'));
}

// task names with underscore (_) prefix will be treated as private
// they will not be exposed as gulp tasks a user can directly run
var tasks = {
    clean: function (isBuild) {
        var glob = [config.temp];
        if (isBuild) {
            glob.push(path.join(config.dist, config.buildEnvironment));
        }
        $.util.log('Cleaning ', $.util.colors.magenta(glob));
        return gulp.src(glob, { read: false })
            .pipe($.rimraf({ force: true }));
    },
    _cleanCordova: function () {
        var glob = path.join(config.cordova, '*');
        $.util.log('Cleaning ', $.util.colors.magenta(glob));
        return gulp.src(glob, { read: false })
            .pipe($.rimraf({ force: true }));
    },
    jshint: function () {
        $.util.log('Linting javascript files...');
        var glob = [
            'gulpfile.js',
            path.join(config.server, '**/*.js'),
            path.join(config.common, '**/*.js'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js'),
            // exclude loopback services file, it fails miserably
            '!' + path.join(config.app, 'scripts/services/lbServices.js')
        ];
        return gulp.src(glob)
            .pipe($.jshint('.jshintrc'))
            .pipe($.jshint.reporter('jshint-stylish'));
    },
    jsonlint: function () {
        $.util.log('Linting JSON files...');
        var glob = [
            '*.json'
        ];
        return gulp.src(glob)
            .pipe($.jsonlint())
            .pipe($.jsonlint.reporter());
    },
    sass: function (isBuild) {
        $.util.log('Compiling SASS files...');
        var glob = path.join(config.app, 'styles/app.scss');
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.clientDir, 'styles'):path.join(config.temp, 'styles');
        return gulp.src(glob)
            // as the css is not 1-to-1, this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.css' }))
            .pipe($.rubySass({
                sourcemap: true,
                style: (isBuild && config.buildEnvironment !== 'dev')?'compressed':'expanded',
                precision: 10,
                lineNumbers: (isBuild)?false:true,
                debugInfo: (isBuild)?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    jade: function (isBuild) {
        $.util.log('Compiling Jade files...');
        var glob = [path.join(config.app, '**/*.jade'), path.join('!', config.app, '**/_*.jade')];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.clientDir):config.temp;
        var LOCALS = {
            DEBUG: (isBuild)?false:true,
            LOCAL: (isBuild)?false:true,
            ENV: (isBuild)?config.buildEnvironment:'local',
            CORDOVA: (config.buildEnvironment === 'cordova')?true:false,
            GIT_REVISION: config.revision,
            VERSION: 'v' + config.pkg.version,
            DATE_STAMP: strftime('%B %d, %Y %H:%M:%S', new Date(config.today)),
            YEAR: new Date(config.today).getFullYear()
        };
        return gulp.src(glob)
            // as the jade files are not 1-to-1 this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.html' }))
            .pipe($.jade({
                locals: LOCALS,
                pretty: (isBuild === 'dist' && config.buildEnvironment !== 'dev')?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    image: function (isBuild) {
        $.util.log('Minifing image files...');
        var glob = [
            path.join(config.app, 'images/**/*.{png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{png,jpg,jpeg}'),
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.clientDir):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe($.imagemin())
            .pipe(gulp.dest(dest));
    },
    _usemin: function (isBuild) {
        $.util.log('Processing usemin js blocks in HTML files...');
        var glob = path.join(config.dist, config.buildEnvironment, config.clientDir, '*.html');
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.clientDir):config.temp;
        return gulp.src(glob)
            .pipe($.usemin({
                css: ['concat', $.rev()],
                angularJs: ['concat', $.ngAnnotate(), $.uglify(), $.rev()],
                js: ['concat', $.uglify(), $.rev()]
            }))
            .pipe(gulp.dest(dest));
    },
    _copyAssets: function (isBuild) {
        $.util.log('Copying front end assets into build destination...');
        // copy all assets relative to config.app
        var glob = [
            // copy gif files manually as they are not compressed
            path.join(config.app, 'images/**/*.gif'),
            path.join(config.app, 'styles/**/*.gif'),
            path.join(config.app, 'styles/fonts/**/*'),
            path.join(config.app, 'favicon.ico')
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.clientDir):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe(gulp.dest(dest));
    },
    _copyServer: function (isBuild) {
        $.util.log('Copying node server assets into build destination...');
        // copy all assets relative to config.server
        var glob = [
            path.join(config.server, '**/*')
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.serverDir):config.temp;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },
    _copyCommon: function (isBuild) {
        $.util.log('Copying common assets into build destination...');
        // copy all assets relative to config.common
        var glob = [
            path.join(config.common, '**/*')
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.commonDir):config.temp;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },
    _copyPackage: function (isBuild) {
        $.util.log('Copying package.json into build destination...');
        // copy all assets relative to root
        var glob = 'package.json';
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment):config.temp;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },
    _copyCordova: function () {
        $.util.log('Copying Cordova build to destination...');
        // copy all assets relative to root
        var glob = path.join(config.dist, config.buildEnvironment, config.clientDir, '**/*');
        var dest = config.cordova;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },
    _addBanner: function (isBuild) {
        $.util.log('Add debug header to files...');
        var glob = [
            path.join(config.dist, config.buildEnvironment, config.clientDir, '**/*.css'),
            path.join(config.dist, config.buildEnvironment, config.clientDir, '**/*.js')
        ];
        var dest = (isBuild)?path.join(config.dist, config.buildEnvironment, config.clientDir):config.temp;
        var banner = [
            '/**',
            ' * <%= pkg.title %> - <%= pkg.description %>',
            ' * @version v<%= pkg.version %>',
            ' * @link <%= pkg.homepage %>',
            ' * @license <%= pkg.license %>',
            ' * @revision <%= revision %>',
            ' * @build <%= build %>',
            ' */',
            ''
        ].join('\n');

        return gulp.src(glob)
            .pipe($.header(banner, {
                pkg : config.pkg,
                revision: config.revision,
                build: strftime('%B %d, %Y %H:%M:%S', new Date(config.today))
            }))
            .pipe(gulp.dest(dest));
    }
};

// taskify individual build and server tasks
var taskList = Object.keys(tasks);

taskList.forEach(function (taskName) {
    if (taskName.indexOf('_') === 0) {
        return;
    }
    gulp.task(taskName, function() {
        return tasks[taskName]();
    });
    environments.forEach(function (environment) {
        gulp.task(taskName + ':' + environment, function() {
            config.buildEnvironment = environment;
            return tasks[taskName](true);
        });
    });
});

function queItUp (taskList, isBuild) {
    var deferred = Q.defer();
    var queue = new Q();
    taskList.forEach(function (task) {
        queue = queue.then(function () {
            // cheap conversion of task stream to promise
            var taskDeferred = Q.defer();
            // call the task name with the task type dist|server
            tasks[task](isBuild)
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    taskDeferred.resolve();
                }));
            return taskDeferred.promise;
        });
    });
    queue = queue.then(function explode() {
        deferred.resolve();
    });
    return deferred.promise;
}

function buildProject () {
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade',
        'image',
        '_usemin',
        '_copyAssets',
        '_copyServer',
        '_copyCommon',
        '_copyPackage',
        '_addBanner'
    ];
    return queItUp(taskList, true);
}

function deployCordova () {
    // List of build task function names
    var taskList = [
        '_cleanCordova',
        '_copyCordova'
    ];
    return queItUp(taskList);
}

function startServer () {
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade'
    ];
    return queItUp(taskList);
}

// Gulp Tasks

// use first environment as default build alias, should be dev
gulp.task('build', ['build:' + environments[0]]);
environments.forEach(function (environment) {
    gulp.task('build:' + environment, function() {
        config.buildEnvironment = environment;
        return buildProject(environment);
    });
});

// serve alias for server
gulp.task('serve', ['server']);
gulp.task('server', function() {
    var deferred = Q.defer();
    startServer().then(function () {
        var server = $.livereload();
        $.util.log('Starting local server...');
        gulp.watch(path.join(config.app, '**/*.{scss,sass}'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.sass()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));

        });
        gulp.watch(path.join(config.app, '**/*.jade'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.jade()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));
        });

        var livereloadGlob = [
            path.join(config.app, 'images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js')
        ];
        gulp.watch(livereloadGlob, function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            server.changed(file.path);
        });

        nodemon({
            script: config.serverJs,
            args: [
                '-port=' + config.port,
                '-host=' + config.hostname,
                '-baseurl=' + config.baseUrl,
                '-local'
            ],
            stdout: false,
            watch: [
                config.server,
                config.common
            ]
        })
            .once('start', function () {
                // delay a second, express is not always immediately ready
                setTimeout(function() {
                    openApp('http://' + config.hostname + ':' + config.port + config.baseUrl);
                }, 1000);
            })
            .on('exit', function () {
                deferred.resolve();
            })
            .on('stdout', function (msg) {
                $.util.log('Server:', $.util.colors.magenta(msg));
            });
    });
    return deferred.promise;
});

gulp.task('config.sh', function () {
    var deferred = Q.defer();
    //make .config.sh from package.json for deploy.sh, remote.sh and tail-log.sh
    var fs = require('fs');
    var configFile = [
        '#Auto-generated by grunt build from values in package.json',
        util.format('BASEDOMAIN="%s";', config.pkg.edgeplate.domain),
        util.format('HOST="%s";', config.pkg.edgeplate.host),
        util.format('SSH_PORT="%d";', config.pkg.edgeplate.ports.ssh),
        util.format('DEV_PORT="%d";', config.pkg.edgeplate.ports.dev),
        util.format('WWW_PORT="%d";', config.pkg.edgeplate.ports.www),
        util.format('DIR="%s";', config.pkg.name)
    ].join('\n');
    fs.writeFile('.config.sh', configFile, function (err) {
        if(err) {
            $.util.beep();
            $.util.log($.util.colors.yellow('Config file creation failed:'), err);
        } else {
            $.util.log($.util.colors.cyan('Config file created successfully.'));
        }
        deferred.resolve();
    });
    return deferred.promise;
});

gulp.task('deploy:cordova', ['build:cordova'], function () {
    var deferred = Q.defer();
    config.buildEnvironment = 'cordova';
    $.util.log('Deploying Cordova build...');
    deployCordova(config.buildEnvironment).then(function () {
        process.chdir('cordova');
        var cordovaPrepare = shell.exec('cordova prepare', { silent:true }).output;
        if (cordovaPrepare.length) {
            // successfuly cordova prepare has no output, if we have output there was a problem
            $.util.beep();
            $.util.log($.util.colors.yellow('Cordova prepare failed:'), cordovaPrepare);
        }
        $.util.log($.util.colors.cyan('Cordova deployed successfully.'));
        process.chdir('../');
        deferred.resolve();
    });
    return deferred.promise;
});
<|endoftext|>


<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

var assert = require('assert'),
  path = require('path'),
  os = require('os'),
  glob = require('glob'),
  LiveValidator = require('../lib/validators/liveValidator.js'),
  Constants = require('../lib/util/constants');

const livePaths = glob.sync(path.join(__dirname, 'swaggers/**/live/*.json'));

describe('Live Validator', function () {
  describe('Initialization', function () {
    it('should initialize with defaults', function () {
      let options = {
        "swaggerPaths": [],
        "git": {
          "url": "https://github.com/Azure/azure-rest-api-specs.git",
          "shouldClone": false
        },
        "directory": path.resolve(os.homedir(), 'repo')
      };
      let validator = new LiveValidator();
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided swaggerPaths', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": {
          "url": "https://github.com/Azure/azure-rest-api-specs.git",
          "shouldClone": false
        },
        "directory": path.resolve(os.homedir(), 'repo')
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided swaggerPaths & directory', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let directory = "/Users/username/repos/"
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": {
          "url": "https://github.com/Azure/azure-rest-api-specs.git",
          "shouldClone": false
        },
        "directory": directory
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths, "directory": directory });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided partial git configuration', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let directory = "/Users/username/repos/"
      let git = {
        "url": "https://github.com/vishrutshah/azure-rest-api-specs.git"
      }
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": {
          "url": git.url,
          "shouldClone": false
        },
        "directory": directory
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths, "directory": directory, "git": git });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided full git configuration', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let directory = "/Users/username/repos/"
      let git = {
        "url": "https://github.com/vishrutshah/azure-rest-api-specs.git",
        "shouldClone": true
      }
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": git,
        "directory": directory
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths, "directory": directory, "git": git });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should throw on invalid options types', function () {
      assert.throws(() => {
        new LiveValidator('string');
      }, /must be of type "object"/);
      assert.throws(() => {
        new LiveValidator({ "swaggerPaths": "should be array" });
      }, /must be of type "array"/);
      assert.throws(() => {
        new LiveValidator({ "git": 1 });
      }, /must be of type "object"/);
      assert.throws(() => {
        new LiveValidator({ "git": { "url": [] } });
      }, /must be of type "string"/);
      assert.throws(() => {
        new LiveValidator({ "git": { "url": "url", "shouldClone": "no" } });
      }, /must be of type "boolean"/);
    });
  });

  describe('Initialize cache', function () {
    it('should initialize for arm-mediaservices', function (done) {
      let expectedProvider = 'microsoft.media';
      let expectedApiVersion = '2015-10-01';
      let options = {
        "directory": "./test/swaggers/"
      };
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        assert.equal(true, expectedProvider in validator.cache);
        assert.equal(6, Object.keys(validator.cache).length);
        assert.equal(true, expectedApiVersion in (validator.cache[expectedProvider]));
        assert.equal(1, Object.keys(validator.cache[expectedProvider]).length);
        assert.equal(2, validator.cache[expectedProvider][expectedApiVersion]['get'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['put'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['patch'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['delete'].length);
        assert.equal(4, validator.cache[expectedProvider][expectedApiVersion]['post'].length);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
    it('should initialize for arm-resources', function (done) {
      let expectedProvider = 'microsoft.resources';
      let expectedApiVersion = '2016-09-01';
      let options = {
        "directory": "./test/swaggers/"
      };
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        assert.equal(true, expectedProvider in validator.cache);
        assert.equal(6, Object.keys(validator.cache).length);
        assert.equal(true, expectedApiVersion in (validator.cache[expectedProvider]));
        assert.equal(1, Object.keys(validator.cache[expectedProvider]).length);
        // 'microsoft.resources' -> '2016-09-01'
        assert.equal(2, validator.cache[expectedProvider][expectedApiVersion]['get'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['delete'].length);
        assert.equal(3, validator.cache[expectedProvider][expectedApiVersion]['post'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['head'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['put'].length);
        // 'microsoft.unknown' -> 'unknown-api-version'
        assert.equal(4, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['post'].length);
        assert.equal(11, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['get'].length);
        assert.equal(3, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['head'].length);
        assert.equal(5, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['put'].length);
        assert.equal(5, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['delete'].length);
        assert.equal(1, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['patch'].length);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
    it('should initialize for all swaggers', function (done) {
      let options = {
        "directory": "./test/swaggers/"
      };
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        assert.equal(6, Object.keys(validator.cache).length);
        assert.equal(2, validator.cache['microsoft.resources']['2016-09-01']['get'].length);
        assert.equal(1, validator.cache['microsoft.resources']['2016-09-01']['head'].length);
        assert.equal(1, validator.cache['microsoft.media']['2015-10-01']['patch'].length);
        assert.equal(4, validator.cache['microsoft.media']['2015-10-01']['post'].length);
        assert.equal(2, validator.cache['microsoft.search']['2015-02-28']['get'].length);
        assert.equal(3, validator.cache['microsoft.search']['2015-08-19']['get'].length);
        assert.equal(1, validator.cache['microsoft.storage']['2015-05-01-preview']['patch'].length);
        assert.equal(4, validator.cache['microsoft.storage']['2015-06-15']['get'].length);
        assert.equal(3, validator.cache['microsoft.storage']['2016-01-01']['post'].length);
        assert.equal(4, validator.cache['microsoft.test']['2016-01-01']['post'].length);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
  });

  describe('Initialize cache and search', function () {
    it('should return one matched operation for arm-storage', function (done) {
      let options = {
        "directory": "./test/swaggers/"
      };
      let listRequestUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts?api-version=2015-06-15";
      let postRequestUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/checkNameAvailability?api-version=2015-06-15";
      let deleteRequestUrl = "https://management.azure.com/subscriptions/subscriptionId/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/accname?api-version=2015-06-15";
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        // Operations to match is StorageAccounts_List
        let operations = validator.getPotentialOperations(listRequestUrl, 'Get').operations;
        assert.equal(1, operations.length);
        assert.equal("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/storageAccounts", operations[0].pathObject.path);

        // Operations to match is StorageAccounts_CheckNameAvailability
        operations = validator.getPotentialOperations(postRequestUrl, 'PoSt').operations;
        assert.equal(1, operations.length);
        assert.equal("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/checkNameAvailability", operations[0].pathObject.path);

        // Operations to match is StorageAccounts_Delete
        operations = validator.getPotentialOperations(deleteRequestUrl, 'delete').operations;
        assert.equal(1, operations.length);
        assert.equal("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", operations[0].pathObject.path);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
    it('should return reason for not matched operations', function (done) {
      let options = {
        "directory": "./test/swaggers/"
      };
      let nonCachedApiUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts?api-version=2015-08-15";
      let nonCachedProviderUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Hello.World/checkNameAvailability?api-version=2015-06-15";
      let nonCachedVerbUrl = "https://management.azure.com/subscriptions/subscriptionId/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/accname?api-version=2015-06-15";
      let nonCachedPath = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts/accountName/properties?api-version=2015-06-15";
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        // Operations to match is StorageAccounts_List with api-version 2015-08-15 [non cached api version]
        let result = validator.getPotentialOperations(nonCachedApiUrl, 'Get');
        let operations = result.operations;
        let reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCacheWithApi.name, reason.code);

        // Operations to match is StorageAccounts_CheckNameAvailability with provider "Hello.World" [non cached provider]
        result = validator.getPotentialOperations(nonCachedProviderUrl, 'PoSt');
        operations = result.operations;
        reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCacheWithProvider.name, reason.code);

        // Operations to match is StorageAccounts_Delete with verb "head" [non cached http verb]
        result = validator.getPotentialOperations(nonCachedVerbUrl, 'head');
        operations = result.operations;
        reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCacheWithVerb.name, reason.code);

        // Operations to match is with path "subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts/storageAccounts/accountName/properties/" [non cached path]
        result = validator.getPotentialOperations(nonCachedPath, 'get');
        operations = result.operations;
        reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCache.name, reason.code);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
  });

  describe('Initialize cache and validate', function () {
    livePaths.forEach((livePath) => {
      it(`should validate request and response for "${livePath}"`, function (done) {
        let options = {
          "directory": "./test/swaggers/specification/storage"
        };
        let validator = new LiveValidator(options);
        validator.initialize().then(function () {
          let reqRes = require(livePath);
          let validationResult = validator.validateLiveRequestResponse(reqRes);
          console.dir(validationResult, { depth: null, colors: true });
          done();
        }).catch((err) => {
          assert.ifError(err);
          done();
        }).catch(done);
      });
    });
  });
});
<commit_msg>Adding one more get method need update on live validator tests<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

var assert = require('assert'),
  path = require('path'),
  os = require('os'),
  glob = require('glob'),
  LiveValidator = require('../lib/validators/liveValidator.js'),
  Constants = require('../lib/util/constants');

const livePaths = glob.sync(path.join(__dirname, 'swaggers/**/live/*.json'));

describe('Live Validator', function () {
  describe('Initialization', function () {
    it('should initialize with defaults', function () {
      let options = {
        "swaggerPaths": [],
        "git": {
          "url": "https://github.com/Azure/azure-rest-api-specs.git",
          "shouldClone": false
        },
        "directory": path.resolve(os.homedir(), 'repo')
      };
      let validator = new LiveValidator();
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided swaggerPaths', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": {
          "url": "https://github.com/Azure/azure-rest-api-specs.git",
          "shouldClone": false
        },
        "directory": path.resolve(os.homedir(), 'repo')
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided swaggerPaths & directory', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let directory = "/Users/username/repos/"
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": {
          "url": "https://github.com/Azure/azure-rest-api-specs.git",
          "shouldClone": false
        },
        "directory": directory
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths, "directory": directory });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided partial git configuration', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let directory = "/Users/username/repos/"
      let git = {
        "url": "https://github.com/vishrutshah/azure-rest-api-specs.git"
      }
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": {
          "url": git.url,
          "shouldClone": false
        },
        "directory": directory
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths, "directory": directory, "git": git });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should initialize with user provided full git configuration', function () {
      let swaggerPaths = ["swaggerPath1", "swaggerPath2"];
      let directory = "/Users/username/repos/"
      let git = {
        "url": "https://github.com/vishrutshah/azure-rest-api-specs.git",
        "shouldClone": true
      }
      let options = {
        "swaggerPaths": swaggerPaths,
        "git": git,
        "directory": directory
      };
      let validator = new LiveValidator({ "swaggerPaths": swaggerPaths, "directory": directory, "git": git });
      assert.deepEqual(validator.cache, {});
      assert.deepEqual(validator.options, options);
    });
    it('should throw on invalid options types', function () {
      assert.throws(() => {
        new LiveValidator('string');
      }, /must be of type "object"/);
      assert.throws(() => {
        new LiveValidator({ "swaggerPaths": "should be array" });
      }, /must be of type "array"/);
      assert.throws(() => {
        new LiveValidator({ "git": 1 });
      }, /must be of type "object"/);
      assert.throws(() => {
        new LiveValidator({ "git": { "url": [] } });
      }, /must be of type "string"/);
      assert.throws(() => {
        new LiveValidator({ "git": { "url": "url", "shouldClone": "no" } });
      }, /must be of type "boolean"/);
    });
  });

  describe('Initialize cache', function () {
    it('should initialize for arm-mediaservices', function (done) {
      let expectedProvider = 'microsoft.media';
      let expectedApiVersion = '2015-10-01';
      let options = {
        "directory": "./test/swaggers/"
      };
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        assert.equal(true, expectedProvider in validator.cache);
        assert.equal(6, Object.keys(validator.cache).length);
        assert.equal(true, expectedApiVersion in (validator.cache[expectedProvider]));
        assert.equal(1, Object.keys(validator.cache[expectedProvider]).length);
        assert.equal(2, validator.cache[expectedProvider][expectedApiVersion]['get'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['put'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['patch'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['delete'].length);
        assert.equal(4, validator.cache[expectedProvider][expectedApiVersion]['post'].length);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
    it('should initialize for arm-resources', function (done) {
      let expectedProvider = 'microsoft.resources';
      let expectedApiVersion = '2016-09-01';
      let options = {
        "directory": "./test/swaggers/"
      };
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        assert.equal(true, expectedProvider in validator.cache);
        assert.equal(6, Object.keys(validator.cache).length);
        assert.equal(true, expectedApiVersion in (validator.cache[expectedProvider]));
        assert.equal(1, Object.keys(validator.cache[expectedProvider]).length);
        // 'microsoft.resources' -> '2016-09-01'
        assert.equal(2, validator.cache[expectedProvider][expectedApiVersion]['get'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['delete'].length);
        assert.equal(3, validator.cache[expectedProvider][expectedApiVersion]['post'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['head'].length);
        assert.equal(1, validator.cache[expectedProvider][expectedApiVersion]['put'].length);
        // 'microsoft.unknown' -> 'unknown-api-version'
        assert.equal(4, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['post'].length);
        assert.equal(12, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['get'].length);
        assert.equal(3, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['head'].length);
        assert.equal(5, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['put'].length);
        assert.equal(5, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['delete'].length);
        assert.equal(1, validator.cache[Constants.unknownResourceProvider][Constants.unknownApiVersion]['patch'].length);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
    it('should initialize for all swaggers', function (done) {
      let options = {
        "directory": "./test/swaggers/"
      };
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        assert.equal(6, Object.keys(validator.cache).length);
        assert.equal(2, validator.cache['microsoft.resources']['2016-09-01']['get'].length);
        assert.equal(1, validator.cache['microsoft.resources']['2016-09-01']['head'].length);
        assert.equal(1, validator.cache['microsoft.media']['2015-10-01']['patch'].length);
        assert.equal(4, validator.cache['microsoft.media']['2015-10-01']['post'].length);
        assert.equal(2, validator.cache['microsoft.search']['2015-02-28']['get'].length);
        assert.equal(3, validator.cache['microsoft.search']['2015-08-19']['get'].length);
        assert.equal(1, validator.cache['microsoft.storage']['2015-05-01-preview']['patch'].length);
        assert.equal(4, validator.cache['microsoft.storage']['2015-06-15']['get'].length);
        assert.equal(3, validator.cache['microsoft.storage']['2016-01-01']['post'].length);
        assert.equal(4, validator.cache['microsoft.test']['2016-01-01']['post'].length);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
  });

  describe('Initialize cache and search', function () {
    it('should return one matched operation for arm-storage', function (done) {
      let options = {
        "directory": "./test/swaggers/"
      };
      let listRequestUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts?api-version=2015-06-15";
      let postRequestUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/checkNameAvailability?api-version=2015-06-15";
      let deleteRequestUrl = "https://management.azure.com/subscriptions/subscriptionId/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/accname?api-version=2015-06-15";
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        // Operations to match is StorageAccounts_List
        let operations = validator.getPotentialOperations(listRequestUrl, 'Get').operations;
        assert.equal(1, operations.length);
        assert.equal("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/storageAccounts", operations[0].pathObject.path);

        // Operations to match is StorageAccounts_CheckNameAvailability
        operations = validator.getPotentialOperations(postRequestUrl, 'PoSt').operations;
        assert.equal(1, operations.length);
        assert.equal("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/checkNameAvailability", operations[0].pathObject.path);

        // Operations to match is StorageAccounts_Delete
        operations = validator.getPotentialOperations(deleteRequestUrl, 'delete').operations;
        assert.equal(1, operations.length);
        assert.equal("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", operations[0].pathObject.path);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
    it('should return reason for not matched operations', function (done) {
      let options = {
        "directory": "./test/swaggers/"
      };
      let nonCachedApiUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts?api-version=2015-08-15";
      let nonCachedProviderUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Hello.World/checkNameAvailability?api-version=2015-06-15";
      let nonCachedVerbUrl = "https://management.azure.com/subscriptions/subscriptionId/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/accname?api-version=2015-06-15";
      let nonCachedPath = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts/accountName/properties?api-version=2015-06-15";
      let validator = new LiveValidator(options);
      validator.initialize().then(function () {
        // Operations to match is StorageAccounts_List with api-version 2015-08-15 [non cached api version]
        let result = validator.getPotentialOperations(nonCachedApiUrl, 'Get');
        let operations = result.operations;
        let reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCacheWithApi.name, reason.code);

        // Operations to match is StorageAccounts_CheckNameAvailability with provider "Hello.World" [non cached provider]
        result = validator.getPotentialOperations(nonCachedProviderUrl, 'PoSt');
        operations = result.operations;
        reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCacheWithProvider.name, reason.code);

        // Operations to match is StorageAccounts_Delete with verb "head" [non cached http verb]
        result = validator.getPotentialOperations(nonCachedVerbUrl, 'head');
        operations = result.operations;
        reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCacheWithVerb.name, reason.code);

        // Operations to match is with path "subscriptions/subscriptionId/providers/Microsoft.Storage/storageAccounts/storageAccounts/accountName/properties/" [non cached path]
        result = validator.getPotentialOperations(nonCachedPath, 'get');
        operations = result.operations;
        reason = result.reason;
        assert.equal(0, operations.length);
        assert.equal(Constants.ErrorCodes.OperationNotFoundInCache.name, reason.code);
        done();
      }).catch((err) => {
        assert.ifError(err);
        done();
      }).catch(done);
    });
  });

  describe('Initialize cache and validate', function () {
    livePaths.forEach((livePath) => {
      it(`should validate request and response for "${livePath}"`, function (done) {
        let options = {
          "directory": "./test/swaggers/specification/storage"
        };
        let validator = new LiveValidator(options);
        validator.initialize().then(function () {
          let reqRes = require(livePath);
          let validationResult = validator.validateLiveRequestResponse(reqRes);
          console.dir(validationResult, { depth: null, colors: true });
          done();
        }).catch((err) => {
          assert.ifError(err);
          done();
        }).catch(done);
      });
    });
  });
});
<|endoftext|>


<commit_before>var datepickers = $(".datepicker");
if (datepickers.length) {
    datepickers.datepicker({
        "format": "dd.mm.yyyy",
        "autoclose": true,
        "weekStart": 1,
        "language": "pl"
    });
}

var palenie_switcher = $(".palenie-switcher");
if (palenie_switcher.length) {
    var palenie_choices = $("input[name='app_badanie_badaniebundle_badanietype[papierosy][kind]']");
    function palenie_show_hide(val) {
        $(".form-palenie-switcher").hide();
        $(".form-palenie-switcher input").attr("disabled", true);
        $(".form-" + val)
            .show()
            .find("input")
            .attr("disabled", false)
        ;
    }
    palenie_choices.on("change", function () {
        palenie_show_hide($(this).val());
    });
    var palenie_active = $("input[name='app_badanie_badaniebundle_badanietype[papierosy][kind]']:checked");
    palenie_show_hide(palenie_active.val());
}

var alkohol_switcher = $(".alkohol-switcher");
if (alkohol_switcher.length) {
    var alkohol_choices = $("input[name='app_badanie_badaniebundle_badanietype[alkohol][kind]']");
    function alkohol_show_hide(val) {
        $(".form-alkohol-switcher").hide();
        $(".form-palenie-switcher input").attr("disabled", true);
        $(".form-" + val)
            .show()
            .find("input")
            .attr("disabled", false)
        ;
    }
    alkohol_choices.on("change", function () {
        alkohol_show_hide($(this).val());
    });
    var alkohol_active = $("input[name='app_badanie_badaniebundle_badanietype[alkohol][kind]']:checked");
    alkohol_show_hide(alkohol_active.val());

    $("#app_badanie_badaniebundle_badanietype_alkohol_pijacy_przedBadaniem")
        .on("change", function () {
            var el = $(".pijacy-additional");
            if ($(this).is(':checked')) {
                el.show();
            }
            else {
                el.hide().find("input").val(null);
            }
        })
        .trigger("change")
    ;
}
<commit_msg>Fixed JS<commit_after>var datepickers = $(".datepicker");
if (datepickers.length) {
    datepickers.datepicker({
        "format": "dd.mm.yyyy",
        "autoclose": true,
        "weekStart": 1,
        "language": "pl"
    });
}

var palenie_switcher = $(".palenie-switcher");
if (palenie_switcher.length) {
    var palenie_choices = $("input[name='app_badanie_badaniebundle_badanietype[papierosy][kind]']");
    function palenie_show_hide(val) {
        $(".form-palenie-switcher").hide();
        $(".form-palenie-switcher input").attr("disabled", true);
        $(".form-" + val)
            .show()
            .find("input")
            .attr("disabled", false)
        ;
    }
    palenie_choices.on("change", function () {
        palenie_show_hide($(this).val());
    });
    var palenie_active = $("input[name='app_badanie_badaniebundle_badanietype[papierosy][kind]']:checked");
    palenie_show_hide(palenie_active.val());
}

var alkohol_switcher = $(".alkohol-switcher");
if (alkohol_switcher.length) {
    var alkohol_choices = $("input[name='app_badanie_badaniebundle_badanietype[alkohol][kind]']");
    function alkohol_show_hide(val) {
        $(".form-alkohol-switcher").hide();
        $(".form-alkohol-switcher input").attr("disabled", true);
        $(".form-" + val)
            .show()
            .find("input")
            .attr("disabled", false)
        ;
    }
    alkohol_choices.on("change", function () {
        alkohol_show_hide($(this).val());
    });
    var alkohol_active = $("input[name='app_badanie_badaniebundle_badanietype[alkohol][kind]']:checked");
    alkohol_show_hide(alkohol_active.val());

    $("#app_badanie_badaniebundle_badanietype_alkohol_pijacy_przedBadaniem")
        .on("change", function () {
            var el = $(".pijacy-additional");
            if ($(this).is(':checked')) {
                el.show();
            }
            else {
                el.hide().find("input").val(null);
            }
        })
        .trigger("change")
    ;
}
<|endoftext|>


<commit_before>/**
 *
 * Generated from https://translate.google.com
 *
 * The languages that Google Translate supports (as of 5/15/16) alongside with their ISO 639-1 codes
 * See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
 */

var langs = {
    'auto': 'Automatic',
    'af': 'Afrikaans',
    'sq': 'Albanian',
    'ar': 'Arabic',
    'hy': 'Armenian',
    'az': 'Azerbaijani',
    'eu': 'Basque',
    'be': 'Belarusian',
    'bn': 'Bengali',
    'bs': 'Bosnian',
    'bg': 'Bulgarian',
    'ca': 'Catalan',
    'ceb': 'Cebuano',
    'ny': 'Chichewa',
    'zh-CN': 'Chinese Simplified',
    'zh-TW': 'Chinese Traditional',
    'co': 'Corsican',
    'hr': 'Croatian',
    'cs': 'Czech',
    'da': 'Danish',
    'nl': 'Dutch',
    'en': 'English',
    'eo': 'Esperanto',
    'et': 'Estonian',
    'tl': 'Filipino',
    'fi': 'Finnish',
    'fr': 'French',
    'fy': 'Frisian',
    'gl': 'Galician',
    'ka': 'Georgian',
    'de': 'German',
    'el': 'Greek',
    'gu': 'Gujarati',
    'ht': 'Haitian Creole',
    'ha': 'Hausa',
    'haw': 'Hawaiian',
    'iw': 'Hebrew',
    'hi': 'Hindi',
    'hmn': 'Hmong',
    'hu': 'Hungarian',
    'is': 'Icelandic',
    'ig': 'Igbo',
    'id': 'Indonesian',
    'ga': 'Irish',
    'it': 'Italian',
    'ja': 'Japanese',
    'jw': 'Javanese',
    'kn': 'Kannada',
    'kk': 'Kazakh',
    'km': 'Khmer',
    'ko': 'Korean',
    'ku': 'Kurdish (Kurmanji)',
    'ky': 'Kyrgyz',
    'lo': 'Lao',
    'la': 'Latin',
    'lv': 'Latvian',
    'lt': 'Lithuanian',
    'lb': 'Luxembourgish',
    'mk': 'Macedonian',
    'mg': 'Malagasy',
    'ms': 'Malay',
    'ml': 'Malayalam',
    'mt': 'Maltese',
    'mi': 'Maori',
    'mr': 'Marathi',
    'mn': 'Mongolian',
    'my': 'Myanmar (Burmese)',
    'ne': 'Nepali',
    'no': 'Norwegian',
    'ps': 'Pashto',
    'fa': 'Persian',
    'pl': 'Polish',
    'pt': 'Portuguese',
    'ma': 'Punjabi',
    'ro': 'Romanian',
    'ru': 'Russian',
    'sm': 'Samoan',
    'gd': 'Scots Gaelic',
    'sr': 'Serbian',
    'st': 'Sesotho',
    'sn': 'Shona',
    'sd': 'Sindhi',
    'si': 'Sinhala',
    'sk': 'Slovak',
    'sl': 'Slovenian',
    'so': 'Somali',
    'es': 'Spanish',
    'su': 'Sudanese',
    'sw': 'Swahili',
    'sv': 'Swedish',
    'tg': 'Tajik',
    'ta': 'Tamil',
    'te': 'Telugu',
    'th': 'Thai',
    'tr': 'Turkish',
    'uk': 'Ukrainian',
    'ur': 'Urdu',
    'uz': 'Uzbek',
    'vi': 'Vietnamese',
    'cy': 'Welsh',
    'xh': 'Xhosa',
    'yi': 'Yiddish',
    'yo': 'Yoruba',
    'zu': 'Zulu'
};
/**
 * Returns the ISO 639-1 code of the desiredLang – if it is supported by Google Translate
 * @param {string} desiredLang – the name or the code of the desired language
 * @returns {string|boolean} The ISO 639-1 code of the language or false if the language is not supported
 */
function getCode(desiredLang) {
    if (!desiredLang) {
        return false;
    }
    desiredLang = desiredLang.toLowerCase();

    if (langs[desiredLang]) {
        return desiredLang;
    }

    var keys = Object.keys(langs).filter(function (key) {
        if (typeof langs[key] !== 'string') {
            return false;
        }

        return langs[key].toLowerCase() === desiredLang;
    });

    return keys[0] || false;
}

/**
 * Returns true if the desiredLang is supported by Google Translate and false otherwise
 * @param desiredLang – the ISO 639-1 code or the name of the desired language
 * @returns {boolean}
 */
function isSupported(desiredLang) {
    return Boolean(getCode(desiredLang));
}

module.exports = langs;
module.exports.isSupported = isSupported;
module.exports.getCode = getCode;
<commit_msg>Change Chinese codes to lower case<commit_after>/**
 *
 * Generated from https://translate.google.com
 *
 * The languages that Google Translate supports (as of 5/15/16) alongside with their ISO 639-1 codes
 * See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
 */

var langs = {
    'auto': 'Automatic',
    'af': 'Afrikaans',
    'sq': 'Albanian',
    'ar': 'Arabic',
    'hy': 'Armenian',
    'az': 'Azerbaijani',
    'eu': 'Basque',
    'be': 'Belarusian',
    'bn': 'Bengali',
    'bs': 'Bosnian',
    'bg': 'Bulgarian',
    'ca': 'Catalan',
    'ceb': 'Cebuano',
    'ny': 'Chichewa',
    'zh-cn': 'Chinese Simplified',
    'zh-tw': 'Chinese Traditional',
    'co': 'Corsican',
    'hr': 'Croatian',
    'cs': 'Czech',
    'da': 'Danish',
    'nl': 'Dutch',
    'en': 'English',
    'eo': 'Esperanto',
    'et': 'Estonian',
    'tl': 'Filipino',
    'fi': 'Finnish',
    'fr': 'French',
    'fy': 'Frisian',
    'gl': 'Galician',
    'ka': 'Georgian',
    'de': 'German',
    'el': 'Greek',
    'gu': 'Gujarati',
    'ht': 'Haitian Creole',
    'ha': 'Hausa',
    'haw': 'Hawaiian',
    'iw': 'Hebrew',
    'hi': 'Hindi',
    'hmn': 'Hmong',
    'hu': 'Hungarian',
    'is': 'Icelandic',
    'ig': 'Igbo',
    'id': 'Indonesian',
    'ga': 'Irish',
    'it': 'Italian',
    'ja': 'Japanese',
    'jw': 'Javanese',
    'kn': 'Kannada',
    'kk': 'Kazakh',
    'km': 'Khmer',
    'ko': 'Korean',
    'ku': 'Kurdish (Kurmanji)',
    'ky': 'Kyrgyz',
    'lo': 'Lao',
    'la': 'Latin',
    'lv': 'Latvian',
    'lt': 'Lithuanian',
    'lb': 'Luxembourgish',
    'mk': 'Macedonian',
    'mg': 'Malagasy',
    'ms': 'Malay',
    'ml': 'Malayalam',
    'mt': 'Maltese',
    'mi': 'Maori',
    'mr': 'Marathi',
    'mn': 'Mongolian',
    'my': 'Myanmar (Burmese)',
    'ne': 'Nepali',
    'no': 'Norwegian',
    'ps': 'Pashto',
    'fa': 'Persian',
    'pl': 'Polish',
    'pt': 'Portuguese',
    'ma': 'Punjabi',
    'ro': 'Romanian',
    'ru': 'Russian',
    'sm': 'Samoan',
    'gd': 'Scots Gaelic',
    'sr': 'Serbian',
    'st': 'Sesotho',
    'sn': 'Shona',
    'sd': 'Sindhi',
    'si': 'Sinhala',
    'sk': 'Slovak',
    'sl': 'Slovenian',
    'so': 'Somali',
    'es': 'Spanish',
    'su': 'Sudanese',
    'sw': 'Swahili',
    'sv': 'Swedish',
    'tg': 'Tajik',
    'ta': 'Tamil',
    'te': 'Telugu',
    'th': 'Thai',
    'tr': 'Turkish',
    'uk': 'Ukrainian',
    'ur': 'Urdu',
    'uz': 'Uzbek',
    'vi': 'Vietnamese',
    'cy': 'Welsh',
    'xh': 'Xhosa',
    'yi': 'Yiddish',
    'yo': 'Yoruba',
    'zu': 'Zulu'
};
/**
 * Returns the ISO 639-1 code of the desiredLang – if it is supported by Google Translate
 * @param {string} desiredLang – the name or the code of the desired language
 * @returns {string|boolean} The ISO 639-1 code of the language or false if the language is not supported
 */
function getCode(desiredLang) {
    if (!desiredLang) {
        return false;
    }
    desiredLang = desiredLang.toLowerCase();

    if (langs[desiredLang]) {
        return desiredLang;
    }

    var keys = Object.keys(langs).filter(function (key) {
        if (typeof langs[key] !== 'string') {
            return false;
        }

        return langs[key].toLowerCase() === desiredLang;
    });

    return keys[0] || false;
}

/**
 * Returns true if the desiredLang is supported by Google Translate and false otherwise
 * @param desiredLang – the ISO 639-1 code or the name of the desired language
 * @returns {boolean}
 */
function isSupported(desiredLang) {
    return Boolean(getCode(desiredLang));
}

module.exports = langs;
module.exports.isSupported = isSupported;
module.exports.getCode = getCode;
<|endoftext|>