<commit_before>var path = require('path'),
    fs = require('fs'),
    exec = require('child_process').exec,
    argv = require('minimist')(process.argv.slice(2)),
    gulp = require('gulp'),
    gutil = require('gulp-util');

var create = function(generatorPath, options) {
  if (argv._.length < 2) {
    gutil.log("Error: See 'em new --help'.");
    process.exit(0);
  }
  // checking the url prefix
  var re = /^http(?:s)?:\/\//,
      userInputPath = options.path,
      // check for remote URL path
      remoteUrl = ( userInputPath ) ? ( re.test(userInputPath) ) ? userInputPath : ('http://' + userInputPath) : undefined;

  // get the full path to the core of application. ( Server && Client )
  var skeletonsCorePath = getSkeletonsCorePath(),
      // get the full path to the ember application or take the generator from github or an URL
      // skeletonsAppPath = ( userInputPath ) ? remoteUrl : getSkeletonsAppPath();
      skeletonsAppPath = getSkeletonsAppPath();

  if (fs.existsSync(generatorPath)) {
    gutil.log('[-log]', 'Folder (', generatorPath, ') has existed in this directory!' );
    process.exit(0);
  } else {
    // Create a new directory name what user passed in
    fs.mkdirSync(generatorPath);
  }

  var currentAppPath = path.resolve(generatorPath);
  // Setup gulp task, copy the source files into the newly create folder
  setupTask (skeletonsCorePath, skeletonsAppPath, currentAppPath);
  // Trigger the generator task
  gulp.start('generator');
};

module.exports = create;

function setupTask (coreSrcPath, appSrcPath, dest) {
  gutil.log('[-log]', 'Starting to generate application at ', dest );
  var coreSrc = [ coreSrcPath + '/**', coreSrcPath + '/**/.*' ],
      appSrc = [ appSrcPath + '/**' ];

  return gulp.task('generator', function (callback) {
      gulp.src(coreSrc)
          .on('end', function() {
              gutil.log('[-log]', 'You new application Server is ready');
          })
          .pipe(gulp.dest(dest));

      gulp.src(appSrc)
          .on('end', function() {
              gutil.log('[-log]', 'New Ember application is ready');
              installNpm( dest, callback );
          })
          .pipe(gulp.dest(dest+'/client/app'));
  });
}

function installNpm (rootPath, callback) {
    rootPath = rootPath || process.cwd();
    gutil.log('[-log]', 'NPM is installing packages...');
    process.chdir(rootPath);
    return exec('npm install', function(error, stdout, stderr) {
      var log;
      //process.chdir(rootPath);
      if (error !== null) {
        log = stderr.toString();
        gutil.log('[-log]', log);
        return callback(log);
      }
      installBower(rootPath, callback);
    });
}

function installBower (rootPath, callback) {
  rootPath = rootPath || process.cwd();
  gutil.log('[-log]', 'Bower is installing javascript packages...');
  process.chdir(rootPath);
  return exec('bower install', function(error, stdout, stderr) {
    var log;
    //process.chdir(rootPath);
    if (error !== null) {
      log = stderr.toString();
      gutil.log('[-log]', log);
      return callback(log);
    }
    gitInit(rootPath, callback);
  });
}

function gitInit(rootPath, callback) {
    gutil.log('[-log]', 'Be Patient, em-cli is doing REALLY hard to initialize your repo ...' );

    rootPath = rootPath || process.cwd();
    process.chdir(rootPath);
    var month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        today = new Date(),
        todayDate = today.getDate(),
        todayMonth = month[today.getMonth()],
        todayYear = today.getFullYear(),
        init = 'git init && git add . && git commit -m "Initial Commit @ ' + todayMonth + ' ' + todayDate + ', ' + todayYear + '"';
    return exec(init, function(error, stdout, stderr) {
        var log;
        if (error !== null) {
          log = stderr.toString();
          gutil.log('[-log]', log);
          return callback(log);
        }
        gutil.log('[-log]', 'Initialized a new git repo & did first commit' );
        callback();
    });
}

function getSkeletonsCorePath () {
  var skeletonsCorePath = pathResolver('skeletons/core');
  return skeletonsCorePath;
}

function getSkeletonsAppPath () {
  var skeletonsAppPath = pathResolver('skeletons/app');
  return skeletonsAppPath;
}

function pathResolver (relativePath) {
  return path.resolve(__dirname, '..', relativePath);
}
<commit_msg>update the description for the function info<commit_after>var path = require('path'),
    fs = require('fs'),
    exec = require('child_process').exec,
    argv = require('minimist')(process.argv.slice(2)),
    gulp = require('gulp'),
    gutil = require('gulp-util');

var create = function(generatorPath, options) {
  if (argv._.length < 2) {
    gutil.log("Error: See 'em new --help'.");
    process.exit(0);
  }
  // checking the url prefix
  var re = /^http(?:s)?:\/\//,
      userInputPath = options.path,
      // check for remote URL path
      remoteUrl = ( userInputPath ) ? ( re.test(userInputPath) ) ? userInputPath : ('http://' + userInputPath) : undefined;

  // get the full path to the core of application. ( Server && Client )
  var skeletonsCorePath = getSkeletonsCorePath(),
      // get the full path to the ember application or take the generator from github or an URL
      // skeletonsAppPath = ( userInputPath ) ? remoteUrl : getSkeletonsAppPath();
      skeletonsAppPath = getSkeletonsAppPath();

  if (fs.existsSync(generatorPath)) {
    gutil.log('[-log]', 'Folder (', generatorPath, ') has existed in this directory!' );
    process.exit(0);
  } else {
    // Create a new directory name what user passed in
    fs.mkdirSync(generatorPath);
  }

  var currentAppPath = path.resolve(generatorPath);
  // Setup gulp task, copy the source files into the newly create folder
  setupTask (skeletonsCorePath, skeletonsAppPath, currentAppPath);
  // Trigger the generator task
  gulp.start('generator');
};

module.exports = create;

function setupTask (coreSrcPath, appSrcPath, dest) {
  gutil.log('[-log]', 'Starting to generate application at ', dest );
  var coreSrc = [ coreSrcPath + '/**', coreSrcPath + '/**/.*' ],
      appSrc = [ appSrcPath + '/**' ];

  return gulp.task('generator', function (callback) {
      gulp.src(coreSrc)
          .on('end', function() {
              gutil.log('[-log]', 'You new application Server is ready');
          })
          .pipe(gulp.dest(dest));

      gulp.src(appSrc)
          .on('end', function() {
              gutil.log('[-log]', 'New Ember application is ready');
              installNpm( dest, callback );
          })
          .pipe(gulp.dest(dest+'/client/app'));
  });
}

function installNpm (rootPath, callback) {
  installer ( rootPath, 'npm install', 'NPM is installing node packages...', installBower, callback );
}

function installBower (rootPath, callback) {
  installer ( rootPath, 'bower install', 'Bower is installing javascript packages...', gitInit, callback );
}

function gitInit(rootPath, callback) {
    gutil.log('[-log]', 'Be Patient, em-cli is doing REALLY hard to initialize your repo ...' );

    rootPath = rootPath || process.cwd();
    process.chdir(rootPath);
    var month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        today = new Date(),
        todayDate = today.getDate(),
        todayMonth = month[today.getMonth()],
        todayYear = today.getFullYear(),
        command = 'git init && git add . && git commit -m "Initial Commit @ ' + todayMonth + ' ' + todayDate + ', ' + todayYear + '"';
    return exec(command, function(error, stdout, stderr) {
        var log;
        if (error !== null) {
          log = stderr.toString();
          gutil.log('[-log]', log);
          return callback(log);
        }
        gutil.log('[-log]', 'Initialized a new git repo & did first commit' );
        callback();
    });
}

// installer plugins to handle the npm and bower packages installation
function installer ( rootPath, command, description, nextStepFn, callback ) {
  rootPath = rootPath || process.cwd();
  gutil.log('[-log]', description );
  process.chdir(rootPath);
  return exec(command, function(error, stdout, stderr) {
    var log;
    //process.chdir(rootPath);
    if (error !== null) {
      log = stderr.toString();
      gutil.log('[-log]', log);
      return callback(log);
    }
    nextStepFn(rootPath, callback);
  });
}

function getSkeletonsCorePath () {
  var skeletonsCorePath = pathResolver('skeletons/core');
  return skeletonsCorePath;
}

function getSkeletonsAppPath () {
  var skeletonsAppPath = pathResolver('skeletons/app');
  return skeletonsAppPath;
}

function pathResolver (relativePath) {
  return path.resolve(__dirname, '..', relativePath);
}
<|endoftext|>


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

	angular
	    .module('shipyard.images')
            .factory('ImagesService', ImagesService);

	ImagesService.$inject = ['$http'];
        function ImagesService($http) {
            return {
                list: function() {
                    var promise = $http
                        .get('/images/json?all=1')
                        .then(function(response) {
                            return response.data;
                        });
                    return promise;
                },
                remove: function(image) {
                    var promise = $http
                        .delete('/images/' + image.Id + '?force=1')
                        .then(function(response) {
                            return response.data;
                        });
                    return promise;
                }
            }
        }
})();
<commit_msg>don't list intermediate images<commit_after>(function(){
	'use strict';

	angular
	    .module('shipyard.images')
            .factory('ImagesService', ImagesService);

	ImagesService.$inject = ['$http'];
        function ImagesService($http) {
            return {
                list: function() {
                    var promise = $http
                        .get('/images/json')
                        .then(function(response) {
                            return response.data;
                        });
                    return promise;
                },
                remove: function(image) {
                    var promise = $http
                        .delete('/images/' + image.Id + '?force=1')
                        .then(function(response) {
                            return response.data;
                        });
                    return promise;
                }
            }
        }
})();
<|endoftext|>


<commit_before>var sys = require('sys');
var couchdb = require('node-couchdb/lib/couchdb');
var couchClient;

function log() {
  var args = Array.prototype.slice.apply(arguments);
  var level = args.shift();
  sys.puts(level + ": " + sys.inspect(args));
}

function getClientFromArgs(args) {
  var databaseURL = args[args.length - 1];
  var urlParts = require('url').parse(databaseURL);
  return couchdb.createClient(urlParts.port, urlParts.hostname);
}

function compileHandler(name, ddoc, dbName) {
  var handler = ddoc.changes[name];
  var code = handler.handler;
  log('DEBUG', code);
  var requireFun = function(module) {
    if (/^\.\//.test(module)) {
      var val = ddoc;
      var pathParts = module.split('/');
      pathParts.shift();
      pathParts.forEach(function(part) {
        val = val[part];
      });
      return val;
    } else {
      return require(module);
    }
  };
  var fullName = [dbName, ddoc._id, name];
  var fun = process.evalcx(
    '(' + code  + ');',
    { require: requireFun },
    fullName.concat('js').join('.')
  );
  if (typeof fun !== 'function') {
    log('ERROR', fullName.join('/') + ' does not evaluate to a function');
    // TODO: somehow catch error...
  }
  return function(change) {
    // EventEmitter.addListener() doesn't work with evaled functions
    log('DEBUG', "Handler called - " + fullName.join('/'));
    fun(change);
  };
}

