<commit_before>var c3 = require('c3'),
    d3 = require('d3');

var each = require('../utils/each'),
    extend = require('../utils/extend'),
    extendDeep = require('../utils/extend-deep'),
    isDateString = require('../utils/assert-date-string');

var c3DefaultDateFormat = require('./c3/extensions/default-date-format');
var c3PaginatingLegend = require('./c3/extensions/paginating-legend');
var c3TooltipContents = require('./c3/extensions/tooltip-contents');

var types = {
  'message' : require('./default/message'),
  'metric'  : require('./default/metric'),
  'table'   : require('./default/table'),
  'spinner' : require('./default/spinner')
};

module.exports = function(lib) {
  var timer, delay;
  bindResizeListener(function(){
    if (timer) {
      clearTimeout(timer);
    }
    delay = (lib.visuals.length > 12) ? 1000 : 250;
    timer = setTimeout(function(){
      each(lib.visuals, function(chart){
        if (chart.view._artifacts.c3) {
          chart.view._artifacts.c3.resize();
        }
      });
    }, delay);
  });

  defineC3();
  return types;
};

function defineC3(){
  var c3Types = [
    // Standard types
    'area',
    'area-spline',
    'area-step',
    'bar',
    'donut',
    'gauge',
    'line',
    'pie',
    'step',
    'spline',

    // Horizontal variant types
    'horizontal-area',
    'horizontal-area-spline',
    'horizontal-area-step',
    'horizontal-bar',
    'horizontal-line',
    'horizontal-step',
    'horizontal-spline'
  ];

  function getDefaultOptions(){
    var DEFAULT_OPTIONS,
        ENFORCED_OPTIONS,
        options;

    DEFAULT_OPTIONS = {
      axis: {},
      color: {},
      data: {
        order: null
      },
      legend: {
        position: 'right',
        show: true
      },
      padding: {},
      point: {
        focus: {
          expand: {
            enabled: false
          }
        },
        r: 2,
        show: true
      },
      tooltip: {}
    };

    ENFORCED_OPTIONS = {
      bindto: this.el().querySelector('.' + this.theme() + '-rendering'),
      color: {
        pattern: this.colors()
      },
      data: {
        colors: extend({}, this.colorMapping()),
        columns: [],
        type: this.type().replace('horizontal-', '')
      },
      size: {
        height: this.height() ? this.height() - this.el().offsetHeight : 400,
        width: this.width()
      },
      tooltip: {},
      transition: {
        duration: 0
      }
    };

    // Apply chartOptions
    options = extendDeep({}, DEFAULT_OPTIONS, this.chartOptions());

    // Apply enforced options
    options = extendDeep(options, ENFORCED_OPTIONS);
    options.color.pattern = ENFORCED_OPTIONS.color.pattern;
    options.data.colors = ENFORCED_OPTIONS.data.colors;
    options.data.columns = ENFORCED_OPTIONS.data.columns;

    return options;
  }

  each(c3Types, function(type, index) {
    types[type] = {
      render: function(){
        var options = getDefaultOptions.call(this);

        if (this.data()[0].length === 1 || this.data().length === 1) {
          this.message('No data to display');
          return;
        }

        if (type === 'gauge') {
          // Accommodate a neat bug:
          options.legend.position = 'bottom';
          options.data.columns = [[
            this.title() || this.data()[1][0],
            this.data()[1][1]
          ]];
        }
        else if (type === 'pie' || type === 'donut') {
          options.data.columns = this.data().slice(1);
        }
        else {

          // Apply formatting for horizontal variant types
          if (type.indexOf('horizontal-') > -1) {
            options.axis.rotated = type.indexOf('horizontal-') > -1;
          }

          if (isDateString(this.data()[1][0])) {
            // TIMESERIES
            options.axis.x = options.axis.x || {};
            options.axis.x.type = 'timeseries';
            options.axis.x.tick = options.axis.x.tick || {
              format: this.dateFormat() || c3DefaultDateFormat(this.data()[1][0], this.data()[2][0]),
              culling: { max: 5 }
            };

            options.data.columns[0] = [];
            each(this.dataset.selectColumn(0), function(cell, i){
              if (i > 0) {
                cell = new Date(cell);
              }
              options.data.columns[0][i] = cell;
            });
            options.data.columns[0][0] = 'x';
            options.data.x = 'x';
            if (this.stacked() && this.data()[0].length > 2) {
              options.data.groups = [ this.dataset.selectRow(0).slice(1) ];
            }
          }
          else {
            // CATEGORIES
            options.axis.x = options.axis.x || {};
            options.axis.x.type = 'category';
            options.axis.x.categories = this.dataset.selectColumn(0).slice(1);
            if (this.stacked() && this.data()[0].length > 2) {
              options.data.groups = [ this.dataset.selectRow(0).slice(1) ];
            }
          }

          if (this.data()[0].length === 2) {
            options.legend.show = false;
          }

          each(this.data()[0], function(cell, i){
            if (i > 0) {
              options.data.columns.push(this.dataset.selectColumn(i));
            }
          }.bind(this));

        }

        if (options.legend.show === true
          && options.legend.position === 'right'
            && ['gauge'].indexOf(type.replace('horizontal-', ''))) {

                // Apply custom color handling
                options.data.color = c3CustomDataMapping.bind(this);

                // Apply custom tooltip
                options.tooltip = {
                  contents: c3TooltipContents,
                  format: {
                    value: c3CustomTooltipFiltering.bind(this)
                  }
                };

                options.legend.show = false;
                var paddedWidth = this.el().querySelector('.' + this.theme() + '-rendering').offsetWidth - 100;
                options.size.width = options.size.width || paddedWidth;
                this.el().querySelector('.' + this.theme() + '-rendering').setAttribute('style', 'margin-right: 120px;');

                // Render artifacts
                this.view._artifacts['c3'] = c3.generate(options);
                c3PaginatingLegend.call(this, options.data.columns);
        }
        else {
          options.legend.show = false;
          this.view._artifacts['c3'] = c3.generate(options);
        }

      },
      update: function(){
        // no special update handling
        this.render();
      },
      destroy: function(){
        if (this.view._artifacts['c3']) {
          this.view._artifacts['c3'].destroy();
          this.view._artifacts['c3'] = null;
        }
      }
    };
  });
}

function c3CustomDataMapping(color, d) {
  var scope;
  if (this.view._artifacts.pagination
    && this.type() !== 'gauge'
      /*&& this.type() !== 'pie'
        && this.type() !== 'donut'*/) {
          // console.log(this.view._artifacts.pagination.labels);
          scope = this.view._artifacts.pagination.labels;
          if ((d.id && scope.indexOf(d.id) > -1)
            || (d && !d.id && scope.indexOf(d) > -1)) {
              return color;
          }
          else {
            if (this.type() === 'donut' || this.type() === 'pie') {
              return 'rgba(0,0,0,.1)';
            }
            else {
              return 'rgba(0,0,0,.07)';
            }
          }
  }
  else {
    return color;
  }
}

function c3CustomTooltipFiltering(value, ratio, id, index) {
  var scope;
  if (this.view._artifacts.pagination
    && this.type() !== 'gauge'
      /*&& this.type() !== 'pie'
        && this.type() !== 'donut'*/) {
          scope = this.view._artifacts.pagination.labels;
          if (scope.indexOf(id) > -1) {
            return value;
          }
  }
  else {
    return value;
  }
}

function bindResizeListener(fn){
  if ('undefined' === typeof window) return;
  window.onresize = window.resize = function(){};
  if (window.addEventListener) {
    window.addEventListener('resize', fn, true);
  }
  else if (window.attachEvent) {
    window.attachEvent('onresize', fn);
  }
}
<commit_msg>Use same timeframe is only one exists.<commit_after>var c3 = require('c3'),
    d3 = require('d3');

var each = require('../utils/each'),
    extend = require('../utils/extend'),
    extendDeep = require('../utils/extend-deep'),
    isDateString = require('../utils/assert-date-string');

var c3DefaultDateFormat = require('./c3/extensions/default-date-format');
var c3PaginatingLegend = require('./c3/extensions/paginating-legend');
var c3TooltipContents = require('./c3/extensions/tooltip-contents');

var types = {
  'message' : require('./default/message'),
  'metric'  : require('./default/metric'),
  'table'   : require('./default/table'),
  'spinner' : require('./default/spinner')
};

module.exports = function(lib) {
  var timer, delay;
  bindResizeListener(function(){
    if (timer) {
      clearTimeout(timer);
    }
    delay = (lib.visuals.length > 12) ? 1000 : 250;
    timer = setTimeout(function(){
      each(lib.visuals, function(chart){
        if (chart.view._artifacts.c3) {
          chart.view._artifacts.c3.resize();
        }
      });
    }, delay);
  });

  defineC3();
  return types;
};