function setupChangesHandler(name, ddoc, dbName) {
  log('DEBUG', name, ddoc, dbName);
  var handlerFun = compileHandler(name, ddoc, dbName);
  var db = couchClient.db(dbName);
  db.info(function(err, info) {
    // copy query options from the ddoc
    var ddocOpts = ddoc.changes[name].query;
    var opts = {};
    for (var key in ddocOpts) { opts[key] = ddocOpts[key]; }
    opts.since = info.update_seq;
    log('DEBUG', opts);
    // TODO: store event emitter and handler function for future removal
    var changesEmitter = db.changesStream(opts);
    changesEmitter.addListener('data', handlerFun);
    log('INFO', "changes handler started", [dbName, ddoc._id, name].join('/'));
  });
}

function startHandlers(dbNames) {
  log('DEBUG', dbNames);
  dbNames.forEach(function(dbName) {
    var db = couchClient.db(dbName);
    db.allDocs({
      startkey: "_design/",
      endkey: "_design0",
      include_docs: true
    }, function(err, resp) {
      log('DEBUG', resp);
      resp.rows.forEach(function(row) {
        var ddoc = row.doc;
        for (var key in (ddoc.changes || [])) {
          setupChangesHandler(key, ddoc, dbName);
        }
      });
    });
  });
}

function start() {
  log('INFO', 'starting');
  couchClient = getClientFromArgs(process.argv);
  log('DEBUG', couchClient);
  couchClient.allDbs(function(err, dbNames) {
    if (err) {
      log('ERROR', err);
    } else {
      startHandlers(dbNames);
    }
  });
}

if (require.main == module) {
  // NB: we're executing, not being require()'ed
  start();
}
<commit_msg>additional logging and error handling to client code<commit_after>var sys = require('sys');
var couchdb = require('node-couchdb/lib/couchdb');
var couchClient;

function log() {
  var args = Array.prototype.slice.apply(arguments);
  var level = args.shift();
  sys.puts(level + ": " + sys.inspect(args));
}

function getClientFromArgs(args) {
  var databaseURL = args[args.length - 1];
  var urlParts = require('url').parse(databaseURL);
  return couchdb.createClient(urlParts.port, urlParts.hostname);
}

// Not being used yet...
function requireFunFor(ddoc) {
  return function(module) {
    if (/^\.\//.test(module)) {
      var val = ddoc;
      var pathParts = module.split('/');
      pathParts.shift();
      pathParts.forEach(function(part) {
        val = val[part];
      });
      return val;
    } else {
      return require(module);
    }
  };
}

function clientLogFun(clientName) {
  return function(msg) {
    log('CLIENT', clientName, msg);
  }
}

function compileHandler(name, ddoc, dbName) {
  var handler = ddoc.changes[name];
  var code = handler.handler;
  log('DEBUG', code);
  var fullName = [dbName, ddoc._id, name].join('/');
  var context = {
    ddoc: ddoc,
    require: require,
    log: clientLogFun(fullName)
  };
  var fun = process.evalcx(
    '(' + code  + ');',
    context,
    fullName
  );
  if (typeof fun !== 'function') {
    log('ERROR', fullName + ' does not evaluate to a function');
    // TODO: somehow catch error...
  }
  return function(change) {
    // EventEmitter.addListener() doesn't work with evaled functions
    log('DEBUG', "Handler called - " + fullName);
    try {
      fun(change);
    } catch (e) {
      log('ERROR', fullName, err.type, err.message, err.stack);
    }
  };
}

function setupChangesHandler(name, ddoc, dbName) {
  log('DEBUG', name, ddoc, dbName);
  var handlerFun = compileHandler(name, ddoc, dbName);
  var db = couchClient.db(dbName);
  db.info(function(err, info) {
    // copy query options from the ddoc
    var ddocOpts = ddoc.changes[name].query;
    var opts = {};
    for (var key in ddocOpts) { opts[key] = ddocOpts[key]; }
    opts.since = info.update_seq;
    log('DEBUG', opts);
    // TODO: store event emitter and handler function for future removal
    var changesEmitter = db.changesStream(opts);
    changesEmitter.addListener('data', handlerFun);
    log('INFO', "changes handler started", [dbName, ddoc._id, name].join('/'));
  });
}

function startHandlers(dbNames) {
  log('DEBUG', dbNames);
  dbNames.forEach(function(dbName) {
    var db = couchClient.db(dbName);
    db.allDocs({
      startkey: "_design/",
      endkey: "_design0",
      include_docs: true
    }, function(err, resp) {
      log('DEBUG', resp);
      resp.rows.forEach(function(row) {
        var ddoc = row.doc;
        for (var key in (ddoc.changes || [])) {
          setupChangesHandler(key, ddoc, dbName);
        }
      });
    });
  });
}

function start() {
  log('INFO', 'starting');
  couchClient = getClientFromArgs(process.argv);
  log('DEBUG', couchClient);
  couchClient.allDbs(function(err, dbNames) {
    if (err) {
      log('ERROR', err);
    } else {
      startHandlers(dbNames);
    }
  });
}

if (require.main == module) {
  // NB: we're executing, not being require()'ed
  start();

  process.addListener('uncaughtException', function (err) {
    log('ERROR', err);
  });
}
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

sap.ui.define([],
	function() {
	"use strict";

	/**
	 * NavContainer renderer.
	 * @namespace
	 */
	var NavContainerRenderer = {
		// apiVersion: 2
	};

	/**
	 * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}.
	 *
	 * @param {sap.ui.core.RenderManager} oRm The RenderManager that can be used for writing to the Render-Output-Buffer
	 * @param {sap.ui.core.Control} oControl The control that should be rendered
	 */
	NavContainerRenderer.render = function(oRm, oControl) {

		oControl._bRenderingInProgress = true;

		// return immediately if control is invisible
		if (!oControl.getVisible()) {
			return;
		}

		var sHeight = oControl.getHeight(),
			sTooltip = oControl.getTooltip_AsString(),
			oContent = oControl.getCurrentPage();

		oRm.openStart("div", oControl);

		oRm.class("sapMNav");

		oRm.style("width", oControl.getWidth());

		if (sHeight && sHeight != "100%") {
			oRm.style("height", sHeight);
		}

		if (this.renderAttributes) {
			this.renderAttributes(oRm, oControl); // may be used by inheriting renderers, but DO NOT write class or style attributes! Instead, call addClass/addStyle.
		}

		if (sTooltip) {
			oRm.attr("title", sTooltip);
		}

		oRm.openEnd(); // div element

		if (this.renderBeforeContent) {
			this.renderBeforeContent(oRm, oControl); // may be used by inheriting renderers
		}

		oControl.getPages().forEach(function(oPage) {
			if (oPage === oContent) {
				oContent.removeStyleClass("sapMNavItemHidden"); // In case the current page was hidden (the previous current page got removed)
				oRm.renderControl(oContent);
			} else {
				oRm.cleanupControlWithoutRendering(oPage);
			}
		});

		oRm.close("div");

		oControl._bRenderingInProgress = false;
	};

	return NavContainerRenderer;

}, /* bExport= */ true);
<commit_msg>[INTERNAL] NavContainer: cleanupControlWithoutRendering was missing<commit_after>/*!
 * ${copyright}
 */

sap.ui.define([],
	function() {
	"use strict";

	/**
	 * NavContainer renderer.
	 * @namespace
	 */
	var NavContainerRenderer = {
		// apiVersion: 2
	};

	/**
	 * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}.
	 *
	 * @param {sap.ui.core.RenderManager} oRm The RenderManager that can be used for writing to the Render-Output-Buffer
	 * @param {sap.ui.core.Control} oControl The control that should be rendered
	 */
	NavContainerRenderer.render = function(oRm, oControl) {

		oControl._bRenderingInProgress = true;

		// return immediately if control is invisible
		if (!oControl.getVisible()) {
			return;
		}

		var sHeight = oControl.getHeight(),
			sTooltip = oControl.getTooltip_AsString(),
			oContent = oControl.getCurrentPage();

		oRm.openStart("div", oControl);

		oRm.class("sapMNav");

		oRm.style("width", oControl.getWidth());

		if (sHeight && sHeight != "100%") {
			oRm.style("height", sHeight);
		}

		if (this.renderAttributes) {
			this.renderAttributes(oRm, oControl); // may be used by inheriting renderers, but DO NOT write class or style attributes! Instead, call addClass/addStyle.
		}

		if (sTooltip) {
			oRm.attr("title", sTooltip);
		}

		oRm.openEnd(); // div element

		if (this.renderBeforeContent) {
			this.renderBeforeContent(oRm, oControl); // may be used by inheriting renderers
		}

		if (oContent) {
			oContent.removeStyleClass("sapMNavItemHidden"); // In case the current page was hidden (the previous current page got removed)
			oRm.renderControl(oContent);
		}

		oRm.close("div");

		oControl._bRenderingInProgress = false;
	};

	return NavContainerRenderer;

}, /* bExport= */ true);
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 misc = require('utils/misc');
var stringUtils = require('utils/string_utils');
var App = require('app');

/**
 * Wrapper View for all sort components. Layout template and common actions are located inside of it.
 * Logic specific for sort fields
 * located in inner view - fieldView.
 *
 * @type {*}
 */
var wrapperView = Em.View.extend({
  tagName: 'tr',

  classNames: ['sort-wrapper'],

  willInsertElement: function () {
    if (this.get('parentView.tableFilteringComplete')) {
      this.get('parentView').set('filteringComplete', true);
    }
  },

  /**
   * Load sort statuses from local storage
   * Works only after finish filtering in the parent View
   */
  loadSortStatuses: function () {
    var statuses = App.db.getSortingStatuses(this.get('controller.name'));
    if (!this.get('parentView.filteringComplete')) return;
    if (statuses) {
      var childViews = this.get('childViews');
      var self = this;
      statuses.forEach(function (st) {
        if (st.status != 'sorting') {
          var sortOrder = false;
          if (st.status == 'sorting_desc') {
            sortOrder = true;
          }
          self.sort(childViews.findProperty('name', st.name), sortOrder);
          childViews.findProperty('name', st.name).set('status', (sortOrder) ? 'sorting_desc' : 'sorting_asc');
          self.get('controller').set('sortingColumn', childViews.findProperty('name', st.name));
        }
        else {
          childViews.findProperty('name', st.name).set('status', st.status);
        }
      });
    }
  }.observes('parentView.filteringComplete'),

  /**
   * Save sort statuses to local storage
   * Works only after finish filtering in the parent View
   */
  saveSortStatuses: function () {
    if (!this.get('parentView.filteringComplete')) return;

    var statuses = [];
    this.get('childViews').forEach(function (childView) {
      statuses.push({
        name: childView.get('name'),
        status: childView.get('status')
      });
    });
    App.db.setSortingStatuses(this.get('controller.name'), statuses);
  },

  /**
   * sort content by property
   * @param property {object}
   * @param order {Boolean} true - DESC, false - ASC
   * @param returnSorted {Boolean}
   */
  sort: function (property, order, returnSorted) {
    var content = this.get('content').toArray();
    var sortFunc = this.getSortFunc(property, order);
    var status = order ? 'sorting_desc' : 'sorting_asc';

    this.resetSort();
    this.get('childViews').findProperty('name', property.get('name')).set('status', status);
    this.saveSortStatuses(property, order);
    content.sort(sortFunc);

    if (!!returnSorted) {
      return content;
    } else {
      this.set('content', content);
    }
  },

  isSorting: false,

  onContentChange: function () {
    if (!this.get('isSorting') && this.get('content.length')) {
      this.get('childViews').forEach(function (view) {
        if (view.status !== 'sorting') {
          var status = view.get('status');
          this.set('isSorting', true);
          this.sort(view, status == 'sorting_desc');
          this.set('isSorting', false);
          view.set('status', status);
        }
      }, this);
    }
  }.observes('controller.contentUpdater'),

  /**
   * reset all sorts fields
   */
  resetSort: function () {
    this.get('childViews').setEach('status', 'sorting');
  },
  /**
   * determines sort function depending on the type of sort field
   * @param property
   * @param order
   * @return {*}
   */
  getSortFunc: function (property, order) {
    var func;
    switch (property.get('type')) {
      case 'ip':
        func = function (a, b) {
          var a = misc.ipToInt(a.get(property.get('name')));
          var b = misc.ipToInt(b.get(property.get('name')));
          if (order) {
            return a - b;
          } else {
            return b - a;
          }
        };
        break;
      case 'number':
        func = function (a, b) {
          var a_p = a.get(property.get('name'));
          var b_p = b.get(property.get('name'));
          a_p = Em.isNone(a_p) ? -Infinity : parseFloat(a_p);
          b_p = Em.isNone(b_p) ? -Infinity : parseFloat(b_p);
          if (order) {
            return a_p - b_p;
          } else {
            return b_p - a_p
          }
        };
        break;
      case 'version':
        func = function (a, b) {
          var res = stringUtils.compareVersions(a.get(property.get('name')), b.get(property.get('name')));
          if (order) {
            return -res;
          } else {
            return res;
          }
        };
        break;
      case 'alert_status':
        func = App.AlertDefinition.getSortDefinitionsByStatus(order);
        break;
      default:
        func = function (a, b) {
          var a_p = a.get(property.get('name'));
          var b_p = b.get(property.get('name'));
          a_p = Em.isNone(a_p) ? '' : ('' + a_p).toLowerCase();
          b_p = Em.isNone(b_p) ? '' : ('' + b_p).toLowerCase();
          return order ? b_p.localeCompare(a_p) : a_p.localeCompare(b_p);
        };
    }
    return func;
  },

  /**
   * method that runs contentWasChanged
   *
   * @method onContentChangeOnce
   */
  onContentChangeOnce: function() {
    var keys = arguments[1].match(/[a-zA-Z]+$/),
      key = keys.length ? keys[0] : null;
    if (key) {
      Em.run.once(this.get('controller'), 'contentWasChanged', key);
    }
  },

  /**
   * Add observer for key to call  onContentChange
   * @param key
   */
  addSortingObserver: function (key) {
    this.addObserver('controller.content.@each.' + key, this, 'onContentChangeOnce');
  },

  /**
   * Remove observer for key to call  onContentChange
   * @param key
   */
  removeSortingObserver: function (key) {
    this.removeObserver('controller.content.@each.' + key, this, 'onContentChangeOnce');
  },

  willDestroyElement: function () {
    this.removeSortingObserver(this.get('controller.sortingColumn.name'));
  }
});

/**
 * view that carry on sorting on server-side via refresh() in parentView
 * @type {*}
 */
var serverWrapperView = Em.View.extend({
  tagName: 'tr',

  classNames: ['sort-wrapper'],

  willInsertElement: function () {
    this.loadSortStatuses();
  },

  /**
   * Initialize and save sorting statuses: hostName sorting_asc
   */
  loadSortStatuses: function () {
    var childViews = this.get('childViews');
    var statuses = App.db.getSortingStatuses(this.get('controller.name'));
    if (statuses) {
      var sortingColumn = App.db.getSortingStatuses(this.get('controller.name')).find(function(column){ return column.status != 'sorting'});
      if (sortingColumn) {
        var sortingColumnView = childViews.findProperty('name', sortingColumn.name);
        sortingColumnView.set('status', sortingColumn.status);
        this.get('controller').set('sortingColumn', sortingColumnView);
      }
    } else {
      statuses = [];
      childViews.forEach(function (childView) {
        var sortStatus = (childView.get('name') == 'hostName' && childView.get('status') == 'sorting') ? 'sorting_asc' : childView.get('status');
        statuses.push({
          name: childView.get('name'),
          status: sortStatus
        });
        childView.set('status', sortStatus);
      });
      App.db.setSortingStatuses(this.get('controller.name'), statuses);
      this.get('controller').set('sortingColumn', childViews.findProperty('name', 'hostName'));
    }
  },

  /**
   * Save sort statuses to local storage
   * Works only after finish filtering in the parent View
   */
  saveSortStatuses: function () {
    var statuses = [];
    this.get('childViews').forEach(function (childView) {
      statuses.push({
        name: childView.get('name'),
        status: childView.get('status')
      });
    });
    App.db.setSortingStatuses(this.get('controller.name'), statuses);
  },

  /**
   * sort content by property
   * @param property {object}
   * @param order {Boolean} true - DESC, false - ASC
   */
  sort: function (property, order) {
    var status = order ? 'sorting_desc' : 'sorting_asc';
    var self = this;

    this.resetSort();
    this.get('childViews').findProperty('name', property.get('name')).set('status', status);
    this.saveSortStatuses();
    if (!this.get('parentView.filteringComplete')) {
      clearTimeout(this.get('parentView.timeOut'));
      this.set('parentView.timeOut', setTimeout(function () {
        self.sort(property, order);
      }, this.get('parentView.filterWaitingTime')));
    } else {
      clearTimeout(this.get('parentView.timeOut'));
      this.get('parentView').refresh();
    }
  },

  /**
   * reset all sorts fields
   */
  resetSort: function () {
    this.get('childViews').setEach('status', 'sorting');
  }
});
/**
 * particular view that contain sort field properties:
 * name - name of property in content table
 * type(optional) - specific type to sort
 * displayName - label to display
 * @type {*}
 */
var fieldView = Em.View.extend({
  template: Em.Handlebars.compile('{{view.displayName}}'),
  classNameBindings: ['viewNameClass'],
  tagName: 'th',
  name: null,
  displayName: null,
  status: 'sorting',
  viewNameClass: function () {
    return 'sort-view-' + this.get('column');
  }.property(),
  type: null,
  column: 0,
  /**
   * callback that run sorting and define order of sorting
   * @param event
   */
  click: function (event) {
    var wrapperView = this.get('parentView');
    var currentObserverProperty = this.get('controller.sortingColumn.name');
    wrapperView.sort(this, (this.get('status') !== 'sorting_desc'));

    // add observer for sorting property key to apply sorting if some value will be changed
    if (currentObserverProperty) {
      wrapperView.removeSortingObserver(currentObserverProperty);
    }

    wrapperView.addSortingObserver(this.get('name'));
    this.get('controller').set('sortingColumn', this);
  }
});

/**
 * Result object, which will be accessible outside
 * @type {Object}
 */
module.exports = {
  serverWrapperView: serverWrapperView,
  wrapperView: wrapperView,
  fieldView: fieldView
};<commit_msg>AMBARI-17663 - Hosts page: JS error when sorting (rzang)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 misc = require('utils/misc');
var stringUtils = require('utils/string_utils');
var App = require('app');

/**
 * Wrapper View for all sort components. Layout template and common actions are located inside of it.
 * Logic specific for sort fields
 * located in inner view - fieldView.
 *
 * @type {*}
 */