function defineC3(){
  var c3Types = [
    // Standard types
    'area',
    'area-spline',
    'area-step',
    'bar',
    'donut',
    'gauge',
    'line',
    'pie',
    'step',
    'spline',

    // Horizontal variant types
    'horizontal-area',
    'horizontal-area-spline',
    'horizontal-area-step',
    'horizontal-bar',
    'horizontal-line',
    'horizontal-step',
    'horizontal-spline'
  ];

  function getDefaultOptions(){
    var DEFAULT_OPTIONS,
        ENFORCED_OPTIONS,
        options;

    DEFAULT_OPTIONS = {
      axis: {},
      color: {},
      data: {
        order: null
      },
      legend: {
        position: 'right',
        show: true
      },
      padding: {},
      point: {
        focus: {
          expand: {
            enabled: false
          }
        },
        r: 2,
        show: true
      },
      tooltip: {}
    };

    ENFORCED_OPTIONS = {
      bindto: this.el().querySelector('.' + this.theme() + '-rendering'),
      color: {
        pattern: this.colors()
      },
      data: {
        colors: extend({}, this.colorMapping()),
        columns: [],
        type: this.type().replace('horizontal-', '')
      },
      size: {
        height: this.height() ? this.height() - this.el().offsetHeight : 400,
        width: this.width()
      },
      tooltip: {},
      transition: {
        duration: 0
      }
    };

    // Apply chartOptions
    options = extendDeep({}, DEFAULT_OPTIONS, this.chartOptions());

    // Apply enforced options
    options = extendDeep(options, ENFORCED_OPTIONS);
    options.color.pattern = ENFORCED_OPTIONS.color.pattern;
    options.data.colors = ENFORCED_OPTIONS.data.colors;
    options.data.columns = ENFORCED_OPTIONS.data.columns;

    return options;
  }

  each(c3Types, function(type, index) {
    types[type] = {
      render: function(){
        var options = getDefaultOptions.call(this);

        if (this.data()[0].length === 1 || this.data().length === 1) {
          this.message('No data to display');
          return;
        }

        if (type === 'gauge') {
          // Accommodate a neat bug:
          options.legend.position = 'bottom';
          options.data.columns = [[
            this.title() || this.data()[1][0],
            this.data()[1][1]
          ]];
        }
        else if (type === 'pie' || type === 'donut') {
          options.data.columns = this.data().slice(1);
        }
        else {

          // Apply formatting for horizontal variant types
          if (type.indexOf('horizontal-') > -1) {
            options.axis.rotated = type.indexOf('horizontal-') > -1;
          }

          if (isDateString(this.data()[1][0])) {
            // TIMESERIES
            options.axis.x = options.axis.x || {};
            options.axis.x.type = 'timeseries';
            options.axis.x.tick = options.axis.x.tick || {
              format: this.dateFormat() || c3DefaultDateFormat(this.data()[1][0], this.data()[2] ? this.data()[2][0] : this.data()[1][0]),
              culling: { max: 5 }
            };

            options.data.columns[0] = [];
            each(this.dataset.selectColumn(0), function(cell, i){
              if (i > 0) {
                cell = new Date(cell);
              }
              options.data.columns[0][i] = cell;
            });
            options.data.columns[0][0] = 'x';
            options.data.x = 'x';
            if (this.stacked() && this.data()[0].length > 2) {
              options.data.groups = [ this.dataset.selectRow(0).slice(1) ];
            }
          }
          else {
            // CATEGORIES
            options.axis.x = options.axis.x || {};
            options.axis.x.type = 'category';
            options.axis.x.categories = this.dataset.selectColumn(0).slice(1);
            if (this.stacked() && this.data()[0].length > 2) {
              options.data.groups = [ this.dataset.selectRow(0).slice(1) ];
            }
          }

          if (this.data()[0].length === 2) {
            options.legend.show = false;
          }

          each(this.data()[0], function(cell, i){
            if (i > 0) {
              options.data.columns.push(this.dataset.selectColumn(i));
            }
          }.bind(this));

        }

        if (options.legend.show === true
          && options.legend.position === 'right'
            && ['gauge'].indexOf(type.replace('horizontal-', ''))) {

                // Apply custom color handling
                options.data.color = c3CustomDataMapping.bind(this);

                // Apply custom tooltip
                options.tooltip = {
                  contents: c3TooltipContents,
                  format: {
                    value: c3CustomTooltipFiltering.bind(this)
                  }
                };

                options.legend.show = false;
                var paddedWidth = this.el().querySelector('.' + this.theme() + '-rendering').offsetWidth - 100;
                options.size.width = options.size.width || paddedWidth;
                this.el().querySelector('.' + this.theme() + '-rendering').setAttribute('style', 'margin-right: 120px;');

                // Render artifacts
                this.view._artifacts['c3'] = c3.generate(options);
                c3PaginatingLegend.call(this, options.data.columns);
        }
        else {
          options.legend.show = false;
          this.view._artifacts['c3'] = c3.generate(options);
        }

      },
      update: function(){
        // no special update handling
        this.render();
      },
      destroy: function(){
        if (this.view._artifacts['c3']) {
          this.view._artifacts['c3'].destroy();
          this.view._artifacts['c3'] = null;
        }
      }
    };
  });
}

function c3CustomDataMapping(color, d) {
  var scope;
  if (this.view._artifacts.pagination
    && this.type() !== 'gauge'
      /*&& this.type() !== 'pie'
        && this.type() !== 'donut'*/) {
          // console.log(this.view._artifacts.pagination.labels);
          scope = this.view._artifacts.pagination.labels;
          if ((d.id && scope.indexOf(d.id) > -1)
            || (d && !d.id && scope.indexOf(d) > -1)) {
              return color;
          }
          else {
            if (this.type() === 'donut' || this.type() === 'pie') {
              return 'rgba(0,0,0,.1)';
            }
            else {
              return 'rgba(0,0,0,.07)';
            }
          }
  }
  else {
    return color;
  }
}

function c3CustomTooltipFiltering(value, ratio, id, index) {
  var scope;
  if (this.view._artifacts.pagination
    && this.type() !== 'gauge'
      /*&& this.type() !== 'pie'
        && this.type() !== 'donut'*/) {
          scope = this.view._artifacts.pagination.labels;
          if (scope.indexOf(id) > -1) {
            return value;
          }
  }
  else {
    return value;
  }
}

function bindResizeListener(fn){
  if ('undefined' === typeof window) return;
  window.onresize = window.resize = function(){};
  if (window.addEventListener) {
    window.addEventListener('resize', fn, true);
  }
  else if (window.attachEvent) {
    window.attachEvent('onresize', fn);
  }
}
<|endoftext|>


<commit_before>(function (env) {
    "use strict";
    env.ddg_spice_ski_resorts = function(api_result) {

        // Validate the response (customize for your Spice)
        if (!api_result || api_result.error) {
            return Spice.failed('ski_resorts');
        }

            Spice.add({
                id: api_result.name,
                name: "Ski Resort",
                templates: {
                    group: 'list',
                    options:{
                        moreAt: true,
                        content: 'record',
                        keySpacing: true
                    }
                },
                data: api_result,
                normalize: function(data){
                    // Display number of runs and highest point
                    var resortInfo = {
                        Country: data.countryName
                    };
                    var difficulties = ['novice', 'easy', 'intermediate', 'advanced', 'expert'];
                    difficulties.forEach( function ( difficulty ) {
                        var count = data.difficulties[difficulty];
                        if ( count ) {
                            resortInfo[difficulty + " run" + ( count > 1 ? "s" : "" )] = count + "";
                        }
                    } );
                    if ( data.highest_point ) {
                        resortInfo["Highest point"] = data.highest_point.name +
                                                      " (" + data.highest_point.ele + "m)";
                    }

                    return {
                      'record_data': resortInfo
                    }
                },
                meta: {
                  sourceName: 'Piste.io',
                  sourceUrl: 'http://www.piste.io/' + api_result.name
                },
            });

    };
}(this));
<commit_msg>Correctly hardcode ID property<commit_after>(function (env) {
    "use strict";
    env.ddg_spice_ski_resorts = function(api_result) {

        // Validate the response (customize for your Spice)
        if (!api_result || api_result.error) {
            return Spice.failed('ski_resorts');
        }

            Spice.add({
                id: "ski_resorts",
                name: "Ski Resort",
                templates: {
                    group: 'list',
                    options:{
                        moreAt: true,
                        content: 'record',
                        keySpacing: true
                    }
                },
                data: api_result,
                normalize: function(data){
                    // Display number of runs and highest point
                    var resortInfo = {
                        Country: data.countryName
                    };
                    var difficulties = ['novice', 'easy', 'intermediate', 'advanced', 'expert'];
                    difficulties.forEach( function ( difficulty ) {
                        var count = data.difficulties[difficulty];
                        if ( count ) {
                            resortInfo[difficulty + " run" + ( count > 1 ? "s" : "" )] = count + "";
                        }
                    } );
                    if ( data.highest_point ) {
                        resortInfo["Highest point"] = data.highest_point.name +
                                                      " (" + data.highest_point.ele + "m)";
                    }

                    return {
                      'record_data': resortInfo
                    }
                },
                meta: {
                  sourceName: 'Piste.io',
                  sourceUrl: 'http://www.piste.io/' + api_result.name
                },
            });

    };
}(this));
<|endoftext|>


<commit_before>// Description:
// Returns a list of streamable MP3s.
//
// Dependencies:
// Requires SoundManager2 and jQuery.
//
// Commands:
// soundcloud falloutboy

nrj("soundmanager2/script/soundmanager2-nodebug-jsmin.js", true);