var wrapperView = Em.View.extend({
  tagName: 'tr',

  classNames: ['sort-wrapper'],

  willInsertElement: function () {
    if (this.get('parentView.tableFilteringComplete')) {
      this.get('parentView').set('filteringComplete', true);
    }
  },

  /**
   * Load sort statuses from local storage
   * Works only after finish filtering in the parent View
   */
  loadSortStatuses: function () {
    var statuses = App.db.getSortingStatuses(this.get('controller.name'));
    if (!this.get('parentView.filteringComplete')) return;
    if (statuses) {
      var childViews = this.get('childViews');
      var self = this;
      statuses.forEach(function (st) {
        if (st.status != 'sorting') {
          var sortOrder = false;
          if (st.status == 'sorting_desc') {
            sortOrder = true;
          }
          self.sort(childViews.findProperty('name', st.name), sortOrder);
          childViews.findProperty('name', st.name).set('status', (sortOrder) ? 'sorting_desc' : 'sorting_asc');
          self.get('controller').set('sortingColumn', childViews.findProperty('name', st.name));
        }
        else {
          childViews.findProperty('name', st.name).set('status', st.status);
        }
      });
    }
  }.observes('parentView.filteringComplete'),

  /**
   * Save sort statuses to local storage
   * Works only after finish filtering in the parent View
   */
  saveSortStatuses: function () {
    if (!this.get('parentView.filteringComplete')) return;

    var statuses = [];
    this.get('childViews').forEach(function (childView) {
      statuses.push({
        name: childView.get('name'),
        status: childView.get('status')
      });
    });
    App.db.setSortingStatuses(this.get('controller.name'), statuses);
  },

  /**
   * sort content by property
   * @param property {object}
   * @param order {Boolean} true - DESC, false - ASC
   * @param returnSorted {Boolean}
   */
  sort: function (property, order, returnSorted) {
    var content = this.get('content').toArray();
    var sortFunc = this.getSortFunc(property, order);
    var status = order ? 'sorting_desc' : 'sorting_asc';

    this.resetSort();
    this.get('childViews').findProperty('name', property.get('name')).set('status', status);
    this.saveSortStatuses(property, order);
    content.sort(sortFunc);

    if (!!returnSorted) {
      return content;
    } else {
      this.set('content', content);
    }
  },

  isSorting: false,

  onContentChange: function () {
    if (!this.get('isSorting') && this.get('content.length')) {
      this.get('childViews').forEach(function (view) {
        if (view.status !== 'sorting') {
          var status = view.get('status');
          this.set('isSorting', true);
          this.sort(view, status == 'sorting_desc');
          this.set('isSorting', false);
          view.set('status', status);
        }
      }, this);
    }
  }.observes('controller.contentUpdater'),

  /**
   * reset all sorts fields
   */
  resetSort: function () {
    this.get('childViews').setEach('status', 'sorting');
  },
  /**
   * determines sort function depending on the type of sort field
   * @param property
   * @param order
   * @return {*}
   */
  getSortFunc: function (property, order) {
    var func;
    switch (property.get('type')) {
      case 'ip':
        func = function (a, b) {
          var a = misc.ipToInt(a.get(property.get('name')));
          var b = misc.ipToInt(b.get(property.get('name')));
          if (order) {
            return a - b;
          } else {
            return b - a;
          }
        };
        break;
      case 'number':
        func = function (a, b) {
          var a_p = a.get(property.get('name'));
          var b_p = b.get(property.get('name'));
          a_p = Em.isNone(a_p) ? -Infinity : parseFloat(a_p);
          b_p = Em.isNone(b_p) ? -Infinity : parseFloat(b_p);
          if (order) {
            return a_p - b_p;
          } else {
            return b_p - a_p
          }
        };
        break;
      case 'version':
        func = function (a, b) {
          var res = stringUtils.compareVersions(a.get(property.get('name')), b.get(property.get('name')));
          if (order) {
            return -res;
          } else {
            return res;
          }
        };
        break;
      case 'alert_status':
        func = App.AlertDefinition.getSortDefinitionsByStatus(order);
        break;
      default:
        func = function (a, b) {
          var a_p = a.get(property.get('name'));
          var b_p = b.get(property.get('name'));
          a_p = Em.isNone(a_p) ? '' : ('' + a_p).toLowerCase();
          b_p = Em.isNone(b_p) ? '' : ('' + b_p).toLowerCase();
          return order ? b_p.localeCompare(a_p) : a_p.localeCompare(b_p);
        };
    }
    return func;
  },

  /**
   * method that runs contentWasChanged
   *
   * @method onContentChangeOnce
   */
  onContentChangeOnce: function() {
    var keys = arguments[1].match(/[a-zA-Z]+$/),
      key = keys.length ? keys[0] : null;
    if (key) {
      Em.run.once(this.get('controller'), 'contentWasChanged', key);
    }
  },

  /**
   * Add observer for key to call  onContentChange
   * @param key
   */
  addSortingObserver: function (key) {
    this.addObserver('controller.content.@each.' + key, this, 'onContentChangeOnce');
  },

  /**
   * Remove observer for key to call  onContentChange
   * @param key
   */
  removeSortingObserver: function (key) {
    this.removeObserver('controller.content.@each.' + key, this, 'onContentChangeOnce');
  },

  willDestroyElement: function () {
    this.removeSortingObserver(this.get('controller.sortingColumn.name'));
  }
});

/**
 * view that carry on sorting on server-side via refresh() in parentView
 * @type {*}
 */
var serverWrapperView = Em.View.extend({
  tagName: 'tr',

  classNames: ['sort-wrapper'],

  willInsertElement: function () {
    this.loadSortStatuses();
  },

  /**
   * Initialize and save sorting statuses: hostName sorting_asc
   */
  loadSortStatuses: function () {
    var childViews = this.get('childViews');
    var statuses = App.db.getSortingStatuses(this.get('controller.name'));
    if (statuses) {
      var sortingColumn = App.db.getSortingStatuses(this.get('controller.name')).find(function(column){ return column.status != 'sorting'});
      if (sortingColumn) {
        var sortingColumnView = childViews.findProperty('name', sortingColumn.name);
        sortingColumnView.set('status', sortingColumn.status);
        this.get('controller').set('sortingColumn', sortingColumnView);
      }
    } else {
      statuses = [];
      childViews.forEach(function (childView) {
        var sortStatus = (childView.get('name') == 'hostName' && childView.get('status') == 'sorting') ? 'sorting_asc' : childView.get('status');
        statuses.push({
          name: childView.get('name'),
          status: sortStatus
        });
        childView.set('status', sortStatus);
      });
      App.db.setSortingStatuses(this.get('controller.name'), statuses);
      this.get('controller').set('sortingColumn', childViews.findProperty('name', 'hostName'));
    }
  },

  /**
   * Save sort statuses to local storage
   * Works only after finish filtering in the parent View
   */
  saveSortStatuses: function () {
    var statuses = [];
    this.get('childViews').forEach(function (childView) {
      statuses.push({
        name: childView.get('name'),
        status: childView.get('status')
      });
    });
    App.db.setSortingStatuses(this.get('controller.name'), statuses);
  },

  /**
   * sort content by property
   * @param property {object}
   * @param order {Boolean} true - DESC, false - ASC
   */
  sort: function (property, order) {
    var status = order ? 'sorting_desc' : 'sorting_asc';
    var self = this;

    this.resetSort();
    this.get('childViews').findProperty('name', property.get('name')).set('status', status);
    this.saveSortStatuses();
    if (!this.get('parentView.filteringComplete')) {
      clearTimeout(this.get('parentView.timeOut'));
      this.set('parentView.timeOut', setTimeout(function () {
        self.sort(property, order);
      }, this.get('parentView.filterWaitingTime')));
    } else {
      clearTimeout(this.get('parentView.timeOut'));
      this.get('parentView').refresh();
    }
  },

  /**
   * reset all sorts fields
   */
  resetSort: function () {
    this.get('childViews').setEach('status', 'sorting');
  }
});
/**
 * particular view that contain sort field properties:
 * name - name of property in content table
 * type(optional) - specific type to sort
 * displayName - label to display
 * @type {*}
 */
var fieldView = Em.View.extend({
  template: Em.Handlebars.compile('{{view.displayName}}'),
  classNameBindings: ['viewNameClass'],
  tagName: 'th',
  name: null,
  displayName: null,
  status: 'sorting',
  viewNameClass: function () {
    return 'sort-view-' + this.get('column');
  }.property(),
  type: null,
  column: 0,
  /**
   * callback that run sorting and define order of sorting
   * @param event
   */
  click: function (event) {
    var wrapperView = this.get('parentView');
    wrapperView.sort(this, (this.get('status') !== 'sorting_desc'));

    // add observer for sorting property key to apply sorting if some value will be changed
    if (wrapperView.addSortingObserver && wrapperView.removeSortingObserver) {
      var currentObserverProperty = this.get('controller.sortingColumn.name');
      if (currentObserverProperty) {
        wrapperView.removeSortingObserver(currentObserverProperty);
      }
      wrapperView.addSortingObserver(this.get('name'));
    }
    this.get('controller').set('sortingColumn', this);
  }
});

/**
 * Result object, which will be accessible outside
 * @type {Object}
 */
module.exports = {
  serverWrapperView: serverWrapperView,
  wrapperView: wrapperView,
  fieldView: fieldView
};<|endoftext|>


<commit_before>define(["after-body/promise-utils/promise-throttler"], function() {

  QUnit.module('promise-utils/promise-throttler');

  QUnit.test("cancel trailing", function(assert) {
    assert.expect(1);
    var done = assert.async();

    var check = [];

    var throttler = promiseThrottler(function(name) {
      check.push('call:' + name);
      return Promise
        .delay(100)
        .then(function() {
          check.push('resolve:' + name);
        })
        .finally(function() {
          check.push('finally:' + name);
        });
    });

    Promise
      .all([
        throttler('foo'),
        throttler('bar')
      ])
      .finally(function() {
        assert.deepEqual(check, ['call:foo', 'resolve:foo', 'finally:foo']);
        done();
      });
  });

  QUnit.test("cancel leading", function(assert) {
    assert.expect(1);
    var done = assert.async();

    var check = [];

    var throttler = promiseThrottler(function(name) {
      check.push('call:' + name);
      return Promise
        .delay(100)
        .then(function() {
          check.push('resolve:' + name);
        })
        .finally(function() {
          check.push('finally:' + name);
        });
    }, {cancelLeading: true});

    throttler('foo').then(function() {
      assert.ok(false);
    });
    throttler('bar').finally(function() {
      assert.deepEqual(check, ['call:foo', 'finally:foo', 'call:foo', 'resolve:bar', 'finally:bar']);
      done();
    });
  });

  QUnit.test("cancel queue", function(assert) {
    assert.expect(1);
    var done = assert.async();

    var check = [];

    var throttler = promiseThrottler(function(name) {
      check.push('call:' + name);
      return Promise
        .delay(100)
        .then(function() {
          check.push('resolve:' + name);
        })
        .finally(function() {
          check.push('finally:' + name);
        });
    }, {queue: true});

    Promise
      .all([
        throttler('foo'),
        throttler('bar')
      ])
      .finally(function() {
        assert.deepEqual(check, ['call:foo', 'resolve:foo', 'finally:foo', 'call:bar', 'resolve:bar', 'finally:bar']);
        done();
      });
  });
});
<commit_msg>Fix promise-throttler test<commit_after>define(["after-body/promise-utils/promise-throttler"], function() {

  QUnit.module('promise-utils/promise-throttler');

  QUnit.test("cancel trailing", function(assert) {
    assert.expect(1);
    var done = assert.async();

    var check = [];

    var throttler = promiseThrottler(function(name) {
      check.push('call:' + name);
      return Promise
        .delay(100)
        .then(function() {
          check.push('resolve:' + name);
        })
        .finally(function() {
          check.push('finally:' + name);
        });
    });

    Promise
      .all([
        throttler('foo'),
        throttler('bar')
      ])
      .finally(function() {
        assert.deepEqual(check, ['call:foo', 'resolve:foo', 'finally:foo']);
        done();
      });
  });

  QUnit.test("cancel leading", function(assert) {
    assert.expect(1);
    var done = assert.async();

    var check = [];

    var throttler = promiseThrottler(function(name) {
      check.push('call:' + name);
      return Promise
        .delay(100)
        .then(function() {
          check.push('resolve:' + name);
        })
        .finally(function() {
          check.push('finally:' + name);
        });
    }, {cancelLeading: true});

    throttler('foo').then(function() {
      assert.ok(false);
    });
    throttler('bar').finally(function() {
      assert.deepEqual(check, ['call:foo', 'finally:foo', 'call:bar', 'resolve:bar', 'finally:bar']);
      done();
    });
  });

  QUnit.test("cancel queue", function(assert) {
    assert.expect(1);
    var done = assert.async();

    var check = [];

    var throttler = promiseThrottler(function(name) {
      check.push('call:' + name);
      return Promise
        .delay(100)
        .then(function() {
          check.push('resolve:' + name);
        })
        .finally(function() {
          check.push('finally:' + name);
        });
    }, {queue: true});

    Promise
      .all([
        throttler('foo'),
        throttler('bar')
      ])
      .finally(function() {
        assert.deepEqual(check, ['call:foo', 'resolve:foo', 'finally:foo', 'call:bar', 'resolve:bar', 'finally:bar']);
        done();
      });
  });
});
<|endoftext|>


<commit_before>/* global define:true */
define([
    'jquery',
    'pixi',
    'signals',
    'gs',
    'experience/issue',
    'experience/circle',
    'experience/responsive',
    'jquery-mobile'
], function (
    $,
    PIXI,
    signals,
    gs,
    Issue,
    Circle,
    Responsive
) {
    'use strict';

    var ExperienceCanvas = function () {
        this.issues = [];
        this.tags = [];
        this.fakes = [];

        this.canvasSize = new PIXI.Point();

        this.renderStartS = new signals.Signal();
        this.renderEndS = new signals.Signal();

        this.swipeLeftS = new signals.Signal();
        this.swipeRightS = new signals.Signal();
        this.pressIssueS = new signals.Signal();

        return this;
    };

    /**
    * Sets HTML element for PIXI container
    * @param  {object} DOM object
    */
    ExperienceCanvas.prototype.init = function (container) {
        this.canvasSize.x = container.width();
        this.canvasSize.y = container.height();

        Responsive.SIZE = this.canvasSize;

        // create pixijs renderer and stage
        this._renderer = new PIXI.autoDetectRenderer(
            this.canvasSize.x,
            this.canvasSize.y,
            {transparent: true, antialias: true});
        this._stage = new PIXI.Stage();
        this._stage.interactive = true;
        container.append(this._renderer.view);

        // lines
        this._linesContainer = new PIXI.Graphics();
        this._linesContainer.x = Math.round(this._renderer.width / 2);
        this._linesContainer.y = Math.round(this._renderer.height / 2);
        this._stage.addChild(this._linesContainer);

        // particles
        this._particlesContainer = new PIXI.DisplayObjectContainer();
        this._particlesContainer.interactive = true;
        this._particlesContainer.x = this._linesContainer.x;
        this._particlesContainer.y = this._linesContainer.y;
        this._stage.addChild(this._particlesContainer);

        // start rendering
        requestAnimationFrame(this._render.bind(this));

        this._drawFakes();

        // touch events
        this._stage.touchstart = this._onTouchStart.bind(this);
        $(document).on('swipeleft', container, this._onSwipeLeft.bind(this));
        $(document).on('swiperight', container, this._onSwipeRight.bind(this));
    };

    ExperienceCanvas.prototype.hide = function () {
        if (!this._isHidden) {
            this._stage.removeChild(this._linesContainer);
            this._stage.removeChild(this._particlesContainer);
        }
        this._isHidden = true;
    };

    ExperienceCanvas.prototype.show = function () {
        if (this._isHidden) {
            this._stage.addChild(this._linesContainer);
            this._stage.addChild(this._particlesContainer);
        }
        this._isHidden = false;
    };

    /**
    * Draw fake circles on canvas
    */
    ExperienceCanvas.prototype._drawFakes = function () {
        var circle;
        for (var i = 0; i < 200; i ++) {
            circle = new Circle();

            this.fakes.push(circle);
            this._particlesContainer.addChild(circle.elm);

            circle.draw(1);
            circle.elm.alpha = 0.3;
        }
    };

    /**
    * Draw tags on canvas
    */
    ExperienceCanvas.prototype.drawTags = function (tagData) {
        this._tagData = tagData;

        var tag;
        var i;
        var j;
        for (i = 0; i < this._tagData.length; i ++) {
            for (j = 0; j < 3; j ++) { // multiply current tags
                tag = new Issue(i, this.canvasSize);
                tag.setIsInteractive(false);
                tag.initRadius = 2;

                this.tags.push(tag);
                this._particlesContainer.addChild(tag.elm);

                tag.setData(this._tagData[i]);
                tag.draw(tag.initRadius);
                tag.pressS.add(this._onPressIssue.bind(this));
            }
        }
    };

    /**
    * Draw issues on canvas
    */
    ExperienceCanvas.prototype.drawIssues = function (issueData) {
        this._issueData = issueData;

        var issue;
        for (var i = 0; i < this._issueData.length; i ++) {
            issue = new Issue(i, this.canvasSize);
            issue.initRadius = 5;
            this.issues.push(issue);
            this._particlesContainer.addChild(issue.elm);

            issue.setData(this._issueData[i]);
            issue.draw(issue.initRadius);
            issue.pressS.add(this._onPressIssue.bind(this));
        }
    };

    ExperienceCanvas.prototype._onPressIssue = function (issue) {
        this.pressIssueS.dispatch(issue);
    };

    ExperienceCanvas.prototype.addChild = function (child) {
        this._stage.addChild(child);
    };

    ExperienceCanvas.prototype.removeChild = function (child) {
        this._stage.removeChild(child);
    };

    /**
     * update particle positions
     */
    ExperienceCanvas.prototype._updateParticles = function () {
        var i;

        for (i = 0; i < this.issues.length; i ++) {
            this.issues[i].update(this.mousePosition);
            this.issues[i].setRadius();
        }

        for (i = 0; i < this.tags.length; i ++) {
            this.tags[i].update(this.mousePosition);
        }
    };

    /**
     * Clear lines from canvas
     */
    ExperienceCanvas.prototype.clearLines = function () {
        this._linesContainer.clear();
    };

    /**
     * Hide lines container
     */
    ExperienceCanvas.prototype.hideLines = function () {
        gs.TweenMax.to(this._linesContainer, 0.3, {alpha: 0, overwrite: true});
    };

    /**
     * Show lines container
     */
    ExperienceCanvas.prototype.showLines = function () {
        gs.TweenMax.to(this._linesContainer, 0.3, {alpha: 1, overwrite: true});
    };

    /**
     * Draw a line on canvas
     * @param  {Circle} issue origin particle
     * @param  {Circle} related destination particle
     * @param  {Number} color line color
     * @param  {Number} alpha line alpha
     */
    ExperienceCanvas.prototype.drawLine = function (issue, related, color, alpha) {
        this._linesContainer.lineStyle(1, color,  alpha);
        this._linesContainer.moveTo(issue.elm.x, issue.elm.y);
        this._linesContainer.lineTo(related.elm.x, related.elm.y);
    };

    /**
    * Get visual element from id
    */
    ExperienceCanvas.prototype.getElementByData = function (data) {
        if (data.elm) {
            return data.elm;
        }

        var i;

        for (i = 0; i < this.issues.length; i ++) {
            if (this.issues[i].data._id === data._id) {
                data.elm = this.issues[i];
                return this.issues[i];
            }
        }

        for (i = 0; i < this.tags.length; i ++) {
            if (this.tags[i].data._id === data._id) {
                data.elm = this.tags[i];
                return this.tags[i];
            }
        }
    };

    ExperienceCanvas.prototype._onTouchStart = function (event) {
        this._touchPosition = event.global;
    };

    ExperienceCanvas.prototype._onSwipeLeft = function () {
        this.swipeLeftS.dispatch();
    };

    ExperienceCanvas.prototype._onSwipeRight = function () {
        this.swipeRightS.dispatch();
    };

    /**
     * Updates _mousePosition
     */
    ExperienceCanvas.prototype._updateMousePosition = function () {
        // mouse position
        var mousePosition = this._stage.getMousePosition().clone();

        // get position from touch if theres one
        if (this._touchPosition) {
            mousePosition = this._touchPosition.clone();
        }

        // make it relative to container
        mousePosition.x -= this._particlesContainer.x;
        mousePosition.y -= this._particlesContainer.y;

        if (this.autoModePosition) {
            mousePosition = this.autoModePosition.clone();
        }

        this.mousePosition = mousePosition;
    };

    /**
     * do render cycle
     */
    ExperienceCanvas.prototype._render = function () {
        this.renderStartS.dispatch();

        // update elements
        this._updateMousePosition();
        this._updateParticles();

        // render canvas
        this._renderer.render(this._stage);
        requestAnimationFrame(this._render.bind(this));

        this.renderEndS.dispatch();
    };

    return ExperienceCanvas;
});
<commit_msg>moved back to CanvasRenderer, preparation for retina<commit_after>/* global define:true */
define([
    'jquery',
    'pixi',
    'signals',
    'gs',
    'experience/issue',
    'experience/circle',
    'experience/responsive',
    'jquery-mobile'
], function (
    $,
    PIXI,
    signals,
    gs,
    Issue,
    Circle,
    Responsive
) {
    'use strict';

    var ExperienceCanvas = function () {
        this.issues = [];
        this.tags = [];
        this.fakes = [];

        this.canvasSize = new PIXI.Point();

        this.renderStartS = new signals.Signal();
        this.renderEndS = new signals.Signal();

        this.swipeLeftS = new signals.Signal();
        this.swipeRightS = new signals.Signal();
        this.pressIssueS = new signals.Signal();

        return this;
    };

    /**
    * Sets HTML element for PIXI container
    * @param  {object} DOM object
    */
    ExperienceCanvas.prototype.init = function (container) {
        Responsive.RATIO = window.devicePixelRatio;
        Responsive.SIZE = new PIXI.Point(container.width(), container.height());
        // Responsive.SIZE.x /= Responsive.RATIO;
        // Responsive.SIZE.y /= Responsive.RATIO;

        this.canvasSize = Responsive.SIZE;

        // create pixijs renderer and stage
        this._renderer = new PIXI.CanvasRenderer(
            this.canvasSize.x,
            this.canvasSize.y,
            {transparent: true, antialias: true, resolution: 1});
        this._stage = new PIXI.Stage();
        this._stage.interactive = true;
        container.append(this._renderer.view);

        // lines
        this._linesContainer = new PIXI.Graphics();
        this._linesContainer.x = Math.round(this._renderer.width / 2);
        this._linesContainer.y = Math.round(this._renderer.height / 2);
        this._stage.addChild(this._linesContainer);

        // particles
        this._particlesContainer = new PIXI.DisplayObjectContainer();
        this._particlesContainer.interactive = true;
        this._particlesContainer.x = this._linesContainer.x;
        this._particlesContainer.y = this._linesContainer.y;
        this._stage.addChild(this._particlesContainer);

        // start rendering
        requestAnimationFrame(this._render.bind(this));

        this._drawFakes();

        // touch events
        this._stage.touchstart = this._onTouchStart.bind(this);
        $(document).on('swipeleft', container, this._onSwipeLeft.bind(this));
        $(document).on('swiperight', container, this._onSwipeRight.bind(this));
    };

    ExperienceCanvas.prototype.hide = function () {
        if (!this._isHidden) {
            this._stage.removeChild(this._linesContainer);
            this._stage.removeChild(this._particlesContainer);
        }
        this._isHidden = true;
    };

    ExperienceCanvas.prototype.show = function () {
        if (this._isHidden) {
            this._stage.addChild(this._linesContainer);
            this._stage.addChild(this._particlesContainer);
        }
        this._isHidden = false;
    };

    /**
    * Draw fake circles on canvas
    */
    ExperienceCanvas.prototype._drawFakes = function () {
        var circle;
        for (var i = 0; i < 200; i ++) {
            circle = new Circle();

            this.fakes.push(circle);
            this._particlesContainer.addChild(circle.elm);

            circle.draw(1);
            circle.elm.alpha = 0.3;
        }
    };

    /**
    * Draw tags on canvas
    */
    ExperienceCanvas.prototype.drawTags = function (tagData) {
        this._tagData = tagData;

        var tag;
        var i;
        var j;
        for (i = 0; i < this._tagData.length; i ++) {
            for (j = 0; j < 3; j ++) { // multiply current tags
                tag = new Issue(i, this.canvasSize);
                tag.setIsInteractive(false);
                tag.initRadius = 2;

                this.tags.push(tag);
                this._particlesContainer.addChild(tag.elm);

                tag.setData(this._tagData[i]);
                tag.draw(tag.initRadius);
                tag.pressS.add(this._onPressIssue.bind(this));
            }
        }
    };

    /**
    * Draw issues on canvas
    */
    ExperienceCanvas.prototype.drawIssues = function (issueData) {
        this._issueData = issueData;

        var issue;
        for (var i = 0; i < this._issueData.length; i ++) {
            issue = new Issue(i, this.canvasSize);
            issue.initRadius = 5;
            this.issues.push(issue);
            this._particlesContainer.addChild(issue.elm);

            issue.setData(this._issueData[i]);
            issue.draw(issue.initRadius);
            issue.pressS.add(this._onPressIssue.bind(this));
        }
    };

    ExperienceCanvas.prototype._onPressIssue = function (issue) {
        this.pressIssueS.dispatch(issue);
    };

    ExperienceCanvas.prototype.addChild = function (child) {
        this._stage.addChild(child);
    };

    ExperienceCanvas.prototype.removeChild = function (child) {
        this._stage.removeChild(child);
    };

    /**
     * update particle positions
     */
    ExperienceCanvas.prototype._updateParticles = function () {
        var i;

        for (i = 0; i < this.issues.length; i ++) {
            this.issues[i].update(this.mousePosition);
            this.issues[i].setRadius();
        }

        for (i = 0; i < this.tags.length; i ++) {
            this.tags[i].update(this.mousePosition);
        }
    };

    /**
     * Clear lines from canvas
     */
    ExperienceCanvas.prototype.clearLines = function () {
        this._linesContainer.clear();
    };

    /**
     * Hide lines container
     */
    ExperienceCanvas.prototype.hideLines = function () {
        gs.TweenMax.to(this._linesContainer, 0.3, {alpha: 0, overwrite: true});
    };

    /**
     * Show lines container
     */
    ExperienceCanvas.prototype.showLines = function () {
        gs.TweenMax.to(this._linesContainer, 0.3, {alpha: 1, overwrite: true});
    };

    /**
     * Draw a line on canvas
     * @param  {Circle} issue origin particle
     * @param  {Circle} related destination particle
     * @param  {Number} color line color
     * @param  {Number} alpha line alpha
     */
    ExperienceCanvas.prototype.drawLine = function (issue, related, color, alpha) {
        this._linesContainer.lineStyle(1, color,  alpha);
        this._linesContainer.moveTo(issue.elm.x, issue.elm.y);
        this._linesContainer.lineTo(related.elm.x, related.elm.y);
    };

    /**
    * Get visual element from id
    */
    ExperienceCanvas.prototype.getElementByData = function (data) {
        if (data.elm) {
            return data.elm;
        }

        var i;

        for (i = 0; i < this.issues.length; i ++) {
            if (this.issues[i].data._id === data._id) {
                data.elm = this.issues[i];
                return this.issues[i];
            }
        }

        for (i = 0; i < this.tags.length; i ++) {
            if (this.tags[i].data._id === data._id) {
                data.elm = this.tags[i];
                return this.tags[i];
            }
        }
    };

    ExperienceCanvas.prototype._onTouchStart = function (event) {
        this._touchPosition = event.global;
    };

    ExperienceCanvas.prototype._onSwipeLeft = function () {
        this.swipeLeftS.dispatch();
    };

    ExperienceCanvas.prototype._onSwipeRight = function () {
        this.swipeRightS.dispatch();
    };

    /**
     * Updates _mousePosition
     */
    ExperienceCanvas.prototype._updateMousePosition = function () {
        // mouse position
        var mousePosition = this._stage.getMousePosition().clone();

        // get position from touch if theres one
        if (this._touchPosition) {
            mousePosition = this._touchPosition.clone();
        }

        // make it relative to container
        mousePosition.x -= this._particlesContainer.x;
        mousePosition.y -= this._particlesContainer.y;

        if (this.autoModePosition) {
            mousePosition = this.autoModePosition.clone();
        }

        this.mousePosition = mousePosition;
    };

    /**
     * do render cycle
     */
    ExperienceCanvas.prototype._render = function () {
        this.renderStartS.dispatch();

        // update elements
        this._updateMousePosition();
        this._updateParticles();

        // render canvas
        this._renderer.render(this._stage);
        requestAnimationFrame(this._render.bind(this));

        this.renderEndS.dispatch();
    };

    return ExperienceCanvas;
});
<|endoftext|>