function ddg_spice_sound_cloud (api_result) {
    "use strict";

    // Get the original query.
    // We're going to pass this to the header.
    var query = "";
    $("script").each(function() {
        var matched, result;
        matched = $(this).attr("src");
        if(matched) {
            result = matched.match(/\/js\/spice\/sound_cloud\/([^\/]+)/);
            if(result) {
                query = result[1];
            }
        }
    });

    // Items that we should not show.
    var skip_id = {
	80320921: true,
	75349402: true
    };

    var skip_array = ["soundcloud"];

    var context = [];
    for(var i = 0; i < api_result.length; i += 1) {
	// Only add the tracks that are:
	// - Streamable.
	// - Are not in the skip hash.
	// - Is relevant.
	var inSkip = api_result[i].id in skip_id;
	var isRelevantTitle = DDG.isRelevant(api_result[i].title, skip_array);
	var isRelevantUsername = DDG.isRelevant(api_result[i].user.username, skip_array);
	var isRelevantBoth = DDG.isRelevant(api_result[i].title + " " + api_result[i].user.username, skip_array);

        if(api_result[i].streamable && !inSkip && (isRelevantTitle || isRelevantUsername || isRelevantBoth)) {
            context.push(api_result[i]);
        }
    }

    // Exit if we don't have what we need.
    if(!api_result || context.length === 0) {
        return;
    }

    // This gets called when the sound is finished playing.
    // It basically just resets the look of the player.
    var clearPlayer = function() {
        var li = $("ul.playlist li");
        li.removeClass();
        li.addClass("sm2_stopped");
        soundManager.stopAll();
    };

    // Display the plugin.
    Spice.render({
        data                     : context,
        header1                  : decodeURIComponent(query) + " (SoundCloud)",
        source_url               : "https://soundcloud.com/search?q=" + query,
        source_name              : "SoundCloud",
        spice_name               : "sound_cloud",
        template_frame           : "carousel",
        template_options         : {
            items           : context,
            template_detail : "sound_cloud_details",
            single_item_handler: function(obj) {
                obj.image_url = obj.data[0].artwork_url || obj.data[0].user.avatar_url;
            }
        },
        force_big_header         : true,
        force_no_fold            : true,
        item_callback            : function() {
            if(window.soundManager) {
                clearPlayer();
            }
        }
    });

    var addPadding = function(time) {
        return time < 10 ? "0" + time : time;
    };

    // Coverts the milliseconds given to minutes and seconds.
    // e.g., 70000 milliseconds gets converted to 01:00.
    var formatTime = function(milliseconds) {
        var minutes = Math.floor(milliseconds / 1000 / 60);
        var seconds = Math.floor(60 * ((milliseconds / 1000 / 60) - minutes));

        return addPadding(minutes) + ":" + addPadding(seconds);
    };

    // Loads and plays the audio file.
    var isFailed = false;
    var playSound = function(anchor) {
        soundManager.stopAll();

        if(isFailed) {
            setTimeout(function() {
                clearPlayer();
            }, 1000);
        } else {
            var sound = soundManager.createSound({
                id: anchor.attr("id"),
                url: anchor.data("stream"),
                // When the sound is finished playing, reset it.
                onfinish: function() {
                    clearPlayer();
                },
                // Update the time displayed.
                whileplaying: function() {
                    $("#position").html(formatTime(this.position));
                    $("#total").html(formatTime(this.durationEstimate));

                    // We add this just in case onfinish doesn't fire.
                    if(this.position === this.durationEstimate) {
                        clearPlayer();
                    }
                }
            });

            sound.play();
        }
    };

    // Initialize SoundManager2.
    window.SM2_DEFER = true;
    var isLoaded = false;
    var isLoading = false;
    var soundSetup = function(anchor) {
        window.soundManager = new SoundManager();
        soundManager.url = "/soundmanager2/swf/";
        soundManager.flashVersion = 9;
        soundManager.useFlashBlock = false;
        soundManager.useHTML5Audio = false;
        soundManager.useFastPolling = true;
        soundManager.useHighPerformance = true;
        soundManager.ontimeout(function() {
            isFailed = true;
            isLoaded = true;
            clearPlayer();
        });
        soundManager.beginDelayedInit();
        soundManager.onready(function() {
            playSound(anchor);
            isLoaded = true;
        });
    };

    // This controls our player.
    var player = function(element) {

        var li = $(element);
        var anchor = li.children();

        // Get the sound
        var current_id = anchor.attr("id");
        var sound;

        // Check if it is already playing.
        // If it is, pause it.
        if(li.hasClass("sm2_playing") && isLoaded) {
            li.removeClass();
            li.addClass("sm2_paused");

            sound = soundManager.getSoundById(current_id);
            sound.pause();
        // If it's not playing, it's probably paused.
        // Let's play it.
        } else if(li.hasClass("sm2_paused")) {
            li.removeClass();
            li.addClass("sm2_playing");

            sound = soundManager.getSoundById(current_id);
            sound.resume();
        // If it's neither paused nor playing, then it means that we didn't load it yet.
        } else {
            // Load SoundManager2 if it hasn't already.
            if(!isLoaded && !isLoading) {
                isLoading = true;
                soundSetup(anchor);
            // If SoundManager already loaded, we should just play the sound.
            } else if(isLoaded) {
                playSound(anchor);
            }

            li.removeClass();
            li.addClass("sm2_playing");
        }
    };

    $(document).ready(function() {
        // Add the player on top of the carousel.
        $("#ddgc_detail").prependTo("#sound_cloud");
    });

    // Expose the function that controls our player.
    ddg_spice_sound_cloud.player = player;
};

// Get the user's avatar if the artwork does not exist.
Handlebars.registerHelper("chooseImage", function(artwork, avatar) {
    "use strict";

    return artwork || avatar;
});
<commit_msg>Parenthesize Sound_cloud Spice.<commit_after>// Description:
// Returns a list of streamable MP3s.
//
// Dependencies:
// Requires SoundManager2 and jQuery.
//
// Commands:
// soundcloud falloutboy

nrj("soundmanager2/script/soundmanager2-nodebug-jsmin.js", true);

function ddg_spice_sound_cloud (api_result) {
    "use strict";

    // Get the original query.
    // We're going to pass this to the header.
    var query = "";
    $("script").each(function() {
        var matched, result;
        matched = $(this).attr("src");
        if(matched) {
            result = matched.match(/\/js\/spice\/sound_cloud\/([^\/]+)/);
            if(result) {
                query = result[1];
            }
        }
    });

    // Items that we should not show.
    var skip_id = {
	80320921: true,
	75349402: true
    };

    var skip_array = ["soundcloud"];

    var context = [];
    for(var i = 0; i < api_result.length; i += 1) {
	// Only add the tracks that are:
	// - Streamable.
	// - Are not in the skip hash.
	// - Is relevant.
	var inSkip = api_result[i].id in skip_id;
	var isRelevantTitle = DDG.isRelevant(api_result[i].title, skip_array);
	var isRelevantUsername = DDG.isRelevant(api_result[i].user.username, skip_array);
	var isRelevantBoth = DDG.isRelevant(api_result[i].title + " " + api_result[i].user.username, skip_array);

        if(api_result[i].streamable && !inSkip && (isRelevantTitle || isRelevantUsername || isRelevantBoth)) {
            context.push(api_result[i]);
        }
    }

    // Exit if we don't have what we need.
    if(!api_result || context.length === 0) {
        return;
    }

    // This gets called when the sound is finished playing.
    // It basically just resets the look of the player.
    var clearPlayer = function() {
        var li = $("ul.playlist li");
        li.removeClass();
        li.addClass("sm2_stopped");
        soundManager.stopAll();
    };

    // Display the plugin.
    Spice.render({
        data                     : context,
        header1                  : decodeURIComponent(query) + " (SoundCloud)",
        source_url               : "https://soundcloud.com/search?q=" + query,
        source_name              : "SoundCloud",
        spice_name               : "sound_cloud",
        template_frame           : "carousel",
        template_options         : {
            items           : context,
            template_detail : "sound_cloud_details",
            single_item_handler: function(obj) {
                obj.image_url = obj.data[0].artwork_url || obj.data[0].user.avatar_url;
            }
        },
        force_big_header         : true,
        force_no_fold            : true,
        item_callback            : function() {
            if(window.soundManager) {
                clearPlayer();
            }
        }
    });

    var addPadding = function(time) {
        return (time < 10) ? "0" + time : time;
    };

    // Coverts the milliseconds given to minutes and seconds.
    // e.g., 70000 milliseconds gets converted to 01:00.
    var formatTime = function(milliseconds) {
        var minutes = Math.floor(milliseconds / 1000 / 60);
        var seconds = Math.floor(60 * ((milliseconds / 1000 / 60) - minutes));

        return addPadding(minutes) + ":" + addPadding(seconds);
    };

    // Loads and plays the audio file.
    var isFailed = false;
    var playSound = function(anchor) {
        soundManager.stopAll();

        if(isFailed) {
            setTimeout(function() {
                clearPlayer();
            }, 1000);
        } else {
            var sound = soundManager.createSound({
                id: anchor.attr("id"),
                url: anchor.data("stream"),
                // When the sound is finished playing, reset it.
                onfinish: function() {
                    clearPlayer();
                },
                // Update the time displayed.
                whileplaying: function() {
                    $("#position").html(formatTime(this.position));
                    $("#total").html(formatTime(this.durationEstimate));

                    // We add this just in case onfinish doesn't fire.
                    if(this.position === this.durationEstimate) {
                        clearPlayer();
                    }
                }
            });

            sound.play();
        }
    };

    // Initialize SoundManager2.
    window.SM2_DEFER = true;
    var isLoaded = false;
    var isLoading = false;
    var soundSetup = function(anchor) {
        window.soundManager = new SoundManager();
        soundManager.url = "/soundmanager2/swf/";
        soundManager.flashVersion = 9;
        soundManager.useFlashBlock = false;
        soundManager.useHTML5Audio = false;
        soundManager.useFastPolling = true;
        soundManager.useHighPerformance = true;
        soundManager.ontimeout(function() {
            isFailed = true;
            isLoaded = true;
            clearPlayer();
        });
        soundManager.beginDelayedInit();
        soundManager.onready(function() {
            playSound(anchor);
            isLoaded = true;
        });
    };

    // This controls our player.
    var player = function(element) {

        var li = $(element);
        var anchor = li.children();

        // Get the sound
        var current_id = anchor.attr("id");
        var sound;

        // Check if it is already playing.
        // If it is, pause it.
        if(li.hasClass("sm2_playing") && isLoaded) {
            li.removeClass();
            li.addClass("sm2_paused");

            sound = soundManager.getSoundById(current_id);
            sound.pause();
        // If it's not playing, it's probably paused.
        // Let's play it.
        } else if(li.hasClass("sm2_paused")) {
            li.removeClass();
            li.addClass("sm2_playing");

            sound = soundManager.getSoundById(current_id);
            sound.resume();
        // If it's neither paused nor playing, then it means that we didn't load it yet.
        } else {
            // Load SoundManager2 if it hasn't already.
            if(!isLoaded && !isLoading) {
                isLoading = true;
                soundSetup(anchor);
            // If SoundManager already loaded, we should just play the sound.
            } else if(isLoaded) {
                playSound(anchor);
            }

            li.removeClass();
            li.addClass("sm2_playing");
        }
    };

    $(document).ready(function() {
        // Add the player on top of the carousel.
        $("#ddgc_detail").prependTo("#sound_cloud");
    });

    // Expose the function that controls our player.
    ddg_spice_sound_cloud.player = player;
};