<commit_before>'use strict';
angular.module('genie.common')
.directive('timeSeries', ['ChartService', 'StylesService',
  'CoreService','ChartDataChangedMsg','ChartDateSelectedMsg',
  function (ChartService, StylesService, CoreService,
    ChartDataChangedMsg, ChartDateSelectedMsg) {

  function link(scope, elem, attrs) {
    var chart;
    var bgColor = StylesService.darkColor;
    var slowSelectionChange = _.debounce(selectionChange, 300);
    var PERIOD = CoreService.env.period; // days
    var DAY = CoreService.env.day; // mins
    var startDay = new Date(scope.getSetting('zoomLevels:startDate'));
    var endDay = new Date(scope.getSetting('zoomLevels:endDate'));
    var chartInterval = 'day';

    ChartDataChangedMsg.listen(function(_, data, interval) {
      var startDate, endDate;
      chartInterval = interval;
      data.rows.forEach(function(row){
        if(!startDate && !endDate){
          startDate = endDate = row[0];
          return;
        }
        if(row[0] > endDate){
          endDate = row[0];
        }
        if(row[0] < startDate){
          startDate = row[0];
        }
      });
      refreshChart(data, new Date(startDate), new Date(endDate));
    });

    function getCountsByInterval(startDate, endDate, columns) {
      var countsByInterval = [];
      var current = new Date(startDate);
      while (current <= endDate) {
        var row = columns.map(function(col){
          return col.type === 'date' ? current : 0;
        });
        countsByInterval.push(row);
        var dat = new Date(current.valueOf());
        if (chartInterval === 'day') {
          dat.setDate(dat.getDate() + 1);
        }
        if (chartInterval === 'hour') {
          dat.setHours(dat.getHours() + 1);
        }
        current = dat;
      }

      return countsByInterval;
    }

    function getDateId(date){
      // normalize string, epoch or date input to date object
      var dateVal = new Date(date);

      return chartInterval === 'day' ?
        dateVal.toLocaleDateString() :
        dateVal.toLocaleDateString() + ':' + dateVal.getHours();
    }

    function insertRowData(rows, target){
      rows.forEach(function(row) {
        var rowId = getDateId(row[0], chartInterval);
        for(var i=0; i<target.length; i++){
          var targetId = getDateId(target[i][0], chartInterval);
          if (rowId === targetId) {
            row[0] = target[i][0];
            target[i] = row;
            break;
          }
        }
      });

      return target;
    }

    function selectionChange() {
      var selection = chart.getSelection()[0];
      if (selection) {
        if (chartInterval === 'hour') {
          ChartDateSelectedMsg
          .broadcast(selection.row, scope.timeSeries.rows[selection.row][0]);
        }
        scope.$apply(function() {
          if (chartInterval === 'day') {
            var endDate = moment(scope.getSetting('zoomLevels:endDate'));
            var selectedDate = moment(scope.timeSeries.rows[selection.row][0]);
            var diff = endDate.diff(selectedDate, 'days')+1;
            var minsAgo = diff * DAY * PERIOD;
            scope.inputs.minutes_ago = minsAgo;
          }
          scope.timeSeries.selectedDate = scope.timeSeries.rows[selection.row][0];
        });
      }
    }

    function refreshChart(chartData, startDate, endDate) {
      if (chart) {
        chart.clearChart();
      }
      var rows = getCountsByInterval(startDate, endDate, chartData.columns);
      rows = insertRowData(chartData.rows, rows);
      // can't access data from graph once its plotted so store for later
      scope.timeSeries.rows = rows;
      var data = new google.visualization.DataTable();
      if (rows.length) {
        chartData.columns.forEach(function(col) {
          data.addColumn(col.type, col.label);
        });
        data.addRows(rows);

        chart = new google.visualization.AnnotationChart(elem[0]);
        google.visualization.events.addListener(chart, 'select',
          slowSelectionChange);

        chart.draw(data, options);
        // show the line dot (doesn't show tooltips, wtf?)
        // chart.setSelection([{row: 0, column: null}]);
      } else {
        CoreService.alertInfo('Missing Data',
          'No time-series data: check system settings for start, end dates');
      }
    }

    var options = {
      displayAnnotations: false,
      displayZoomButtons: false,
      displayRangeSelector: false,
      displayLegendDots: false,
      fill: 10,
      min: 0,
      chart: {
        backgroundColor: bgColor,
        chartArea: {
          backgroundColor: bgColor
        },
        vAxis: {
          gridlines: {
            color: bgColor
          },
          textStyle: {color: '#FFF'}
        },
        hAxis: {
          gridlines: {
            color: bgColor
          },
          textStyle: {color: '#FFF'}
        }
      }
    };

    // initial load (by day)
    ChartService.getData(attrs.chartName)
      .then(function(chartData) {
        refreshChart(chartData, startDay, endDay);
        // show the line dot (doesn't show tooltips, wtf?)
        var rows = chartData.rows;
        var lastRow = rows.length;
        chart.setSelection([{row: lastRow, column: null}]);
        scope.timeSeries.selectedDate = rows[0][0];
      });
  }

  return {
    restrict: 'AE',
    link: link,
    replace: true,
    template: "

"
  };
}]);
<commit_msg>fix time series chart bug<commit_after>'use strict';
angular.module('genie.common')
.directive('timeSeries', ['ChartService', 'StylesService',
  'CoreService','ChartDataChangedMsg','ChartDateSelectedMsg',
  function (ChartService, StylesService, CoreService,
    ChartDataChangedMsg, ChartDateSelectedMsg) {

  function link(scope, elem, attrs) {
    var chart;
    var bgColor = StylesService.darkColor;
    var slowSelectionChange = _.debounce(selectionChange, 300);
    var PERIOD = CoreService.env.period; // days
    var DAY = CoreService.env.day; // mins
    var startDay = new Date(scope.getSetting('zoomLevels:startDate'));
    var endDay = new Date(scope.getSetting('zoomLevels:endDate'));
    var chartInterval = 'day';

    ChartDataChangedMsg.listen(function(_, data, interval) {
      var startDate, endDate;
      chartInterval = interval;
      data.rows.forEach(function(row){
        if(!startDate && !endDate){
          startDate = endDate = row[0];
          return;
        }
        if(row[0] > endDate){
          endDate = row[0];
        }
        if(row[0] < startDate){
          startDate = row[0];
        }
      });
      refreshChart(data, new Date(startDate), new Date(endDate));
    });

    function getCountsByInterval(startDate, endDate, columns) {
      var countsByInterval = [];
      var current = new Date(startDate);
      while (current <= endDate) {
        var row = columns.map(function(col){
          return col.type === 'date' ? current : 0;
        });
        countsByInterval.push(row);
        var dat = new Date(current.valueOf());
        if (chartInterval === 'day') {
          dat.setDate(dat.getDate() + 1);
        }
        if (chartInterval === 'hour') {
          dat.setHours(dat.getHours() + 1);
        }
        current = dat;
      }

      return countsByInterval;
    }

    function getDateId(date){
      // normalize string, epoch or date input to date object
      var dateVal = new Date(date);

      return chartInterval === 'day' ?
        dateVal.toLocaleDateString() :
        dateVal.toLocaleDateString() + ':' + dateVal.getHours();
    }

    function insertRowData(rows, target){
      rows.forEach(function(row) {
        var rowId = getDateId(row[0], chartInterval);
        for(var i=0; i<target.length; i++){
          var targetId = getDateId(target[i][0], chartInterval);
          if (rowId === targetId) {
            row[0] = target[i][0];
            target[i] = row;
            break;
          }
        }
      });

      return target;
    }

    function selectionChange() {
      var selection = chart.getSelection()[0];
      if (selection) {
        if (chartInterval === 'hour') {
          ChartDateSelectedMsg
          .broadcast(selection.row, scope.timeSeries.rows[selection.row][0]);
        }
        scope.$apply(function() {
          if (chartInterval === 'day') {
            var endDate = moment(scope.getSetting('zoomLevels:endDate'));
            var selectedDate = moment(scope.timeSeries.rows[selection.row][0]);
            var diff = endDate.diff(selectedDate, 'days')+1;
            var minsAgo = diff * DAY * PERIOD;
            scope.inputs.minutes_ago = minsAgo;
          }
          scope.timeSeries.selectedDate = scope.timeSeries.rows[selection.row][0];
        });
      }
    }

    function refreshChart(chartData, startDate, endDate) {
      if (chart) {
        chart.clearChart();
      }
      var rows = getCountsByInterval(startDate, endDate, chartData.columns);
      rows = insertRowData(chartData.rows, rows);
      // can't access data from graph once its plotted so store for later
      scope.timeSeries.rows = rows;
      var data = new google.visualization.DataTable();
      if (rows.length) {
        chartData.columns.forEach(function(col) {
          data.addColumn(col.type, col.label);
        });
        data.addRows(rows);

        chart = new google.visualization.AnnotationChart(elem[0]);
        google.visualization.events.addListener(chart, 'select',
          slowSelectionChange);

        chart.draw(data, options);
        // show the line dot (doesn't show tooltips, wtf?)
        // chart.setSelection([{row: 0, column: null}]);
      } else {
        CoreService.alertInfo('Missing Data',
          'No time-series data: check system settings for start, end dates');
      }
    }

    var options = {
      displayAnnotations: false,
      displayZoomButtons: false,
      displayRangeSelector: false,
      displayLegendDots: false,
      fill: 10,
      min: 0,
      chart: {
        backgroundColor: bgColor,
        chartArea: {
          backgroundColor: bgColor
        },
        vAxis: {
          gridlines: {
            color: bgColor
          },
          textStyle: {color: '#FFF'}
        },
        hAxis: {
          gridlines: {
            color: bgColor
          },
          textStyle: {color: '#FFF'}
        }
      }
    };

    // initial load (by day)
    ChartService.getData(attrs.chartName)
      .then(function(chartData) {
        refreshChart(chartData, startDay, endDay);
        // show the line dot (doesn't show tooltips, wtf?)
        var rows = chartData.rows;
        var lastRow = rows.length+1;
        chart.setSelection([{row: lastRow, column: null}]);
        scope.timeSeries.selectedDate = rows[0][0];
      });
  }

  return {
    restrict: 'AE',
    link: link,
    replace: true,
    template: "

"
  };
}]);
<|endoftext|>


<commit_before>exports.run = function (bot, msg, args) {
    if (args.length < 1) {
        msg.edit(':no_entry_sign: You must specify what to search for.')
            .then(m => m.delete(2000));
        return;
    }

    var query = args.join(' ');

    msg.edit(`:arrows_counterclockwise: Searching the last \`100\` messages for \`${query}\``)
        .then(m => {

            msg.channel.fetchMessages({ limit: 100, before: msg.id })
                .then(messages => {
                    var results = messages.filter(it => it.content.toLowerCase().indexOf(query.toLowerCase()) != -1);
                    var output = results
                        .map(it => `[${it.createdAt.getDay()}/${it.createdAt.getMonth()}/${it.createdAt.getYear() + 1900} ${it.createdAt.getHours()}:${it.createdAt.getMinutes()}:${it.createdAt.getSeconds()}] [${it.author.username}] ${it.content}`)
                        .join('\n');
                    console.log(output);
                    m.editCode('log', output);

                }).catch(err => {
                    console.error(err);
                    m.edit(':no_entry_sign:');
                });

        });

};

exports.info = {
    name: 'search',
    usage: 'search <# of messages> <search text>',
    description: 'Searches a certain number of messages for the given search text'
};<commit_msg>Made date-formatting work better1<commit_after>function formatDate(date) {
    return `[${_(date.getDay())}/${_(date.getMonth())}/${_(date.getYear() - 100)}] [${_(date.getHours())}:${_(date.getMinutes())}:${_(date.getSeconds())}]`;
}

function _(number) {
    return number < 10 ? '0' + number : '' + number;
}

exports.run = function (bot, msg, args) {
    if (args.length < 1) {
        msg.edit(':no_entry_sign: You must specify what to search for.')
            .then(m => m.delete(2000));
        return;
    }

    var query = args.join(' ');

    msg.edit(`:arrows_counterclockwise: Searching the last \`100\` messages for \`${query}\``)
        .then(m => {

            msg.channel.fetchMessages({ limit: 100, before: msg.id })
                .then(messages => {
                    var results = messages.filter(it => it.content.toLowerCase().indexOf(query.toLowerCase()) != -1);
                    var output = results
                        .map(it => `${formatDate(it.createdAt)} ${it.author.username}: ${it.content}`)
                        .join('\n');
                    console.log(output);
                    m.editCode('log', output);

                }).catch(err => {
                    console.error(err);
                    m.edit(':no_entry_sign:');
                });

        });

};

exports.info = {
    name: 'search',
    usage: 'search <# of messages> <search text>',
    description: 'Searches a certain number of messages for the given search text'
};<|endoftext|>


<commit_before>/* =========================================================================
 *
 * Console
 *      Default transport - console
 *
 * ========================================================================= */
var STYLES = require('../styles');
var SYMBOLS = require('../symbols');

// --------------------------------------
//
// Setup group Colors to print
//
// --------------------------------------
GROUP_COLORS = [
    STYLES.colors.blue,
    STYLES.colors.magenta,
    STYLES.colors.green,
    STYLES.colors.yellow,
    STYLES.colors.cyan,
    STYLES.colors.red,

    STYLES.backgrounds.white + STYLES.colors.black,
    STYLES.backgrounds.blue + STYLES.colors.white,
    STYLES.backgrounds.magenta + STYLES.colors.white,
    STYLES.backgrounds.green + STYLES.colors.white,

    STYLES.backgrounds.blue + STYLES.colors.black,
    STYLES.backgrounds.white + STYLES.colors.magenta,
    STYLES.backgrounds.magenta + STYLES.colors.black,
    STYLES.backgrounds.green + STYLES.colors.black,
    STYLES.backgrounds.cyan + STYLES.colors.white,
    STYLES.backgrounds.green + STYLES.colors.grey,
    STYLES.backgrounds.magenta + STYLES.colors.green,

    STYLES.backgrounds.yellow + STYLES.colors.red,

    STYLES.backgrounds.white + STYLES.colors.grey,
    STYLES.backgrounds.magenta + STYLES.colors.blue,

    STYLES.backgrounds.green + STYLES.colors.white
];
OVERFLOW_SYMBOLS = [
    'asertik', 'floral', 'snowflake', 'fourDiamond', 'spade', 'club', 'heart',
    'diamond', 'queen', 'rook', 'pawn', 'atom'
];

// ======================================
//
// Console Transport
//
// ======================================
function TransportConsole ( options ){
    options = options || {};
    // Transport must set groupsEnabled and groupsDisabled to provide transport
    // level support for overriding what groups to log
    // (NOTE - the user does not need to pass in groupsEnabled, but the
    // transport must set these properties)
    this.groupsEnabled = options.groupsEnabled;
    this.groupsDisabled = options.groupsDisabled;

    // Display / meta related config options
    // ----------------------------------
    // showStackTrace: {Boolean} provide the full stack trace? Disabled
    // by default
    this.showStackTrace = options.showStackTrace !== undefined ? options.showStackTrace: false;

    // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    // TODO: Deprecate this...currently this exists for older version:
    if(options.showFullStackTrace === true){ this.showStackTrace = true; }
    // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    // showMeta: {Boolean} Show the meta info (calling func, time, line num, etc)
    //  NOTE: This is primarily used only if you want to disable everything.
    //  If this is true and showStackTrace
    //  options will be checked. If it is set to false, nothing will be shown
    this.showMeta = options.showMeta !== undefined ? options.showMeta : true;

    // Transport specific settings
    // ----------------------------------
    this.showColors = options.showColors === undefined ? true : options.showColor;

    this._foundColors = [];
    this._colorDict = {
        error: STYLES.styles.bold + SYMBOLS.error + ' ' +
            STYLES.styles.blink + STYLES.backgrounds.red + STYLES.colors.white,
        warn: STYLES.styles.bold + STYLES.styles.blink + STYLES.backgrounds.yellow +
            STYLES.colors.white
    };

    this.curSymbolIndex = 0;

    return this;
}