// Get the user's avatar if the artwork does not exist.
Handlebars.registerHelper("chooseImage", function(artwork, avatar) {
    "use strict";

    return artwork || avatar;
});
<|endoftext|>


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

    var root = this,
        Chart = root.Chart,
        //Cache a local reference to Chart.helpers
        helpers = Chart.helpers;

    var defaultConfig = {

        animation: {
            //Boolean - Whether we animate the rotation of the Doughnut
            animateRotate: true,

            //Boolean - Whether we animate scaling the Doughnut from the centre
            animateScale: false,
        },

        //The percentage of the chart that we cut out of the middle.

        cutoutPercentage: 50,

    };

    Chart.Type.extend({
        //Passing in a name registers this chart in the Chart namespace
        name: "Doughnut",
        //Providing a defaults will also register the deafults in the chart namespace
        defaults: defaultConfig,
        //Initialize is fired when the chart is initialized - Data is passed in as a parameter
        //Config is automatically merged by the core of Chart.js, and is available at this.options
        initialize: function() {

            //Set up tooltip events on the chart
            helpers.bindEvents(this, this.options.events, this.events);

            //Create a new bar for each piece of data
            helpers.each(this.data.datasets, function(dataset, datasetIndex) {
                dataset.metaData = [];
                helpers.each(dataset.data, function(dataPoint, index) {
                    dataset.metaData.push(new Chart.Arc({
                        _chart: this.chart,
                        _datasetIndex: datasetIndex,
                        _index: index,
                        _model: {}
                    }));
                }, this);
            }, this);

            // Create tooltip instance exclusively for this chart with some defaults.
            this.tooltip = new Chart.Tooltip({
                _chart: this.chart,
                _data: this.data,
                _options: this.options,
            }, this);

            this.resetElements();

            // Update the chart with the latest data.
            this.update();

        },

        calculateCircumference: function(dataset, value) {
            if (dataset.total > 0) {
                return (Math.PI * 2) * (value / dataset.total);
            } else {
                return 0;
            }
        },
        resetElements: function() {
            this.outerRadius = (helpers.min([this.chart.width, this.chart.height]) - this.options.elements.slice.borderWidth / 2) / 2;
            this.innerRadius = this.options.cutoutPercentage ? (this.outerRadius / 100) * (this.options.cutoutPercentage) : 1;
            this.radiusLength = (this.outerRadius - this.innerRadius) / this.data.datasets.length;

            // Update the points
            helpers.each(this.data.datasets, function(dataset, datasetIndex) {
                // So that calculateCircumference works
                dataset.total = 0;
                helpers.each(dataset.data, function(value) {
                    dataset.total += Math.abs(value);
                }, this);

                dataset.outerRadius = this.outerRadius - (this.radiusLength * datasetIndex);
                dataset.innerRadius = dataset.outerRadius - this.radiusLength;

                helpers.each(dataset.metaData, function(slice, index) {
                    helpers.extend(slice, {
                        _model: {
                            x: this.chart.width / 2,
                            y: this.chart.height / 2,
                            startAngle: Math.PI * -0.5, // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function
                            circumference: (this.options.animation.animateRotate) ? 0 : this.calculateCircumference(metaSlice.value),
                            outerRadius: (this.options.animation.animateScale) ? 0 : dataset.outerRadius,
                            innerRadius: (this.options.animation.animateScale) ? 0 : dataset.innerRadius,

                            backgroundColor: slice.custom && slice.custom.backgroundColor ? slice.custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor),
                            hoverBackgroundColor: slice.custom && slice.custom.hoverBackgroundColor ? slice.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, this.options.elements.slice.hoverBackgroundColor),
                            borderWidth: slice.custom && slice.custom.borderWidth ? slice.custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth),
                            borderColor: slice.custom && slice.custom.borderColor ? slice.custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor),

                            label: helpers.getValueAtIndexOrDefault(dataset.label, index, this.data.labels[index])
                        },
                    });

                    slice.pivot();
                }, this);

            }, this);
        },
        update: function() {

            this.outerRadius = (helpers.min([this.chart.width, this.chart.height]) - this.options.elements.slice.borderWidth / 2) / 2;
            this.innerRadius = this.options.cutoutPercentage ? (this.outerRadius / 100) * (this.options.cutoutPercentage) : 1;
            this.radiusLength = (this.outerRadius - this.innerRadius) / this.data.datasets.length;

            // Update the points
            helpers.each(this.data.datasets, function(dataset, datasetIndex) {

                dataset.total = 0;
                helpers.each(dataset.data, function(value) {
                    dataset.total += Math.abs(value);
                }, this);

                dataset.outerRadius = this.outerRadius - (this.radiusLength * datasetIndex);

                dataset.innerRadius = dataset.outerRadius - this.radiusLength;

                helpers.each(dataset.metaData, function(slice, index) {

                    helpers.extend(slice, {
                        // Utility
                        _chart: this.chart,
                        _datasetIndex: datasetIndex,
                        _index: index,

                        // Desired view properties
                        _model: {
                            x: this.chart.width / 2,
                            y: this.chart.height / 2,
                            circumference: this.calculateCircumference(dataset, dataset.data[index]),
                            outerRadius: dataset.outerRadius,
                            innerRadius: dataset.innerRadius,

                            backgroundColor: slice.custom && slice.custom.backgroundColor ? slice.custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor),
                            hoverBackgroundColor: slice.custom && slice.custom.hoverBackgroundColor ? slice.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, this.options.elements.slice.hoverBackgroundColor),
                            borderWidth: slice.custom && slice.custom.borderWidth ? slice.custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth),
                            borderColor: slice.custom && slice.custom.borderColor ? slice.custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor),

                            label: helpers.getValueAtIndexOrDefault(dataset.label, index, this.data.labels[index])
                        },
                    });

                    if (index === 0) {
                        slice._model.startAngle = Math.PI * -0.5; // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function
                    } else {
                        slice._model.startAngle = dataset.metaData[index - 1]._model.endAngle;
                    }

                    slice._model.endAngle = slice._model.startAngle + slice._model.circumference;

                    //Check to see if it's the last slice, if not get the next and update its start angle
                    if (index < dataset.data.length - 1) {
                        dataset.metaData[index + 1]._model.startAngle = slice._model.endAngle;
                    }

                    slice.pivot();
                }, this);

            }, this);

            this.render();
        },
        draw: function(easeDecimal) {
            easeDecimal = easeDecimal || 1;
            this.clear();

            this.eachElement(function(slice) {
                slice.transition(easeDecimal).draw();
            }, this);

            this.tooltip.transition(easeDecimal).draw();
        },
        events: function(e) {

            // If exiting chart
            if (e.type == 'mouseout') {
                return this;
            }

            this.lastActive = this.lastActive || [];

            // Find Active Elements
            this.active = function() {
                switch (this.options.hover.mode) {
                    case 'single':
                        return this.getSliceAtEvent(e);
                    case 'label':
                        return this.getSlicesAtEvent(e);
                    case 'dataset':
                        return this.getDatasetAtEvent(e);
                    default:
                        return e;
                }
            }.call(this);

            // On Hover hook
            if (this.options.hover.onHover) {
                this.options.hover.onHover.call(this, this.active);
            }

            if (e.type == 'mouseup' || e.type == 'click') {
                if (this.options.onClick) {
                    this.options.onClick.call(this, e, this.active);
                }
            }

            var dataset;
            var index;
            // Remove styling for last active (even if it may still be active)
            if (this.lastActive.length) {
                switch (this.options.hover.mode) {
                    case 'single':
                        dataset = this.data.datasets[this.lastActive[0]._datasetIndex];
                        index = this.lastActive[0]._index;

                        this.lastActive[0]._model.backgroundColor = this.lastActive[0].custom && this.lastActive[0].custom.backgroundColor ? this.lastActive[0].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
                        this.lastActive[0]._model.borderColor = this.lastActive[0].custom && this.lastActive[0].custom.borderColor ? this.lastActive[0].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
                        this.lastActive[0]._model.borderWidth = this.lastActive[0].custom && this.lastActive[0].custom.borderWidth ? this.lastActive[0].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
                        break;
                    case 'label':
                        for (var i = 0; i < this.lastActive.length; i++) {
                            dataset = this.data.datasets[this.lastActive[i]._datasetIndex];
                            index = this.lastActive[i]._index;

                            this.lastActive[i]._model.backgroundColor = this.lastActive[i].custom && this.lastActive[i].custom.backgroundColor ? this.lastActive[i].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
                            this.lastActive[i]._model.borderColor = this.lastActive[i].custom && this.lastActive[i].custom.borderColor ? this.lastActive[i].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
                            this.lastActive[i]._model.borderWidth = this.lastActive[i].custom && this.lastActive[i].custom.borderWidth ? this.lastActive[i].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
                        }
                        break;
                    case 'dataset':
                        break;
                    default:
                        // Don't change anything
                }
            }

            // Built in hover styling
            if (this.active.length && this.options.hover.mode) {
                switch (this.options.hover.mode) {
                    case 'single':
                        dataset = this.data.datasets[this.active[0]._datasetIndex];
                        index = this.active[0]._index;

                        this.active[0]._model.radius = this.active[0].custom && this.active[0].custom.hoverRadius ? this.active[0].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[0]._model.radius + 2);
                        this.active[0]._model.backgroundColor = this.active[0].custom && this.active[0].custom.hoverBackgroundColor ? this.active[0].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[0]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
                        this.active[0]._model.borderColor = this.active[0].custom && this.active[0].custom.hoverBorderColor ? this.active[0].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[0]._model.borderColor).saturate(0.5).darken(0.35).rgbString());
                        this.active[0]._model.borderWidth = this.active[0].custom && this.active[0].custom.hoverBorderWidth ? this.active[0].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[0]._model.borderWidth + 2);
                        break;
                    case 'label':
                        for (var i = 0; i < this.active.length; i++) {
                            dataset = this.data.datasets[this.active[i]._datasetIndex];
                            index = this.active[i]._index;

                            this.active[i]._model.radius = this.active[i].custom && this.active[i].custom.hoverRadius ? this.active[i].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[i]._model.radius + 2);
                            this.active[i]._model.backgroundColor = this.active[i].custom && this.active[i].custom.hoverBackgroundColor ? this.active[i].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[i]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
                            this.active[i]._model.borderColor = this.active[i].custom && this.active[i].custom.hoverBorderColor ? this.active[i].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[i]._model.borderColor).saturate(0.5).darken(0.35).rgbString());
                            this.active[i]._model.borderWidth = this.active[i].custom && this.active[i].custom.hoverBorderWidth ? this.active[i].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[i]._model.borderWidth + 2);
                        }
                        break;
                    case 'dataset':
                        break;
                    default:
                        // Don't change anything
                }
            }

            // Built in Tooltips
            if (this.options.tooltips.enabled) {

                // The usual updates
                this.tooltip.initialize();

                // Active
                if (this.active.length) {
                    this.tooltip._model.opacity = 1;

                    helpers.extend(this.tooltip, {
                        _active: this.active,
                    });

                    this.tooltip.update();
                } else {
                    // Inactive
                    this.tooltip._model.opacity = 0;
                }
            }

            // Hover animations
            this.tooltip.pivot();

            if (!this.animating) {
                var changed;

                helpers.each(this.active, function(element, index) {
                    if (element !== this.lastActive[index]) {
                        changed = true;
                    }
                }, this);

                // If entering, leaving, or changing elements, animate the change via pivot
                if ((!this.lastActive.length && this.active.length) ||
                    (this.lastActive.length && !this.active.length) ||
                    (this.lastActive.length && this.active.length && changed)) {

                    this.stop();
                    this.render(this.options.hover.animationDuration);
                }
            }

            // Remember Last Active
            this.lastActive = this.active;
            return this;
        },
        getSliceAtEvent: function(e) {
            var elements = [];

            var location = helpers.getRelativePosition(e);

            this.eachElement(function(slice, index) {
                if (slice.inRange(location.x, location.y)) {
                    elements.push(slice);
                }
            }, this);
            return elements;
        },
        /*getSlicesAtEvent: function(e) {
            var elements = [];

            var location = helpers.getRelativePosition(e);

            this.eachElement(function(slice, index) {
                if (slice.inGroupRange(location.x, location.y)) {
                    elements.push(slice);
                }
            }, this);
            return elements;
        },*/
    });

    Chart.types.Doughnut.extend({
        name: "Pie",
        defaults: helpers.merge(defaultConfig, {
            cutoutPercentage: 0
        })
    });

}).call(this);
<commit_msg>Doughnut/Pie Fixes<commit_after>(function() {
    "use strict";

    var root = this,
        Chart = root.Chart,
        //Cache a local reference to Chart.helpers
        helpers = Chart.helpers;

    var defaultConfig = {

        animation: {
            //Boolean - Whether we animate the rotation of the Doughnut
            animateRotate: true,

            //Boolean - Whether we animate scaling the Doughnut from the centre
            animateScale: false,
        },

        hover: {
            mode: 'single'
        },

        //The percentage of the chart that we cut out of the middle.

        cutoutPercentage: 50,

    };

    Chart.Type.extend({
        //Passing in a name registers this chart in the Chart namespace
        name: "Doughnut",
        //Providing a defaults will also register the deafults in the chart namespace
        defaults: defaultConfig,
        //Initialize is fired when the chart is initialized - Data is passed in as a parameter
        //Config is automatically merged by the core of Chart.js, and is available at this.options
        initialize: function() {

            //Set up tooltip events on the chart
            helpers.bindEvents(this, this.options.events, this.events);

            //Create a new bar for each piece of data
            helpers.each(this.data.datasets, function(dataset, datasetIndex) {
                dataset.metaData = [];
                helpers.each(dataset.data, function(dataPoint, index) {
                    dataset.metaData.push(new Chart.Arc({
                        _chart: this.chart,
                        _datasetIndex: datasetIndex,
                        _index: index,
                        _model: {}
                    }));
                }, this);
            }, this);

            // Create tooltip instance exclusively for this chart with some defaults.
            this.tooltip = new Chart.Tooltip({
                _chart: this.chart,
                _data: this.data,
                _options: this.options,
            }, this);

            this.resetElements();

            // Update the chart with the latest data.
            this.update();

        },

        calculateCircumference: function(dataset, value) {
            if (dataset.total > 0) {
                return (Math.PI * 2) * (value / dataset.total);
            } else {
                return 0;
            }
        },
        resetElements: function() {
            this.outerRadius = (helpers.min([this.chart.width, this.chart.height]) - this.options.elements.slice.borderWidth / 2) / 2;
            this.innerRadius = this.options.cutoutPercentage ? (this.outerRadius / 100) * (this.options.cutoutPercentage) : 1;
            this.radiusLength = (this.outerRadius - this.innerRadius) / this.data.datasets.length;

            // Update the points
            helpers.each(this.data.datasets, function(dataset, datasetIndex) {
                // So that calculateCircumference works
                dataset.total = 0;
                helpers.each(dataset.data, function(value) {
                    dataset.total += Math.abs(value);
                }, this);

                dataset.outerRadius = this.outerRadius - (this.radiusLength * datasetIndex);
                dataset.innerRadius = dataset.outerRadius - this.radiusLength;

                helpers.each(dataset.metaData, function(slice, index) {
                    helpers.extend(slice, {
                        _model: {
                            x: this.chart.width / 2,
                            y: this.chart.height / 2,
                            startAngle: Math.PI * -0.5, // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function
                            circumference: (this.options.animation.animateRotate) ? 0 : this.calculateCircumference(metaSlice.value),
                            outerRadius: (this.options.animation.animateScale) ? 0 : dataset.outerRadius,
                            innerRadius: (this.options.animation.animateScale) ? 0 : dataset.innerRadius,

                            backgroundColor: slice.custom && slice.custom.backgroundColor ? slice.custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor),
                            hoverBackgroundColor: slice.custom && slice.custom.hoverBackgroundColor ? slice.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, this.options.elements.slice.hoverBackgroundColor),
                            borderWidth: slice.custom && slice.custom.borderWidth ? slice.custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth),
                            borderColor: slice.custom && slice.custom.borderColor ? slice.custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor),

                            label: helpers.getValueAtIndexOrDefault(dataset.label, index, this.data.labels[index])
                        },
                    });

                    slice.pivot();
                }, this);

            }, this);
        },
        update: function() {

            this.outerRadius = (helpers.min([this.chart.width, this.chart.height]) - this.options.elements.slice.borderWidth / 2) / 2;
            this.innerRadius = this.options.cutoutPercentage ? (this.outerRadius / 100) * (this.options.cutoutPercentage) : 1;
            this.radiusLength = (this.outerRadius - this.innerRadius) / this.data.datasets.length;

            // Update the points
            helpers.each(this.data.datasets, function(dataset, datasetIndex) {

                dataset.total = 0;
                helpers.each(dataset.data, function(value) {
                    dataset.total += Math.abs(value);
                }, this);

                dataset.outerRadius = this.outerRadius - (this.radiusLength * datasetIndex);

                dataset.innerRadius = dataset.outerRadius - this.radiusLength;

                helpers.each(dataset.metaData, function(slice, index) {

                    helpers.extend(slice, {
                        // Utility
                        _chart: this.chart,
                        _datasetIndex: datasetIndex,
                        _index: index,

                        // Desired view properties
                        _model: {
                            x: this.chart.width / 2,
                            y: this.chart.height / 2,
                            circumference: this.calculateCircumference(dataset, dataset.data[index]),
                            outerRadius: dataset.outerRadius,
                            innerRadius: dataset.innerRadius,

                            backgroundColor: slice.custom && slice.custom.backgroundColor ? slice.custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor),
                            hoverBackgroundColor: slice.custom && slice.custom.hoverBackgroundColor ? slice.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, this.options.elements.slice.hoverBackgroundColor),
                            borderWidth: slice.custom && slice.custom.borderWidth ? slice.custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth),
                            borderColor: slice.custom && slice.custom.borderColor ? slice.custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor),

                            label: helpers.getValueAtIndexOrDefault(dataset.label, index, this.data.labels[index])
                        },
                    });

                    if (index === 0) {
                        slice._model.startAngle = Math.PI * -0.5; // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function
                    } else {
                        slice._model.startAngle = dataset.metaData[index - 1]._model.endAngle;
                    }

                    slice._model.endAngle = slice._model.startAngle + slice._model.circumference;

                    //Check to see if it's the last slice, if not get the next and update its start angle
                    if (index < dataset.data.length - 1) {
                        dataset.metaData[index + 1]._model.startAngle = slice._model.endAngle;
                    }

                    slice.pivot();
                }, this);

            }, this);

            this.render();
        },
        draw: function(easeDecimal) {
            easeDecimal = easeDecimal || 1;
            this.clear();

            this.eachElement(function(slice) {
                slice.transition(easeDecimal).draw();
            }, this);

            this.tooltip.transition(easeDecimal).draw();
        },
        events: function(e) {

            // If exiting chart
            if (e.type == 'mouseout') {
                return this;
            }

            this.lastActive = this.lastActive || [];

            // Find Active Elements
            this.active = function() {
                switch (this.options.hover.mode) {
                    case 'single':
                        return this.getSliceAtEvent(e);
                    case 'label':
                        return this.getSlicesAtEvent(e);
                    case 'dataset':
                        return this.getDatasetAtEvent(e);
                    default:
                        return e;
                }
            }.call(this);

            // On Hover hook
            if (this.options.hover.onHover) {
                this.options.hover.onHover.call(this, this.active);
            }

            if (e.type == 'mouseup' || e.type == 'click') {
                if (this.options.onClick) {
                    this.options.onClick.call(this, e, this.active);
                }
            }

            var dataset;
            var index;
            // Remove styling for last active (even if it may still be active)
            if (this.lastActive.length) {
                switch (this.options.hover.mode) {
                    case 'single':
                        dataset = this.data.datasets[this.lastActive[0]._datasetIndex];
                        index = this.lastActive[0]._index;

                        this.lastActive[0]._model.backgroundColor = this.lastActive[0].custom && this.lastActive[0].custom.backgroundColor ? this.lastActive[0].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
                        this.lastActive[0]._model.borderColor = this.lastActive[0].custom && this.lastActive[0].custom.borderColor ? this.lastActive[0].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
                        this.lastActive[0]._model.borderWidth = this.lastActive[0].custom && this.lastActive[0].custom.borderWidth ? this.lastActive[0].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
                        break;
                    case 'label':
                        for (var i = 0; i < this.lastActive.length; i++) {
                            dataset = this.data.datasets[this.lastActive[i]._datasetIndex];
                            index = this.lastActive[i]._index;

                            this.lastActive[i]._model.backgroundColor = this.lastActive[i].custom && this.lastActive[i].custom.backgroundColor ? this.lastActive[i].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.slice.backgroundColor);
                            this.lastActive[i]._model.borderColor = this.lastActive[i].custom && this.lastActive[i].custom.borderColor ? this.lastActive[i].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.slice.borderColor);
                            this.lastActive[i]._model.borderWidth = this.lastActive[i].custom && this.lastActive[i].custom.borderWidth ? this.lastActive[i].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.slice.borderWidth);
                        }
                        break;
                    case 'dataset':
                        break;
                    default:
                        // Don't change anything
                }
            }

            // Built in hover styling
            if (this.active.length && this.options.hover.mode) {
                switch (this.options.hover.mode) {
                    case 'single':
                        dataset = this.data.datasets[this.active[0]._datasetIndex];
                        index = this.active[0]._index;

                        this.active[0]._model.radius = this.active[0].custom && this.active[0].custom.hoverRadius ? this.active[0].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.active[0]._model.radius + 2);
                        this.active[0]._model.backgroundColor = this.active[0].custom && this.active[0].custom.hoverBackgroundColor ? this.active[0].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(this.active[0]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
                        this.active[0]._model.borderColor = this.active[0].custom && this.active[0].custom.hoverBorderColor ? this.active[0].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, this.active[0]._model.borderColor);
                        this.active[0]._model.borderWidth = this.active[0].custom && this.active[0].custom.hoverBorderWidth ? this.active[0].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, this.active[0]._model.borderWidth);
                        break;
                    case 'label':
                        for (var i = 0; i < this.active.length; i++) {
                            dataset = this.data.datasets[this.active[i]._datasetIndex];
                            index = this.active[i]._index;

                            this.active[i]._model.radius = this.active[i].custom && this.active[i].custom.hoverRadius ? this.active[i].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.active[i]._model.radius + 2);
                            this.active[i]._model.backgroundColor = this.active[i].custom && this.active[i].custom.hoverBackgroundColor ? this.active[i].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(this.active[i]._model.backgroundColor).saturate(0.5).darken(0.35).rgbString());
                            this.active[i]._model.borderColor = this.active[i].custom && this.active[i].custom.hoverBorderColor ? this.active[i].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, this.active[0]._model.borderColor);
                            this.active[i]._model.borderWidth = this.active[i].custom && this.active[i].custom.hoverBorderWidth ? this.active[i].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, this.active[i]._model.borderWidth);
                        }
                        break;
                    case 'dataset':
                        break;
                    default:
                        // Don't change anything
                }
            }

            // Built in Tooltips
            if (this.options.tooltips.enabled) {

                // The usual updates
                this.tooltip.initialize();

                // Active
                if (this.active.length) {
                    this.tooltip._model.opacity = 1;

                    helpers.extend(this.tooltip, {
                        _active: this.active,
                    });

                    this.tooltip.update();
                } else {
                    // Inactive
                    this.tooltip._model.opacity = 0;
                }
            }

            // Hover animations
            this.tooltip.pivot();

            if (!this.animating) {
                var changed;

                helpers.each(this.active, function(element, index) {
                    if (element !== this.lastActive[index]) {
                        changed = true;
                    }
                }, this);

                // If entering, leaving, or changing elements, animate the change via pivot
                if ((!this.lastActive.length && this.active.length) ||
                    (this.lastActive.length && !this.active.length) ||
                    (this.lastActive.length && this.active.length && changed)) {

                    this.stop();
                    this.render(this.options.hover.animationDuration);
                }
            }

            // Remember Last Active
            this.lastActive = this.active;
            return this;
        },
        getSliceAtEvent: function(e) {
            var elements = [];

            var location = helpers.getRelativePosition(e);

            this.eachElement(function(slice, index) {
                if (slice.inRange(location.x, location.y)) {
                    elements.push(slice);
                }
            }, this);
            return elements;
        },
        /*getSlicesAtEvent: function(e) {
            var elements = [];

            var location = helpers.getRelativePosition(e);

            this.eachElement(function(slice, index) {
                if (slice.inGroupRange(location.x, location.y)) {
                    elements.push(slice);
                }
            }, this);
            return elements;
        },*/
    });

    Chart.types.Doughnut.extend({
        name: "Pie",
        defaults: helpers.merge(defaultConfig, {
            cutoutPercentage: 0
        })
    });

}).call(this);
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const logger = require('./')('server');

module.exports = function summary(request, response) {
  if (request.method === 'options') {
    return;
  }

  var line = {
    code: response.isBoom ? response.output.statusCode : response.statusCode,
    method: request.method,
    errno: response.errno || 0,
    path: request.path,
    agent: request.headers['user-agent'],
    t: Date.now() - request.info.received,
    remoteAddressChain: request.app.remoteAddressChain
  };

  if (line.code >= 500) {
    line.stack = response.stack;
    logger.error('summary', line);
  } else {
    logger.info('summary', line);
  }
};

<commit_msg>fix(logs): add client_id to summary logs (#235) r=seanmonstar<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const logger = require('./')('server');

module.exports = function summary(request, response) {
  if (request.method === 'options') {
    return;
  }

  var line = {
    code: response.isBoom ? response.output.statusCode : response.statusCode,
    method: request.method,
    errno: response.errno || 0,
    path: request.path,
    agent: request.headers['user-agent'],
    t: Date.now() - request.info.received,
    remoteAddressChain: request.app.remoteAddressChain
  };

  if (request.auth && request.auth.credentials) {
    line.client_id = request.auth.credentials.client_id;
  }

  if (line.code >= 500) {
    line.stack = response.stack;
    logger.error('summary', line);
  } else {
    logger.info('summary', line);
  }
};

<|endoftext|>


<commit_before>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

var BeakerPageObject = require('./beaker.po.js');
var path = require('path');
var beakerPO;

describe('Category Plots (Bar Charts)', function () {

  beforeEach(function () {
    beakerPO = new BeakerPageObject();
    browser.get(beakerPO.baseURL + "beaker/#/open?uri=file:config%2Ftutorials%2FCategoryPlot.bkr&readOnly=true");

    browser.waitForAngular();
    beakerPO.waitUntilLoadingFinished();

  });

  afterEach(function (done) {
    beakerPO.closeNotebook()
      .then(done);
  });

  it('Input values', function () {
    beakerPO.checkPlotIsPresent(0);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(0, 0, 0), 'plot-bar');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(0, 0, 1), 'plot-bar');

    beakerPO.checkCount(beakerPO.getPlotMaing(0, 0).all(by.tagName('rect')), 6);
  });

  it('Size', function () {
    beakerPO.checkPlotIsPresent(1);
    beakerPO.checkSize(beakerPO.getPlotSvg(1, 0), 400, 200);
  });

  it('Title and Axis Labels', function () {
    beakerPO.checkPlotIsPresent(2);

    expect(beakerPO.getCodeCellOutputContainerYLabel(2)).toBe("Values");
    expect(beakerPO.getCodeCellOutputContainerXLabel(2)).toBe("Categories");
    expect(beakerPO.getCodeCellOutputContainerTitle(2)).toBe("Hello CategoryPlot!");
  });

  it('Category Names', function () {
    beakerPO.checkPlotIsPresent(3);

    expect(beakerPO.getPlotLabelg(3).element(By.id('label_x_0')).getText()).toBe('Helium');
    expect(beakerPO.getPlotLabelg(3).element(By.id('label_x_1')).getText()).toBe('Neon');
    expect(beakerPO.getPlotLabelg(3).element(By.id('label_x_2')).getText()).toBe('Argon');
  });

  it('Series Names', function () {
    beakerPO.checkPlotIsPresent(4);

    beakerPO.checkPlotLegentdLabel(4, 0, 1, 'Gas');
    beakerPO.checkPlotLegentdLabel(4, 0, 2, 'Liquid');

  });

  it('Category Label Orientation', function () {
    beakerPO.checkPlotIsPresent(8);

    var label_x_0 = beakerPO.getPlotLabelg(8).element(By.id('label_x_0'));
    var label_x_1 = beakerPO.getPlotLabelg(8).element(By.id('label_x_1'));
    var label_x_2 = beakerPO.getPlotLabelg(8).element(By.id('label_x_2'));

    expect(label_x_0.getText()).toBe('Acid');
    expect(label_x_1.getText()).toBe('Neutral');
    expect(label_x_2.getText()).toBe('Base');

    expect(label_x_0.getAttribute('transform')).toContain('translate(12 -10) rotate(45');
    expect(label_x_1.getAttribute('transform')).toContain('translate(20.5 -10) rotate(45');
    expect(label_x_2.getAttribute('transform')).toContain('translate(13 -10) rotate(45');

  });

  it('Single Color', function () {
    beakerPO.checkPlotIsPresent(11);
    var style = 'fill: rgb(255, 175, 175); fill-opacity: 1; stroke-opacity: 0;';
    expect(beakerPO.getPlotSvgElementByIndex(11, 0, 0).getAttribute('style')).toBe(style);
    expect(beakerPO.getPlotSvgElementByIndex(11, 0, 1).getAttribute('style')).toBe(style);
    expect(beakerPO.getPlotSvgElementByIndex(11, 0, 2).getAttribute('style')).toBe(style);
  });

  it('CategoryStems', function () {
    beakerPO.checkPlotIsPresent(21);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(21, 0, 0), 'plot-stem');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(21, 0, 1), 'plot-stem');

  });

  it('CategoryPoints', function () {
    beakerPO.checkPlotIsPresent(22);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(22, 0, 0), 'plot-point');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(22, 0, 1), 'plot-point');
  });

  it('CategoryLines', function () {
    beakerPO.checkPlotIsPresent(23);

    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 0).element(by.tagName('circle')).isPresent()).toBe(true);
    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 0).element(by.tagName('path')).isPresent()).toBe(true);
    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 1).element(by.tagName('circle')).isPresent()).toBe(true);
    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 1).element(by.tagName('path')).isPresent()).toBe(true);
  });

  it('From a table (list of Maps)', function () {
    beakerPO.checkPlotIsPresent(33);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(33, 0, 0), 'plot-bar');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(33, 0, 1), 'plot-bar');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(33, 0, 2), 'plot-bar');

    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_0')).getText()).toBe('closePrice_mean');
    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_1')).getText()).toBe('highPrice_mean');
    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_2')).getText()).toBe('lowPrice_mean');
    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_3')).getText()).toBe('openPrice_mean');

    beakerPO.checkPlotLegentdLabel(33, 0, 1, 'A');
    beakerPO.checkPlotLegentdLabel(33, 0, 2, 'B');
    beakerPO.checkPlotLegentdLabel(33, 0, 3, 'C');
  });

});<commit_msg>create test for category plot notebook #3667<commit_after>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