TransportConsole.prototype.getColor = function getColor(group){
    // Color Formatting
    // ----------------------------------
    // Returns the background color for a passed in log group
    // TODO: if more found colors exist than the original length of the
    // COLOR array, cycle back and modify the original color
    //
    var color = '';
    var baseColor = '';
    var curSymbol;

    // For color, get the first group
    group = group.split(':')[0];

    // if a color exists for the passed in log group, use it
    if(this._colorDict[group]){
        return this._colorDict[group];
    }

    if(this._foundColors.length >= GROUP_COLORS.length){
        // is the index too high? loop around if so
        color = GROUP_COLORS[this._foundColors.length % GROUP_COLORS.length];
        baseColor = color;

        // setup symbol
        // ------------------------------
        if(!OVERFLOW_SYMBOLS[this.curSymbolIndex]){
            // reset index to 0
            this.curSymbolIndex = 0;
        }
        curSymbol = SYMBOLS[OVERFLOW_SYMBOLS[this.curSymbolIndex]];
        this.curSymbolIndex++;

        // add underline if odd
        // ------------------------------
        if(this._foundColors.length % GROUP_COLORS.length === 1){
            color += STYLES.styles.underline;
        }

        // set final color
        // ------------------------------
        color += baseColor + curSymbol;

    } else {

        // We haven't yet exhausted all the colors
        color = GROUP_COLORS[this._foundColors.length];
    }

    // update the stored color info
    this._foundColors.push(color);
    this._colorDict[group] = color;

    return color;
};

// Prototype properties (All these must exist to be a valid transport)
// --------------------------------------
TransportConsole.prototype.name = 'Console';

TransportConsole.prototype.log = function transportConsoleLog( loggedObject ){
    // log
    //  Logs a passed object to the console
    //
    //  params:
    //      loggedObject: {Object} the log object to log
    //      options : {Object} the logger options
    //
    // Setup message for console output
    // ------------------------------
    //  The final message will look like:
    //      [ group ]      message
    //      meta info (function caller, time, file info)
    //
    var consoleMessage = "";

    // Setup final log message format, depending on if it's a browser or not
    // ------------------------------
    consoleMessage +=
        STYLES.colors.reset + "[ " +
            (this.getColor(loggedObject.group) + ' ' +
                loggedObject.group +
            ' ' + STYLES.colors.reset) +
        " ] \t";

    // NOTE: Use the full styledMessage property
    consoleMessage += loggedObject.styledMessage + STYLES.colors.reset;

    // Include some meta info (time, function that called, etc.)
    // ----------------------------------
    if(this.showMeta){
        consoleMessage += '\n' + STYLES.colors.grey;

        // Show the name of the calling function
        consoleMessage += 'caller: ' + loggedObject.meta.caller + ' \t    ';
        // JSON timestamp
        consoleMessage += new Date().toJSON() + ' \t ';

        // For node, log line number and filename
        if(loggedObject.meta.file && loggedObject.meta.line ){
            consoleMessage +=  loggedObject.meta.file +
                ':' + loggedObject.meta.line +
                ':' + loggedObject.meta.column +
                '';
        }

        consoleMessage += STYLES.colors.reset;
    }

    if(this.showStackTrace && loggedObject.meta.trace){
        // Show full stack trace if set
        // --------------------------
        consoleMessage += '\n' + STYLES.colors.reset + STYLES.backgrounds.white +
            STYLES.colors.black +
            '(Stack Trace)' +
            STYLES.colors.reset +
            '\n';

        // Skip the first item in the stack (this function)
        for(i=0; i<loggedObject.meta.trace.length; i++){
            consoleMessage += STYLES.colors.reset + '\t' +
                loggedObject.meta.trace[i] + '\n';
        }
    }

    consoleMessage += '\n';

    // Log it
    // ------------------------------
    console.log( consoleMessage );

    return this;
};

module.exports = TransportConsole;
<commit_msg>adds ability to add line breaks to console transport<commit_after>/* =========================================================================
 *
 * Console
 *      Default transport - console
 *
 * ========================================================================= */
var STYLES = require('../styles');
var SYMBOLS = require('../symbols');

// --------------------------------------
//
// Setup group Colors to print
//
// --------------------------------------
GROUP_COLORS = [
    STYLES.colors.blue,
    STYLES.colors.magenta,
    STYLES.colors.green,
    STYLES.colors.yellow,
    STYLES.colors.cyan,
    STYLES.colors.red,

    STYLES.backgrounds.white + STYLES.colors.black,
    STYLES.backgrounds.blue + STYLES.colors.white,
    STYLES.backgrounds.magenta + STYLES.colors.white,
    STYLES.backgrounds.green + STYLES.colors.white,

    STYLES.backgrounds.blue + STYLES.colors.black,
    STYLES.backgrounds.white + STYLES.colors.magenta,
    STYLES.backgrounds.magenta + STYLES.colors.black,
    STYLES.backgrounds.green + STYLES.colors.black,
    STYLES.backgrounds.cyan + STYLES.colors.white,
    STYLES.backgrounds.green + STYLES.colors.grey,
    STYLES.backgrounds.magenta + STYLES.colors.green,

    STYLES.backgrounds.yellow + STYLES.colors.red,

    STYLES.backgrounds.white + STYLES.colors.grey,
    STYLES.backgrounds.magenta + STYLES.colors.blue,

    STYLES.backgrounds.green + STYLES.colors.white
];
OVERFLOW_SYMBOLS = [
    'asertik', 'floral', 'snowflake', 'fourDiamond', 'spade', 'club', 'heart',
    'diamond', 'queen', 'rook', 'pawn', 'atom'
];

// ======================================
//
// Console Transport
//
// ======================================
function TransportConsole ( options ){
    options = options || {};
    // Transport must set groupsEnabled and groupsDisabled to provide transport
    // level support for overriding what groups to log
    // (NOTE - the user does not need to pass in groupsEnabled, but the
    // transport must set these properties)
    this.groupsEnabled = options.groupsEnabled;
    this.groupsDisabled = options.groupsDisabled;

    // Display / meta related config options
    // ----------------------------------
    // showStackTrace: {Boolean} provide the full stack trace? Disabled
    // by default
    this.showStackTrace = options.showStackTrace !== undefined ? options.showStackTrace: false;

    this.addLineBreak = options.addLineBreak !== undefined ? options.addLineBreak : true;

    // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    // TODO: Deprecate this...currently this exists for older version:
    if(options.showFullStackTrace === true){ this.showStackTrace = true; }
    // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    // showMeta: {Boolean} Show the meta info (calling func, time, line num, etc)
    //  NOTE: This is primarily used only if you want to disable everything.
    //  If this is true and showStackTrace
    //  options will be checked. If it is set to false, nothing will be shown
    this.showMeta = options.showMeta !== undefined ? options.showMeta : true;

    // Transport specific settings
    // ----------------------------------
    this.showColors = options.showColors === undefined ? true : options.showColor;

    this._foundColors = [];
    this._colorDict = {
        error: STYLES.styles.bold + SYMBOLS.error + ' ' +
            STYLES.styles.blink + STYLES.backgrounds.red + STYLES.colors.white,
        warn: STYLES.styles.bold + STYLES.styles.blink + STYLES.backgrounds.yellow +
            STYLES.colors.white
    };

    this.curSymbolIndex = 0;

    return this;
}

TransportConsole.prototype.getColor = function getColor(group){
    // Color Formatting
    // ----------------------------------
    // Returns the background color for a passed in log group
    // TODO: if more found colors exist than the original length of the
    // COLOR array, cycle back and modify the original color
    //
    var color = '';
    var baseColor = '';
    var curSymbol;

    // For color, get the first group
    group = group.split(':')[0];

    // if a color exists for the passed in log group, use it
    if(this._colorDict[group]){
        return this._colorDict[group];
    }

    if(this._foundColors.length >= GROUP_COLORS.length){
        // is the index too high? loop around if so
        color = GROUP_COLORS[this._foundColors.length % GROUP_COLORS.length];
        baseColor = color;

        // setup symbol
        // ------------------------------
        if(!OVERFLOW_SYMBOLS[this.curSymbolIndex]){
            // reset index to 0
            this.curSymbolIndex = 0;
        }
        curSymbol = SYMBOLS[OVERFLOW_SYMBOLS[this.curSymbolIndex]];
        this.curSymbolIndex++;

        // add underline if odd
        // ------------------------------
        if(this._foundColors.length % GROUP_COLORS.length === 1){
            color += STYLES.styles.underline;
        }

        // set final color
        // ------------------------------
        color += baseColor + curSymbol;

    } else {

        // We haven't yet exhausted all the colors
        color = GROUP_COLORS[this._foundColors.length];
    }

    // update the stored color info
    this._foundColors.push(color);
    this._colorDict[group] = color;

    return color;
};

// Prototype properties (All these must exist to be a valid transport)
// --------------------------------------
TransportConsole.prototype.name = 'Console';

TransportConsole.prototype.log = function transportConsoleLog( loggedObject ){
    // log
    //  Logs a passed object to the console
    //
    //  params:
    //      loggedObject: {Object} the log object to log
    //      options : {Object} the logger options
    //
    // Setup message for console output
    // ------------------------------
    //  The final message will look like:
    //      [ group ]      message
    //      meta info (function caller, time, file info)
    //
    var consoleMessage = "";

    // Setup final log message format, depending on if it's a browser or not
    // ------------------------------
    consoleMessage +=
        STYLES.colors.reset + "[ " +
            (this.getColor(loggedObject.group) + ' ' +
                loggedObject.group +
            ' ' + STYLES.colors.reset) +
        " ] \t";

    // NOTE: Use the full styledMessage property
    consoleMessage += loggedObject.styledMessage + STYLES.colors.reset;

    // Include some meta info (time, function that called, etc.)
    // ----------------------------------
    if(this.showMeta){
        consoleMessage += '\n' + STYLES.colors.grey;

        // Show the name of the calling function
        consoleMessage += 'caller: ' + loggedObject.meta.caller + ' \t    ';
        // JSON timestamp
        consoleMessage += new Date().toJSON() + ' \t ';

        // For node, log line number and filename
        if(loggedObject.meta.file && loggedObject.meta.line ){
            consoleMessage +=  loggedObject.meta.file +
                ':' + loggedObject.meta.line +
                ':' + loggedObject.meta.column +
                '';
        }

        consoleMessage += STYLES.colors.reset;
    }

    if(this.showStackTrace && loggedObject.meta.trace){
        // Show full stack trace if set
        // --------------------------
        consoleMessage += '\n' + STYLES.colors.reset + STYLES.backgrounds.white +
            STYLES.colors.black +
            '(Stack Trace)' +
            STYLES.colors.reset +
            '\n';

        // Skip the first item in the stack (this function)
        for(i=0; i<loggedObject.meta.trace.length; i++){
            consoleMessage += STYLES.colors.reset + '\t' +
                loggedObject.meta.trace[i] + '\n';
        }
    }

    // add line break to console messages if set
    if(options.addLineBreak){
        consoleMessage += '\n';
    }

    // Log it
    // ------------------------------
    console.log( consoleMessage );

    return this;
};

module.exports = TransportConsole;
<|endoftext|>