var BeakerPageObject = require('./beaker.po.js');
var path = require('path');
var beakerPO;

describe('Category Plots (Bar Charts)', function () {

  beforeEach(function () {
    beakerPO = new BeakerPageObject();
    browser.get(beakerPO.baseURL + "beaker/#/open?uri=file:config%2Ftutorials%2FCategoryPlot.bkr&readOnly=true");

    browser.waitForAngular();
    beakerPO.waitUntilLoadingFinished();

  });

  afterEach(function (done) {
    beakerPO.closeNotebook()
      .then(done);
  });

  it('Input values', function () {
    beakerPO.checkPlotIsPresent(0);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(0, 0, 0), 'plot-bar');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(0, 0, 1), 'plot-bar');

    //beakerPO.checkCount(beakerPO.getPlotMaing(0, 0).all(by.tagName('rect')), 6);
  });

  it('Size', function () {
    beakerPO.checkPlotIsPresent(1);
    beakerPO.checkSize(beakerPO.getPlotSvg(1, 0), 400, 200);
  });

  it('Title and Axis Labels', function () {
    beakerPO.checkPlotIsPresent(2);

    expect(beakerPO.getCodeCellOutputContainerYLabel(2)).toBe("Values");
    expect(beakerPO.getCodeCellOutputContainerXLabel(2)).toBe("Categories");
    expect(beakerPO.getCodeCellOutputContainerTitle(2)).toBe("Hello CategoryPlot!");
  });

  it('Category Names', function () {
    beakerPO.checkPlotIsPresent(3);

    expect(beakerPO.getPlotLabelg(3).element(By.id('label_x_0')).getText()).toBe('Helium');
    expect(beakerPO.getPlotLabelg(3).element(By.id('label_x_1')).getText()).toBe('Neon');
    expect(beakerPO.getPlotLabelg(3).element(By.id('label_x_2')).getText()).toBe('Argon');
  });

  it('Series Names', function () {
    beakerPO.checkPlotIsPresent(4);

    beakerPO.checkPlotLegentdLabel(4, 0, 1, 'Gas');
    beakerPO.checkPlotLegentdLabel(4, 0, 2, 'Liquid');

  });

  it('Category Label Orientation', function () {
    beakerPO.checkPlotIsPresent(8);

    var label_x_0 = beakerPO.getPlotLabelg(8).element(By.id('label_x_0'));
    var label_x_1 = beakerPO.getPlotLabelg(8).element(By.id('label_x_1'));
    var label_x_2 = beakerPO.getPlotLabelg(8).element(By.id('label_x_2'));

    expect(label_x_0.getText()).toBe('Acid');
    expect(label_x_1.getText()).toBe('Neutral');
    expect(label_x_2.getText()).toBe('Base');

    expect(label_x_0.getAttribute('transform')).toContain('translate(12 -10) rotate(45');
    expect(label_x_1.getAttribute('transform')).toContain('translate(20.5 -10) rotate(45');
    expect(label_x_2.getAttribute('transform')).toContain('translate(13 -10) rotate(45');

  });

  it('Single Color', function () {
    beakerPO.checkPlotIsPresent(11);
    var style = 'fill: rgb(255, 175, 175); fill-opacity: 1; stroke-opacity: 0;';
    expect(beakerPO.getPlotSvgElementByIndex(11, 0, 0).getAttribute('style')).toBe(style);
    expect(beakerPO.getPlotSvgElementByIndex(11, 0, 1).getAttribute('style')).toBe(style);
    expect(beakerPO.getPlotSvgElementByIndex(11, 0, 2).getAttribute('style')).toBe(style);
  });

  it('CategoryStems', function () {
    beakerPO.checkPlotIsPresent(21);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(21, 0, 0), 'plot-stem');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(21, 0, 1), 'plot-stem');

  });

  it('CategoryPoints', function () {
    beakerPO.checkPlotIsPresent(22);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(22, 0, 0), 'plot-point');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(22, 0, 1), 'plot-point');
  });

  it('CategoryLines', function () {
    beakerPO.checkPlotIsPresent(23);

    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 0).element(by.tagName('circle')).isPresent()).toBe(true);
    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 0).element(by.tagName('path')).isPresent()).toBe(true);
    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 1).element(by.tagName('circle')).isPresent()).toBe(true);
    expect(beakerPO.getPlotSvgElementByIndex(23, 0, 1).element(by.tagName('path')).isPresent()).toBe(true);
  });

  it('From a table (list of Maps)', function () {
    beakerPO.checkPlotIsPresent(33);

    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(33, 0, 0), 'plot-bar');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(33, 0, 1), 'plot-bar');
    beakerPO.checkClass(beakerPO.getPlotSvgElementByIndex(33, 0, 2), 'plot-bar');

    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_0')).getText()).toBe('closePrice_mean');
    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_1')).getText()).toBe('highPrice_mean');
    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_2')).getText()).toBe('lowPrice_mean');
    expect(beakerPO.getPlotLabelg(33).element(By.id('label_x_3')).getText()).toBe('openPrice_mean');

    beakerPO.checkPlotLegentdLabel(33, 0, 1, 'A');
    beakerPO.checkPlotLegentdLabel(33, 0, 2, 'B');
    beakerPO.checkPlotLegentdLabel(33, 0, 3, 'C');
  });

});<|endoftext|>


<commit_before>var fs = require('fs'),
    Endpoint = require('../endpoint'),
    Group = require('../group'),
    Mapper = require('./mapper')

function Postman() {

}
Postman.prototype = new Mapper()

function transformVariableFormat(val) {
  return val.replace(/\{\{(.*)\}\}/i, "<<$1>>")
}

function parseQuery(qstr) {
  var query = {}
  if (qstr && qstr.length > 0) {
    var a = qstr.substr(1).split('&')
    for (var i = 0; i < a.length; i++) {
        var b = a[i].split('=')
        query[decodeURIComponent(b[0])] = {
          type: 'string',
          default: transformVariableFormat(decodeURIComponent(b[1] || ''))
        }
    }
  }

  return {type: 'object', properties: query, required: []}
}

function mapPathParams(data) {
  var pathParams = {}
  for(var key in data) {
    pathParams[key] = transformVariableFormat(data[key])
  }
  return pathParams
}

function mapHeaders(data) {
  var headerObj = {"type": "object", properties:{}, required:[]}, headers
  headers = data.split('\n')
  for(var j in headers) {
    var header = headers[j]
    if(!header) {
      continue
    }
    var keyValueParts = header.split(':')
    headerObj['properties'][keyValueParts[0]] = {
      type: 'string',
      default: transformVariableFormat(keyValueParts[1])
    }
  }
  return headerObj
}

function mapRequestBody(mode, requestData) {
  var data = {body: {type: 'object', properties: {}, required: []}}
  //TODO map Body
  switch (mode) {
    case 'urlencoded':
      data.mimeType = 'application/x-www-form-urlencoded'
    case 'params':
      //check for best suitability
      data.mimeType = 'multipart/form-data'
      break
    default:
      data.mimeType = 'text/plain'
      break
  }

  for(var j in requestData) {
    var type = null
    switch (requestData[j].type) {
      case 'text':
        type = 'string'
        break
      default:
        type = 'binary'
    }
    data.body.properties[requestData[j].key] = {
      'type': type,
      'default': transformVariableFormat(requestData[j].value)
    }
  }
  return data
}

function mapEndpoint(pmr) {
  var endpoint, headers, v, queryString, urlParts
  endpoint = new Endpoint(pmr.name)
  endpoint.ItemId = pmr.id
  urlParts = pmr.url.split('?')
  endpoint.QueryString = parseQuery(urlParts[1])
  endpoint.Path = transformVariableFormat(urlParts[0])
  endpoint.Method = pmr.method

  endpoint.Before = pmr.preRequestScript

  endpoint.PathParams = mapPathParams(pmr.pathVariables)

  //parse headers
  endpoint.Headers = mapHeaders(pmr.headers)

  endpoint.Body = mapRequestBody(pmr.dataMode, pmr.data)
  return endpoint
}

function mapEndpointGroup(folder) {
  group = new Group(folder.name)
  group.Items = folder.order
  return group
}

Postman.prototype.loadFile = function (filePath) {
  var data = fs.readFileSync(filePath, 'utf8')
  this.data = JSON.parse(data)
  return
}

Postman.prototype.map = function() {

  for (var i = 0; i < this.data.requests.length; i++) {
    this.endpoints.push(mapEndpoint(this.data.requests[i]))
  }

  for (var i = 0; i < this.data.folders.length; i++) {
    this.groups.push(mapEndpointGroup(this.data.folders[i]))
  }
}

module.exports = Postman
<commit_msg>- small fix<commit_after>var fs = require('fs'),
    Endpoint = require('../endpoint'),
    Group = require('../group'),
    Mapper = require('./mapper')

function Postman() {

}
Postman.prototype = new Mapper()

function transformVariableFormat(val) {
  return val.replace(/\{\{(.*)\}\}/i, "<<$1>>")
}

function parseQuery(qstr) {
  var query = {}
  if (qstr && qstr.length > 0) {
    var a = qstr.substr(1).split('&')
    for (var i = 0; i < a.length; i++) {
        var b = a[i].split('=')
        query[decodeURIComponent(b[0])] = {
          type: 'string',
          default: transformVariableFormat(decodeURIComponent(b[1] || ''))
        }
    }
  }

  return {type: 'object', properties: query, required: []}
}

function mapPathParams(data) {
  var pathParams = {}
  for(var key in data) {
    pathParams[key] = transformVariableFormat(data[key])
  }
  return pathParams
}

function mapHeaders(data) {
  var headerObj = {"type": "object", properties:{}, required:[]}, headers
  headers = data.split('\n')
  for(var j in headers) {
    var header = headers[j]
    if(!header) {
      continue
    }
    var keyValueParts = header.split(':')
    headerObj['properties'][keyValueParts[0]] = {
      type: 'string',
      default: transformVariableFormat(keyValueParts[1])
    }
  }
  return headerObj
}

function mapRequestBody(mode, requestData) {
  var data = {body: {type: 'object', properties: {}, required: []}}
  //TODO map Body
  switch (mode) {
    case 'urlencoded':
      data.mimeType = 'application/x-www-form-urlencoded'
    case 'params':
      //check for best suitability
      data.mimeType = 'multipart/form-data'
      break
    default:
      data.mimeType = 'text/plain'
      break
  }

  for(var j in requestData) {
    var type = null
    switch (requestData[j].type) {
      case 'text':
        type = 'string'
        break
      default:
        type = 'binary'
    }
    data.body.properties[requestData[j].key] = {
      'type': type,
      'default': transformVariableFormat(requestData[j].value)
    }
  }
  return data
}

function mapEndpoint(pmr) {
  var endpoint, headers, v, queryString, urlParts
  endpoint = new Endpoint(pmr.name)
  endpoint.ItemId = pmr.id
  urlParts = pmr.url.split('?')
  endpoint.QueryString = parseQuery(urlParts[1])
  endpoint.Path = transformVariableFormat(urlParts[0])
  endpoint.Method = pmr.method

  endpoint.Before = pmr.preRequestScript

  endpoint.PathParams = mapPathParams(pmr.pathVariables)

  //parse headers
  endpoint.Headers = mapHeaders(pmr.headers)

  endpoint.Body = mapRequestBody(pmr.dataMode, pmr.data)
  return endpoint
}

function mapEndpointGroup(folder) {
  group = new Group(folder.name)
  group.Items = folder.order
  return group
}

Postman.prototype.loadFile = function (filePath) {
  var data = fs.readFileSync(filePath, 'utf8')
  return this.data = JSON.parse(data)
}

Postman.prototype.map = function() {

  for (var i = 0; i < this.data.requests.length; i++) {
    this.endpoints.push(mapEndpoint(this.data.requests[i]))
  }

  for (var i = 0; i < this.data.folders.length; i++) {
    this.groups.push(mapEndpointGroup(this.data.folders[i]))
  }
}

module.exports = Postman
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path'),
  dirname = path.dirname,
  basename = path.basename;
var spawn = require('child_process').spawn;

var bitmask = require('cli-fs').bitmask;

var alias = require('../util/alias');
var ExecError = require('../error/exec');

/**
 *  Execute a command as an external program.
 *
 *  @param argv The program arguments.
 *  @param cmd The command to execute.
 *  @param args Array of arguments to pass to the command.
 *  @param req The request object for the middleware execution.
 */
function execute(argv, cmd, args, req) {
  var config = this.configuration();
  var errors = this.errors, scope = this, e;
  var dir = config.bin || dirname(argv[1]);
  var bin = this._name + '-' + cmd;
  var local = path.join(dir, bin);
  var exists = fs.existsSync(local);
  var data = {bin: bin, dir: dir, local: local, args: args};
  if(!exists) {
    e = new ExecError(errors.ENOENT.message, [bin], errors.ENOENT.code);
    e.data = data;
    throw e;
  }
  var stat = fs.statSync(local);
  // FIXME: this logic is flawed
  var mode = (process.getuid() === 0) ? '777' : '077';
  if(!bitmask(stat, 1, mode)) {
    e = new ExecError(errors.EPERM.message, [bin], errors.EPERM.code);
    e.data = data;
    throw e;
  }
  var ps = spawn(local, args, {stdio: 'inherit'});
  req.process = ps;
  this.emit('exec', ps, local, args, req);
  ps.on('error', function(err){
    //NOTE: keep these tests just in case the above logic is wrong
    //NOTE: or quite likely fails on windows
    //if(err.code == 'ENOENT') {
      //raise.call(scope, codes.ENOENT, null, [bin, dir, local, args]);
    //}else if (err.code == 'EACCES') {
      //raise.call(scope, codes.EPERM, null, [bin, dir, local, args]);
    //}
    //scope.emit('error', e);
    scope.raise(e);
  });
  ps.on('close', function (code, signal) {
    // NOTE: workaround for https://github.com/joyent/node/issues/3222
    // NOTE: assume child process exited gracefully on SIGINT
    if(signal == 'SIGINT') {
      return process.exit(0);
    }
    // TODO: remove this event?
    scope.emit('close', code, signal);
    if(config.exit) process.exit(code);
  });
  return ps;
}

/**
 *  Searches the raw arguments looking for the first argument
 *  that matches a known command and executes the command if it
 *  is in the list of exec commands.
 */
module.exports = function(){
  return function exec(req, next) {
    if(!arguments.length) return;
    var i, raw = req.result.raw.slice(0), cmd, arg, ps;
    for(i = 0;i < raw.length;i++) {
      cmd = raw[i]; arg = alias(cmd, this._commands);
      if(arg) {
        raw.splice(i, 1);
        if(this._exec[arg.key()]) {
          try {
            ps = execute.call(this, process.argv, cmd, raw, req);
          }catch(e) {
            return next(e);
          }
          req.process = ps;
          // NOTE: we must not call next() here, middleware processing halts
          return;
        }
      }
    }
    next();
  }
}
<commit_msg>Handle exec subcommand error event.<commit_after>var fs = require('fs');
var path = require('path'),
  dirname = path.dirname,
  basename = path.basename;
var spawn = require('child_process').spawn;

var bitmask = require('cli-fs').bitmask;

var alias = require('../util/alias');
var ExecError = require('../error/exec');

/**
 *  Execute a command as an external program.
 *
 *  @param argv The program arguments.
 *  @param cmd The command to execute.
 *  @param args Array of arguments to pass to the command.
 *  @param req The request object for the middleware execution.
 */
function execute(argv, cmd, args, req) {
  var config = this.configuration();
  var errors = this.errors, scope = this, e;
  var dir = config.bin || dirname(argv[1]);
  var bin = this._name + '-' + cmd;
  var local = path.join(dir, bin);
  var exists = fs.existsSync(local);
  var data = {bin: bin, dir: dir, local: local, args: args};
  if(!exists) {
    e = new ExecError(errors.ENOENT.message, [bin], errors.ENOENT.code);
    e.data = data;
    throw e;
  }
  var stat = fs.statSync(local);
  // FIXME: this logic is flawed
  var mode = (process.getuid() === 0) ? '777' : '077';
  if(!bitmask(stat, 1, mode)) {
    e = new ExecError(errors.EPERM.message, [bin], errors.EPERM.code);
    e.data = data;
    throw e;
  }
  var ps = spawn(local, args, {stdio: 'inherit'});
  req.process = ps;
  this.emit('exec', ps, local, args, req);
  ps.on('error', function(err){
    if(err.code == 'ENOENT') {
      scope.raise(scope.errors.ENOENT, [bin]);
    }else if (err.code == 'EACCES') {
      scope.raise(scope.errors.EPERM, [bin]);
    }
  });
  ps.on('close', function (code, signal) {
    // NOTE: workaround for https://github.com/joyent/node/issues/3222
    // NOTE: assume child process exited gracefully on SIGINT
    if(signal == 'SIGINT') {
      return process.exit(0);
    }
    // TODO: remove this event?
    scope.emit('close', code, signal);
    if(config.exit) process.exit(code);
  });
  return ps;
}

/**
 *  Searches the raw arguments looking for the first argument
 *  that matches a known command and executes the command if it
 *  is in the list of exec commands.
 */
module.exports = function(){
  return function exec(req, next) {
    if(!arguments.length) return;
    var i, raw = req.result.raw.slice(0), cmd, arg, ps;
    for(i = 0;i < raw.length;i++) {
      cmd = raw[i]; arg = alias(cmd, this._commands);
      if(arg) {
        raw.splice(i, 1);
        if(this._exec[arg.key()]) {
          try {
            ps = execute.call(this, process.argv, cmd, raw, req);
          }catch(e) {
            return next(e);
          }
          req.process = ps;
          // NOTE: we must not call next() here, middleware processing halts
          return;
        }
      }
    }
    next();
  }
}
<|endoftext|>