<commit_before>var bootcomplete = angular.module('bootcomplete', []);

bootcomplete.
directive('bootcomplete', ["$compile", "$templateRequest", "$timeout", "$sce", function ($compile, $templateRequest, $timeout, $sce) {
    return {
        restric: 'E',
        transclude: true,
        replace: true,
        scope: {
            btcSize: '@',
            btcTemplate: '@',
            btcMinlength: '@',
            btcLabel: '@',
            btcPlaceholder: '@',
            btcMaxresults: '@',
            btcNoresults: '@',
            btcKeepselection: '@',
            btcEmptyonclose:'@',
            btcQuery: '=',
            btcCallback: '=',
            bindModel: '=ngModel'
        },
        template: "
\n" +
            "<input placeholder='{{btcPlaceholder}}' type='text' class='form-control' ng-model='bindModel' ng-blur='blur($event)' autocomplete=\"off\"/>\n" +
            "\n" +
            "
",
        link: function (scope, element, attrs, controller) {

            var input = element[0].querySelector('.form-control'),
                suggestionTemplate = "
\n" +
                "
\n" +
                "\n" +
                "
\n" +
                "
\n" +
                "{{noresultsMsg}}\n" +
                "
\n" +
                "
",
                _getCords = function () {
                    var box = input.getBoundingClientRect(),
                        top = box.top + window.pageYOffset,
                        left = box.left + window.pageXOffset;

                    scope.top = (top + box.height + 1) + 'px';
                    scope.left = left + 'px';
                    scope.width = box.width + 'px';
                };

            scope.results = [];
            scope.selectedIndex = -1;
            scope.minlength = scope.btcMinlength || 1;
            scope.noresultsMsg = scope.btcNoresults || 'Your search yielded no results';

            scope.$watch("visible", function (newValue, oldValue) {
                if (newValue === false) {
                    return;
                }
                _getCords();
            });

            // select item
            scope.select = function (index) {

                if (!scope.btcTemplate)
                    delete scope.results[index].btclabel; // delete label from object

                // clear input if we don't want to display the selection
                if (!scope.btcKeepselection) {
                    input.value = '';
                }
                // otherwise update the input with the selected value, and get out of focus
                else {
                    input.value = scope.results[index][scope.btcLabel];
                    input.blur();
                }
                // call the callback with the result as parameter
                if (scope.btcCallback)
                    scope.btcCallback.call(this, scope.results[index]);

                scope.close();
            };

            // close autocomplete
            scope.close = function () {
                scope.visible = false;
                scope.selectedIndex = -1;
                if(!scope.btcKeepselection)
                    input.value='';
            };

            // close on blur
            scope.blur = function (e) {
                setTimeout(function () {
                    var focused = document.activeElement;
                    if (focused.tagName !== 'A' || focused.className.indexOf('btc-clickLink') === -1) {
                        scope.close();
                        scope.$apply();
                    } // check the elemnt with focus
                }, 1);
            };

            // append element to the DOM
            scope.makeDom = function (html) {
                document.body.appendChild(html);
            };

            input.onkeyup = function (e) {
                scope.search = e.target.value;
                if (scope.search.length >= scope.minlength && e.keyCode !== 40 && e.keyCode !== 38 && e.keyCode !== 27) {
                    scope.loading = true;
                    var promise = scope.btcQuery.call(null, scope.search);
                    promise.then(function (results) {

                        // max result length
                        scope.results = scope.btcMaxresults ? results.slice(0, scope.btcMaxresults) : results;

                        // results label
                        if (!scope.btcTemplate) {
                            scope.results.map(function (result) {
                                result.btclabel = result[scope.btcLabel];
                                result.btclabel = $sce.trustAsHtml(result[scope.btcLabel].replace(new RegExp(scope.search, 'gi'), '$&'));
                                return result;
                            });
                        }

                        scope.visible = true;
                        $timeout(function () {
                            scope.loading = false;
                        }, 100);

                    });
                }
                if (scope.search.length === 0) {
                    scope.close();
                }
            };

            element[0].onkeydown = function (e) {
                //up
                if (e.keyCode === 40) {
                    if (scope.selectedIndex + 1 === scope.results.length) {
                        scope.selectedIndex = 0;
                    } else {
                        scope.selectedIndex++;
                    }
                }
                //down
                if (e.keyCode === 38) {
                    if (scope.selectedIndex === 0) {
                        scope.selectedIndex = scope.results.length - 1;
                    }
                    if (scope.selectedIndex === -1) {
                        scope.selectedIndex = 0;
                    } else scope.selectedIndex--;
                }
                //enter
                if (e.keyCode === 13) {
                    if (scope.selectedIndex != -1)
                        scope.select(scope.selectedIndex);
                }
                //esc or tab
                if (e.keyCode === 27 || e.keyCode === 9) {
                    scope.close();
                }

                scope.$apply();
            };

            var wrapper = "
",
                wrapper_closure = "
";

            if (scope.btcTemplate) {

                $templateRequest(scope.btcTemplate).then(function (template) {
                    var output = wrapper + template + wrapper_closure,
                        compiledhtml = $compile(output)(scope)[0];

                    scope.makeDom(compiledhtml);
                });
            } else {

                var output = wrapper + suggestionTemplate + wrapper_closure,
                    compiledhtml = $compile(output)(scope)[0];

                scope.makeDom(compiledhtml);
            }
        }
    };
}]);<commit_msg>Fixing bug from state change<commit_after>var bootcomplete = angular.module('bootcomplete', []);

bootcomplete.
directive('bootcomplete', ["$compile", "$templateRequest", "$timeout", "$sce", function ($compile, $templateRequest, $timeout, $sce) {
    return {
        restric: 'E',
        transclude: true,
        replace: true,
        scope: {
            btcSize: '@',
            btcTemplate: '@',
            btcMinlength: '@',
            btcLabel: '@',
            btcPlaceholder: '@',
            btcMaxresults: '@',
            btcNoresults: '@',
            btcKeepselection: '@',
            btcEmptyonclose:'@',
            btcQuery: '=',
            btcCallback: '=',
            bindModel: '=ngModel'
        },
        template: "
\n" +
            "<input placeholder='{{btcPlaceholder}}' type='text' class='form-control' ng-model='bindModel' ng-blur='blur($event)' autocomplete=\"off\"/>\n" +
            "\n" +
            "
",
        link: function (scope, element, attrs, controller) {

            var input = element[0].querySelector('.form-control'),
                suggestionTemplate = "
\n" +
                "
\n" +
                "\n" +
                "
\n" +
                "
\n" +
                "{{noresultsMsg}}\n" +
                "
\n" +
                "
",
                _getCords = function () {
                    var box = input.getBoundingClientRect(),
                        top = box.top + window.pageYOffset,
                        left = box.left + window.pageXOffset;

                    scope.top = (top + box.height + 1) + 'px';
                    scope.left = left + 'px';
                    scope.width = box.width + 'px';
                };

            scope.results = [];
            scope.selectedIndex = -1;
            scope.minlength = scope.btcMinlength || 1;
            scope.noresultsMsg = scope.btcNoresults || 'Your search yielded no results';

            scope.$watch("visible", function (newValue, oldValue) {
                if (newValue === false) {
                    return;
                }
                _getCords();
            });

            // select item
            scope.select = function (index) {

                if (!scope.btcTemplate)
                    delete scope.results[index].btclabel; // delete label from object

                // clear input if we don't want to display the selection
                if (!scope.btcKeepselection) {
                    input.value = '';
                }
                // otherwise update the input with the selected value, and get out of focus
                else {
                    input.value = scope.results[index][scope.btcLabel];
                    input.blur();
                }
                // call the callback with the result as parameter
                if (scope.btcCallback)
                    scope.btcCallback.call(this, scope.results[index]);

                scope.close();
            };

            // close autocomplete
            scope.close = function () {
                scope.visible = false;
                scope.selectedIndex = -1;
                if(!scope.btcKeepselection)
                    input.value='';
            };

            // close on blur
            scope.blur = function (e) {
                setTimeout(function () {
                    var focused = document.activeElement;
                    if (focused.tagName !== 'A' || focused.className.indexOf('btc-clickLink') === -1) {
                        scope.close();
                        scope.$apply();
                    } // check the elemnt with focus
                }, 1);
            };

            // append element to the DOM
            scope.makeDom = function (html) {
                document.body.appendChild(html);
            };

            scope.$on('$destroy', function () {
                var elements = document.body.getElementsByClassName('wrapper_bootcomplete');
                while(elements.length > 0){
                    elements[0].parentNode.removeChild(elements[0]);
                }
            });

            input.onkeyup = function (e) {
                scope.search = e.target.value;
                if (scope.search.length >= scope.minlength && e.keyCode !== 40 && e.keyCode !== 38 && e.keyCode !== 27) {
                    scope.loading = true;
                    var promise = scope.btcQuery.call(null, scope.search);
                    promise.then(function (results) {

                        // max result length
                        scope.results = scope.btcMaxresults ? results.slice(0, scope.btcMaxresults) : results;

                        // results label
                        if (!scope.btcTemplate) {
                            scope.results.map(function (result) {
                                result.btclabel = result[scope.btcLabel];
                                result.btclabel = $sce.trustAsHtml(result[scope.btcLabel].replace(new RegExp(scope.search, 'gi'), '$&'));
                                return result;
                            });
                        }

                        scope.visible = true;
                        $timeout(function () {
                            scope.loading = false;
                        }, 100);

                    });
                }
                if (scope.search.length === 0) {
                    scope.close();
                }
            };

            element[0].onkeydown = function (e) {
                //up
                if (e.keyCode === 40) {
                    if (scope.selectedIndex + 1 === scope.results.length) {
                        scope.selectedIndex = 0;
                    } else {
                        scope.selectedIndex++;
                    }
                }
                //down
                if (e.keyCode === 38) {
                    if (scope.selectedIndex === 0) {
                        scope.selectedIndex = scope.results.length - 1;
                    }
                    if (scope.selectedIndex === -1) {
                        scope.selectedIndex = 0;
                    } else scope.selectedIndex--;
                }
                //enter
                if (e.keyCode === 13) {
                    if (scope.selectedIndex != -1)
                        scope.select(scope.selectedIndex);
                }
                //esc or tab
                if (e.keyCode === 27 || e.keyCode === 9) {
                    scope.close();
                }

                scope.$apply();
            };

            var wrapper = "
",
                wrapper_closure = "
";

            if (scope.btcTemplate) {

                $templateRequest(scope.btcTemplate).then(function (template) {
                    var output = wrapper + template + wrapper_closure,
                        compiledhtml = $compile(output)(scope)[0];

                    scope.makeDom(compiledhtml);
                });
            } else {

                var output = wrapper + suggestionTemplate + wrapper_closure,
                    compiledhtml = $compile(output)(scope)[0];

                scope.makeDom(compiledhtml);
            }
        }
    };
}]);
<|endoftext|>


<commit_before>var template = require('./helpers/template.js');

var timeoutDuration = 10000;

var actions = {
    assert: require('./actions/assert.js').bind(casper),
    capture: require('./actions/capture.js').bind(casper),
    dom: require('./actions/dom.js').bind(casper),
    get: require('./actions/get.js').bind(casper),
    request: require('./actions/request.js').bind(casper),
    wait: require('./actions/wait.js').bind(casper)
};

var config = function (casper, cwd) {
    return {
        execute: function (task) {
            if (task.type && actions[task.type]) {
                var response;
                task = template.parse(task);
                response = actions[task.type](
                    task.params,
                    timeoutDuration,
                    cwd
                );

                if (task.type === 'get') {
                    template.store(task.params.key, response);
                }
                return response;
            } else {
                log('no task found for: ', task, 'ERROR');
                throw new Error('no task found');
            }
        },
        navigate: function (url, next) {
            log('navigate to', url, 'INFO_BAR');
            var loadSuccess = function (status) {
                casper.removeListener('load.failed', loadFailed);
                casper.removeListener('load.finished', loadSuccess);
                if (status === 'fail') {
                    next('fail');
                } else {
                    next();
                }
            };
            var loadFailed = function (err) {
                casper.removeListener('load.failed', loadFailed);
                casper.removeListener('load.finished', loadSuccess);
                next(err);
            };
            casper.on('load.failed', loadFailed);
            casper.on('load.finished', loadSuccess);
            return casper.start(url);
        }
    };
};

module.exports = {
    config: config
};
<commit_msg>fix(actions): remove binding casper since casper is global<commit_after>var template = require('./helpers/template.js');

var timeoutDuration = 10000;

var actions = {
    assert: require('./actions/assert.js'),
    capture: require('./actions/capture.js'),
    dom: require('./actions/dom.js'),
    get: require('./actions/get.js'),
    request: require('./actions/request.js'),
    wait: require('./actions/wait.js')
};

var config = function (casper, cwd) {
    return {
        execute: function (task) {
            if (task.type && actions[task.type]) {
                var response;
                task = template.parse(task);
                response = actions[task.type](
                    task.params,
                    timeoutDuration,
                    cwd
                );

                if (task.type === 'get') {
                    template.store(task.params.key, response);
                }
                return response;
            } else {
                log('no task found for: ', task, 'ERROR');
                throw new Error('no task found');
            }
        },
        navigate: function (url, next) {
            log('navigate to', url, 'INFO_BAR');
            var loadSuccess = function (status) {
                casper.removeListener('load.failed', loadFailed);
                casper.removeListener('load.finished', loadSuccess);
                if (status === 'fail') {
                    next('fail');
                } else {
                    next();
                }
            };
            var loadFailed = function (err) {
                casper.removeListener('load.failed', loadFailed);
                casper.removeListener('load.finished', loadSuccess);
                next(err);
            };
            casper.on('load.failed', loadFailed);
            casper.on('load.finished', loadSuccess);
            return casper.start(url);
        }
    };
};

module.exports = {
    config: config
};
<|endoftext|>


<commit_before>function notSupported() {
    console.log('ContentSync is not supported on browser platform');
}

var ContentSync = function() {};
ContentSync.prototype.on = function() {};
ContentSync.prototype.emit = function() {};
ContentSync.prototype.cancel = function() {};

function sync() {
    notSupported();
    return new ContentSync();
}

module.exports = {
    sync: sync,
    unzip: notSupported,
    download: notSupported,
    ContentSync: ContentSync
};
<commit_msg>Added error output for successive calls to sync functions<commit_after>function notSupported() {
    console.log('ContentSync is not supported on browser platform');
}

var ContentSync = function() {};
ContentSync.prototype.on = function() { notSupported(); };
ContentSync.prototype.emit = function() { notSupported(); };
ContentSync.prototype.cancel = function() { notSupported(); };

function sync() {
    notSupported();
    return new ContentSync();
}

module.exports = {
    sync: sync,
    unzip: notSupported,
    download: notSupported,
    ContentSync: ContentSync
};
<|endoftext|>


<commit_before>window.blog = {DEUBUG: true};

require.config({
  paths: {
    text: 'lib/require-text',
    css: 'lib/require-css',

    jquery: 'lib/jquery',

    underscore: 'lib/underscore',
    'underscore.crunch': 'lib/underscore.crunch',

    backbone: 'lib/backbone',

    marked: 'lib/marked',
    'marked.highlight': 'lib/marked.highlight',

    moment: 'lib/moment',

    highlight: 'lib/highlight'
  },

  shim: {
    highlight: {
      deps: ['css!style/highlight.css'],
      exports: 'hljs'
    }
  }
});

require(['views', 'css!style/main.css'], function(V) {
  new V.List({el: $('body')});
});
<commit_msg>Add backbone routing.<commit_after>require.config({
  paths: {
    text: 'lib/require-text',
    css: 'lib/require-css',

    jquery: 'lib/jquery',

    underscore: 'lib/underscore',
    'underscore.crunch': 'lib/underscore.crunch',

    backbone: 'lib/backbone',

    marked: 'lib/marked',
    'marked.highlight': 'lib/marked.highlight',

    moment: 'lib/moment',

    highlight: 'lib/highlight'
  },

  shim: {
    highlight: {
      deps: ['css!style/highlight.css'],
      exports: 'hljs'
    }
  }
});

require(['backbone', 'models', 'views', 'css!style/main.css'], function(B, M, V) {
  new (B.Router.extend({
    routes: {'': 'list'},
    list: function() { new V.List({el: $('body')}); }
  }));

  B.history.start({root: '/living-with-django/'});
});
<|endoftext|>


<commit_before>var sprites = [];
var arrows, item, bucket, emitter, cloud, pipe1, pipe2, pipe3, pipe4;
var rainDirection = 1;
var rainSaved = 0;
var velocity = 12;
var rainAmount = 1;
var rainLifespan = 1500;
var GameTime = 20;
var rainDrop;
var GameScoreText,TimerText;
var splashEmitter;

var MaxSplashParticles = 40;
var SingleSplashParticles = 20;
var SplashLifespan = 500;
var SplashYRange = 0;
var SplashXRange = 0;

var LeakMaxSpeed = 500;

function tick() {
  if (arrows.right.isDown) {
    bucket.x += velocity;
  }
  if (arrows.left.isDown) {
    bucket.x -= velocity;
  }
}

function bucketCollide(bucket, particle) {
  rainSaved += 1;
  particle.kill();
  GameScoreText.text = scoreText();
  splashEmitter.x = bucket.x + 60;
  splashEmitter.y = bucket.y;
  splashEmitter.explode(SplashLifespan, SingleSplashParticles);
}

function scoreText() {
  return "Water Saved: " + rainSaved
}

function drawScore() {
  GameScoreText = game.add.text(10, 35, scoreText());
  GameScoreText.fill = "#FFF";
  GameScoreText.fontSize = 14;
}

function drawTimer() {
  TimerText = game.add.text(750, 35, GameTime);
  TimerText.fill = "yellow";
  TimerText.fontSize = 16;
}

function drawGameOver() {
  game.physics.arcade.isPaused = true;
  GameScoreText.fontSize = 20;
  var text = game.add.text(game.world.centerX, game.world.centerY, "GAME OVER");
  text.anchor.set(0.5);
  text.fontSize = 80;
  text.fill = "#ffffff";
  emitter.on = false;
}

function update() {
  if (game.physics.arcade.isPaused) {
    return;
  }

  var timeLeft = GameTime - Math.floor(game.time.now / 1000);
  if (timeLeft <= 5) {
    TimerText.fill = "red";
  }
  if (timeLeft <= 0) {
    drawGameOver();
  }
  TimerText.text = timeLeft;

  tick();
  game.physics.arcade.collide(emitter, bucket, bucketCollide);
}

function preload() {
  game.load.image('bucket', 'img/bucket.png');
  game.load.image("pipe", "img/pipe.png");
  var rainDrop = makeRainDrop(20);
  emitter = game.add.emitter(game.world.centerX, 30, rainAmount);
  emitter.width = 400;
  emitter.makeParticles(rainDrop, 0, emitter.maxParticles, true, false);
  emitter.gravity = 800;
  emitter.minParticleScale = 1;
  emitter.maxParticleScale = 1;
  emitter.setXSpeed(0,5);
  emitter.setYSpeed(350, LeakMaxSpeed);
  emitter.start(false, rainLifespan, 10);

  splashEmitter = game.add.emitter(0, 0, 40);
  splashEmitter.width = 50;
  splashEmitter.makeParticles(makeRainDrop(10), 0);
  splashEmitter.minParticleScale = 0.4;
  splashEmitter.maxParticleScale = 1;
  splashEmitter.setYSpeed(-250 - SplashYRange, 0 + SplashYRange);
  splashEmitter.setXSpeed(-50 - SplashXRange, 50 + SplashXRange);
  splashEmitter.gravity = 400;

  arrows = game.input.keyboard.createCursorKeys();
}

function makePipes() {
  var pipeGroup = game.add.group();
  pipe1 = pipeGroup.create(5, 0, "pipe");
  pipe2 = pipeGroup.create(pipe1.x + pipe1.width - 3, 0, "pipe");
  pipe3 = pipeGroup.create(pipe2.x + pipe2.width - 3, 0, "pipe");
  pipe4 = pipeGroup.create(pipe3.x + pipe3.width - 3, 0, "pipe");
}

function create() {
  game.physics.startSystem(Phaser.Physics.ARCADE);
  bucket = game.add.sprite(30, 480, 'bucket')
  makePipes();
  game.physics.arcade.enable(bucket);
  bucket.body.collideWorldBounds = true;
  bucket.body.immovable = true;
  game.physics.arcade.enable(emitter);
  drawScore();
  drawTimer();
}

function makeRainDrop(radius) {
  var graphics = game.add.graphics(10, 10);
  graphics.moveTo(10, 10);
  graphics.beginFill(0xB6DAFF);
  graphics.drawCircle(10,10,radius);
  graphics.endFill();
  txt = graphics.generateTexture();
  graphics.destroy();
  return txt;
}
<commit_msg>Cleanup<commit_after>var sprites = [];
var arrows, item, bucket, emitter, cloud, pipe1, pipe2, pipe3, pipe4;
var rainDirection = 1;
var rainSaved = 0;
var velocity = 12;
var rainAmount = 1;
var rainLifespan = 1000;
var GameTime = 20;
var rainDrop;
var GameScoreText,TimerText;
var splashEmitter;

var MaxSplashParticles = 40;
var SingleSplashParticles = 20;
var SplashLifespan = 500;
var SplashYRange = 0;
var SplashXRange = 0;
var MaxSplashSize = 20;

var LeakMaxSpeed = 500;

function tick() {
  if (arrows.right.isDown) {
    bucket.x += velocity;
  }
  if (arrows.left.isDown) {
    bucket.x -= velocity;
  }
}

function bucketCollide(bucket, particle) {
  rainSaved += 1;
  particle.kill();
  GameScoreText.text = scoreText();
  splashEmitter.x = bucket.x + 60;
  splashEmitter.y = bucket.y;
  splashEmitter.explode(SplashLifespan, SingleSplashParticles);
}

function scoreText() {
  return "Water Saved: " + rainSaved
}

function drawScore() {
  GameScoreText = game.add.text(10, 35, scoreText());
  GameScoreText.fill = "#FFF";
  GameScoreText.fontSize = 14;
}

function drawTimer() {
  TimerText = game.add.text(750, 35, GameTime);
  TimerText.fill = "yellow";
  TimerText.fontSize = 16;
}

function drawGameOver() {
  game.physics.arcade.isPaused = true;
  GameScoreText.fontSize = 20;
  var text = game.add.text(game.world.centerX, game.world.centerY, "GAME OVER");
  text.anchor.set(0.5);
  text.fontSize = 80;
  text.fill = "#ffffff";
  emitter.on = false;
}

function update() {
  if (game.physics.arcade.isPaused) {
    return;
  }

  var timeLeft = GameTime - Math.floor(game.time.now / 1000);
  if (timeLeft <= 5) {
    TimerText.fill = "red";
  }
  if (timeLeft <= 0) {
    drawGameOver();
  }
  TimerText.text = timeLeft;

  tick();
  game.physics.arcade.collide(emitter, bucket, bucketCollide);
}

function preload() {
  game.load.image('bucket', 'img/bucket.png');
  game.load.image("pipe", "img/pipe.png");
  var rainDrop = makeRainDrop(20);
  emitter = game.add.emitter(game.world.centerX, 30, rainAmount);
  emitter.width = 400;
  emitter.makeParticles(rainDrop, 0, emitter.maxParticles, true, false);
  emitter.gravity = 800;
  emitter.minParticleScale = 1;
  emitter.maxParticleScale = 1;
  emitter.setXSpeed(0,5);
  emitter.setYSpeed(350, LeakMaxSpeed);
  emitter.start(false, rainLifespan, 10);

  splashEmitter = game.add.emitter(0, 0, 40);
  splashEmitter.width = 50;
  splashEmitter.makeParticles(makeRainDrop(MaxSplashSize), 0);
  splashEmitter.minParticleScale = 0.15;
  splashEmitter.maxParticleScale = 1;
  splashEmitter.setYSpeed(-250 - SplashYRange, 0 + SplashYRange);
  splashEmitter.setXSpeed(-50 - SplashXRange, 50 + SplashXRange);
  splashEmitter.gravity = 400;

  arrows = game.input.keyboard.createCursorKeys();
}

function makePipes() {
  var pipeGroup = game.add.group();
  pipe1 = pipeGroup.create(5, 0, "pipe");
  pipe2 = pipeGroup.create(pipe1.x + pipe1.width - 3, 0, "pipe");
  pipe3 = pipeGroup.create(pipe2.x + pipe2.width - 3, 0, "pipe");
  pipe4 = pipeGroup.create(pipe3.x + pipe3.width - 3, 0, "pipe");
}

function create() {
  game.physics.startSystem(Phaser.Physics.ARCADE);
  bucket = game.add.sprite(30, 480, 'bucket')
  makePipes();
  game.physics.arcade.enable(bucket);
  bucket.body.collideWorldBounds = true;
  bucket.body.immovable = true;
  game.physics.arcade.enable(emitter);
  drawScore();
  drawTimer();
}

function makeRainDrop(radius) {
  var graphics = game.add.graphics(10, 10);
  graphics.moveTo(10, 10);
  graphics.beginFill(0xB6DAFF);
  graphics.drawCircle(10,10,radius);
  graphics.endFill();
  txt = graphics.generateTexture();
  graphics.destroy();
  return txt;
}
<|endoftext|>


<commit_before>/**
 * Progressbar.js.
 *
 *
 * To use:
 *
 * Pass the taskId into the progrsesbar constructor OR (currently doesn't work) create a div with id "progress-area" on
 * your page, and a task id in a div with id "taskId".
 *
 * An optional update area "messages" may be used. Arrange for createIndeterminateProgressBar or
 * createDeterminateProgressBar to be called, followed by startProgress().
 *
 * @author Kelsey
 * @author Paul
 * @version $Id$
 */

progressbar = function(config) {

	Ext.apply(this, config);

	this.addEvents({
				finish : true,
				fail : true,
				cancel : true
			});

	progressbar.superclass.constructor.call(this);
};

Ext.extend(progressbar, Ext.util.Observable, {

	waiting : false,
	bar : null,
	determinate : false,
	previousMessage : "",
	timeoutid : null,
	detbarwidth : 200,

	// time in ms between updates
	BAR_UPDATE_INTERVAL : 2000,

	handleFailure : function(data, e) {
		this.stopProgress();
		var messageArea = Ext.get("messages");
		if (messageArea) {
			var messageText;
			if (data.description) {
				messageText = data.description;
			} else if (!e) {
				messageText = data;
			} else if (e.message) {
				messageText = e.message;
			} else {
				messageText = e;
			}
			this.fireEvent("fail", messageText);
		} else {
			this.fireEvent('fail');
		}
	},

	findTaskId : function() {

		// try to get from query string

		var queryStart = document.URL.indexOf("?");
		if (queryStart > -1) {
			var param = Ext.urlDecode(document.URL.substr(queryStart + 1));
			if (param.taskId)
				return param.taskId;
		}

		// try to get from hidden input field.
		return dwr.util.getValue("taskId");

		// FIME: this doesn't work nor does Ext.get("taskId")
		// the returned value is always a blank string (from both)
		// The task id is being returned from the server (checked)
		// Perhaps is some dom refresh problem

	},

	/**
	 * Start the progressbar in motion.
	 */
	startProgress : function() {
		if (this.determinate == 0) {
			document.getElementById("progressTextArea").innerHTML = "Starting job...";
		} else {
			// document.getElementById("progressTextArea").value = "Please
			// wait...";
		}

		if (!this.taskId) {

			var taskId = this.findTaskId();

			if (!taskId) {
				alert("no task id");
				return;
			}

			this.taskId = taskId;

		}
		var callParams = [];
		var callback = this.updateProgress.createDelegate(this);
		var errorHandler = this.handleFailure.createDelegate(this);
		callParams.push(callback);
		callParams.push(errorHandler);
		var f = this.refreshProgress.createDelegate(this, callParams, false);
		this.timeoutid = window.setInterval(f, this.BAR_UPDATE_INTERVAL);
	},

	stopProgress : function() {
		window.clearInterval(this.timeoutid);
		// Ext.DomHelper.overwrite("progress-area", "");
		this.previousMessage = null;
		this.waiting = false;
	},

	/*
	 * Private Callback for DWR @param {Object} data
	 */
	updateProgress : function(data) {
		this.waiting = false;
		if (this.determinate == 1) {
			this.updateDeterminateProgress(data);
		} else {
			this.updateIndeterminateProgress(data);
		}
	},

	updateDeterminateProgress : function(data) {
		var messages = "";
		var percent = 0;
		if (data.push) {
			for (var i = 0, len = data.length; i < len; i++) {
				var d = data[i];
				messages = messages + "
" + d.description;
				delta = d.percent - percent;
				percent = d.percent; // use last value.

				if (delta > 5) {
					// document.getElementById("progressTextArea").innerHTML =
					// messages + " " + percent + "%";
					document.getElementById("progress-bar-box-content").style.width = parseInt(percent
							* (detbarwidth / 100))
							+ "px";
				}

				if (d.failed) {
					this.stopProgress();
					return this.handleFailure(d);
				} else if (d.done) {
					this.fireEvent('done', d.payload);
					this.stopProgress();
					if (this.doFoward && d.forwardingURL !== undefined && d.forwardingURL !== null) {
						window.location = d.forwardingURL + "?taskId=" + this.taskId;
					} else {
						var callback = this.maybeDoForward.createDelegate(this, [], true);
						TaskCompletionController.checkResult(this.taskId, callback);
					}
					return;
				}
			}
		} else {
			if (data.done) {
				this.stopProgress();
				return this.handleFailure(data);
			} else if (d.done) {
				this.fireEvent('done', data.payload);
				this.stopProgress();
			}
			percent = data.percent;
		}

		// document.getElementById("progressTextArea").innerHTML = messages + "
		// " + percent + "%";
		document.getElementById("progress-bar-box-content").style.width = parseInt(percent * this.detbarwidth / 100)
				+ "px";
	},

	maybeDoForward : function(url) {
		if (this.doForward && url) {
			window.location = url;
		}
	},

	updateIndeterminateProgress : function(data) {

		var messages = "";
		if (data.push) {
			for (var i = 0, len = data.length; i < len; i++) {
				var d = data[i];
				messages = messages + "
" + d.description;
				if (d.failed) {
					this.stopProgress();
					return this.handleFailure(d);
				} else if (d.done) {
					this.fireEvent('done', d.payload);
					this.stopProgress();
					if (this.doFoward && d.forwardingURL !== undefined && d.forwardingURL !== null) {
						window.location = d.forwardingURL + "?taskId=" + this.taskId;
					} else {
						var callback = this.maybeDoForward.createDelegate(this, [], true);
						var errorHandler = this.handleFailure.createDelegate(this, [], true);
						TaskCompletionController.checkResult(this.taskId, {
									callback : callback,
									errorHandler : errorHandler
								});
					}
					return;
				}
			}
		} else {
			if (data.done) {
				this.stopProgress();
				return this.handleFailure(data);
			} else if (d.done) {
				this.fireEvent('done', data.payload);
				this.stopProgress();
			}
		}

		if (!document.getElementById("progressTextArea"))
			return;

		if (this.previousMessage != messages && messages.length > 0) {
			this.previousMessage = messages;
			document.getElementById("progressTextArea").innerHTML += messages;
			document.getElementById("progressTextArea").scrollTop = document.getElementById("progressTextArea").scrollHeight;
		} else {
			document.getElementById("progressTextArea").innerHTML += ".";
			document.getElementById("progressTextArea").scrollTop = document.getElementById("progressTextArea").scrollHeight;
		}
	},

	/*
	 * Private Send a cancel notification to the server.
	 */
	cancelJob : function() {
		this.waiting = false;
		document.getElementById("progressTextArea").innerHTML = "Cancelling...";
		var f = this.cancelCallback.createDelegate(this, [], true);
		ProgressStatusService.cancelJob(this.taskId, f);
	},

	/*
	 * Private Check for status from server.
	 */
	refreshProgress : function(callback, errorHandler) {
		// only check for status if we aren't already waiting for a reply.
		if (!this.waiting) {
			ProgressStatusService.getProgressStatus(this.taskId, {
						callback : callback,
						errorHandler : errorHandler
					});
			this.waiting = true;
		}
	},

	/*
	 * Private Callback to handle cancellation @param {Object} data
	 */
	cancelCallback : function(data) {
		this.stopProgress();
		var messageArea = Ext.get("messages");
		if (messageArea) {
			Ext.DomHelper.overwrite("messages", {
						tag : 'img',
						src : '/Gemma/images/icons/ok.png'
					});
			Ext.DomHelper.append("messages", " Job was cancelled.");
		}
		this.fireEvent('cancel');

	},

	/**
	 * Create a progress bar that has no fixed endpoint
	 */
	createIndeterminateProgressBar : function() {
		this.determinate = 0;
		this.bar = this.createIndeterminateBarDetails();
		f = this.cancelJob.createDelegate(this, [], true);
		Ext.get("cancel-button").on('click', f);
	},

	/**
	 * Create a progress bar that has a known endpoint
	 */
	createDeterminateProgressBar : function() {
		this.determinate = 1;
		var div = '
	<input style="float:left;margin:0px;" type="button" id="cancel-button" name="Cancel" value="Cancel job" />

'
		Ext.DomHelper.overwrite("progress-area", div);
		f = this.cancelJob.createDelegate(this, [], true);
		Ext.get("cancel-button").on('click', f);
	},

	createIndeterminateBarDetails : function() {
		var div = '
<input type="textarea" />

<input style="float:left" type="button" id="cancel-button" name="Cancel" value="Cancel job" />
';
		Ext.DomHelper.overwrite("progress-area", div);
	}

});
<commit_msg>less frequent server pinging<commit_after>/**
 * Progressbar.js.
 *
 *
 * To use:
 *
 * Pass the taskId into the progrsesbar constructor OR (currently doesn't work) create a div with id "progress-area" on
 * your page, and a task id in a div with id "taskId".
 *
 * An optional update area "messages" may be used. Arrange for createIndeterminateProgressBar or
 * createDeterminateProgressBar to be called, followed by startProgress().
 *
 * @author Kelsey
 * @author Paul
 * @version $Id$
 */

progressbar = function(config) {

	Ext.apply(this, config);

	this.addEvents({
				finish : true,
				fail : true,
				cancel : true
			});

	progressbar.superclass.constructor.call(this);
};

Ext.extend(progressbar, Ext.util.Observable, {

	waiting : false,
	bar : null,
	determinate : false,
	previousMessage : "",
	timeoutid : null,
	detbarwidth : 200,

	// time in ms between updates
	BAR_UPDATE_INTERVAL : 4000,

	handleFailure : function(data, e) {
		this.stopProgress();
		var messageArea = Ext.get("messages");
		if (messageArea) {
			var messageText;
			if (data.description) {
				messageText = data.description;
			} else if (!e) {
				messageText = data;
			} else if (e.message) {
				messageText = e.message;
			} else {
				messageText = e;
			}
			this.fireEvent("fail", messageText);
		} else {
			this.fireEvent('fail');
		}
	},

	findTaskId : function() {

		// try to get from query string

		var queryStart = document.URL.indexOf("?");
		if (queryStart > -1) {
			var param = Ext.urlDecode(document.URL.substr(queryStart + 1));
			if (param.taskId)
				return param.taskId;
		}

		// try to get from hidden input field.
		return dwr.util.getValue("taskId");

		// FIME: this doesn't work nor does Ext.get("taskId")
		// the returned value is always a blank string (from both)
		// The task id is being returned from the server (checked)
		// Perhaps is some dom refresh problem

	},

	/**
	 * Start the progressbar in motion.
	 */
	startProgress : function() {
		if (this.determinate == 0) {
			document.getElementById("progressTextArea").innerHTML = "Starting job...";
		} else {
			// document.getElementById("progressTextArea").value = "Please
			// wait...";
		}

		if (!this.taskId) {

			var taskId = this.findTaskId();

			if (!taskId) {
				alert("no task id");
				return;
			}

			this.taskId = taskId;

		}
		var callParams = [];
		var callback = this.updateProgress.createDelegate(this);
		var errorHandler = this.handleFailure.createDelegate(this);
		callParams.push(callback);
		callParams.push(errorHandler);
		var f = this.refreshProgress.createDelegate(this, callParams, false);
		this.timeoutid = window.setInterval(f, this.BAR_UPDATE_INTERVAL);
	},

	stopProgress : function() {
		window.clearInterval(this.timeoutid);
		// Ext.DomHelper.overwrite("progress-area", "");
		this.previousMessage = null;
		this.waiting = false;
	},

	/*
	 * Private Callback for DWR @param {Object} data
	 */
	updateProgress : function(data) {
		this.waiting = false;
		if (this.determinate == 1) {
			this.updateDeterminateProgress(data);
		} else {
			this.updateIndeterminateProgress(data);
		}
	},

	updateDeterminateProgress : function(data) {
		var messages = "";
		var percent = 0;
		if (data.push) {
			for (var i = 0, len = data.length; i < len; i++) {
				var d = data[i];
				messages = messages + "
" + d.description;
				delta = d.percent - percent;
				percent = d.percent; // use last value.

				if (delta > 5) {
					// document.getElementById("progressTextArea").innerHTML =
					// messages + " " + percent + "%";
					document.getElementById("progress-bar-box-content").style.width = parseInt(percent
							* (detbarwidth / 100))
							+ "px";
				}

				if (d.failed) {
					this.stopProgress();
					return this.handleFailure(d);
				} else if (d.done) {
					this.fireEvent('done', d.payload);
					this.stopProgress();
					if (this.doFoward && d.forwardingURL !== undefined && d.forwardingURL !== null) {
						window.location = d.forwardingURL + "?taskId=" + this.taskId;
					} else {
						var callback = this.maybeDoForward.createDelegate(this, [], true);
						TaskCompletionController.checkResult(this.taskId, callback);
					}
					return;
				}
			}
		} else {
			if (data.done) {
				this.stopProgress();
				return this.handleFailure(data);
			} else if (d.done) {
				this.fireEvent('done', data.payload);
				this.stopProgress();
			}
			percent = data.percent;
		}

		// document.getElementById("progressTextArea").innerHTML = messages + "
		// " + percent + "%";
		document.getElementById("progress-bar-box-content").style.width = parseInt(percent * this.detbarwidth / 100)
				+ "px";
	},

	maybeDoForward : function(url) {
		if (this.doForward && url) {
			window.location = url;
		}
	},

	updateIndeterminateProgress : function(data) {

		var messages = "";
		if (data.push) {
			for (var i = 0, len = data.length; i < len; i++) {
				var d = data[i];
				messages = messages + "
" + d.description;
				if (d.failed) {
					this.stopProgress();
					return this.handleFailure(d);
				} else if (d.done) {
					this.fireEvent('done', d.payload);
					this.stopProgress();
					if (this.doFoward && d.forwardingURL !== undefined && d.forwardingURL !== null) {
						window.location = d.forwardingURL + "?taskId=" + this.taskId;
					} else {
						var callback = this.maybeDoForward.createDelegate(this, [], true);
						var errorHandler = this.handleFailure.createDelegate(this, [], true);
						TaskCompletionController.checkResult(this.taskId, {
									callback : callback,
									errorHandler : errorHandler
								});
					}
					return;
				}
			}
		} else {
			if (data.done) {
				this.stopProgress();
				return this.handleFailure(data);
			} else if (d.done) {
				this.fireEvent('done', data.payload);
				this.stopProgress();
			}
		}

		if (!document.getElementById("progressTextArea"))
			return;

		if (this.previousMessage != messages && messages.length > 0) {
			this.previousMessage = messages;
			document.getElementById("progressTextArea").innerHTML += messages;
			document.getElementById("progressTextArea").scrollTop = document.getElementById("progressTextArea").scrollHeight;
		} else {
			document.getElementById("progressTextArea").innerHTML += ".";
			document.getElementById("progressTextArea").scrollTop = document.getElementById("progressTextArea").scrollHeight;
		}
	},

	/*
	 * Private Send a cancel notification to the server.
	 */
	cancelJob : function() {
		this.waiting = false;
		document.getElementById("progressTextArea").innerHTML = "Cancelling...";
		var f = this.cancelCallback.createDelegate(this, [], true);
		ProgressStatusService.cancelJob(this.taskId, f);
	},

	/*
	 * Private Check for status from server.
	 */
	refreshProgress : function(callback, errorHandler) {
		// only check for status if we aren't already waiting for a reply.
		if (!this.waiting) {
			ProgressStatusService.getProgressStatus(this.taskId, {
						callback : callback,
						errorHandler : errorHandler
					});
			this.waiting = true;
		}
	},

	/*
	 * Private Callback to handle cancellation @param {Object} data
	 */
	cancelCallback : function(data) {
		this.stopProgress();
		var messageArea = Ext.get("messages");
		if (messageArea) {
			Ext.DomHelper.overwrite("messages", {
						tag : 'img',
						src : '/Gemma/images/icons/ok.png'
					});
			Ext.DomHelper.append("messages", " Job was cancelled.");
		}
		this.fireEvent('cancel');

	},

	/**
	 * Create a progress bar that has no fixed endpoint
	 */
	createIndeterminateProgressBar : function() {
		this.determinate = 0;
		this.bar = this.createIndeterminateBarDetails();
		f = this.cancelJob.createDelegate(this, [], true);
		Ext.get("cancel-button").on('click', f);
	},

	/**
	 * Create a progress bar that has a known endpoint
	 */
	createDeterminateProgressBar : function() {
		this.determinate = 1;
		var div = '
	<input style="float:left;margin:0px;" type="button" id="cancel-button" name="Cancel" value="Cancel job" />

'
		Ext.DomHelper.overwrite("progress-area", div);
		f = this.cancelJob.createDelegate(this, [], true);
		Ext.get("cancel-button").on('click', f);
	},

	createIndeterminateBarDetails : function() {
		var div = '
<input type="textarea" />

<input style="float:left" type="button" id="cancel-button" name="Cancel" value="Cancel job" />
';
		Ext.DomHelper.overwrite("progress-area", div);
	}

});
<|endoftext|>


<commit_before>/**
 * KBase widget to display table of BIOM data
 */
(function($, undefined) {
    $.KBWidget({
            name: 'AbundanceDataPcoa',
            parent: "kbaseAuthenticatedWidget",
            version: '1.0.0',
            token: null,
            options: {
	            id: null,
	            ws: null,
	            x_axis: "1",
	            y_axis: "2"
        },
	    ws_url: window.kbconfig.urls.workspace,
	    loading_image: "static/kbase/images/ajax-loader.gif",

	    init: function(options) {
            this._super(options);
            return this;
        },

        render: function() {
	        var self = this;
	        var pref = this.uuidv4();

	        var container = this.$elem;
	        container.empty();
            if (self.token == null) {
                container.append("
[Error] You're not logged in
");
                return;
            }
            container.append("
  loading data...
");

	        var kbws = new Workspace(self.ws_url, {'token': self.token});
	        kbws.get_objects([{ref: self.options.ws+"/"+self.options.id}], function(data) {
	            container.empty();
		        // parse data
		        if (data.length == 0) {
		            var msg = "[Error] Object "+self.options.id+" does not exist in workspace "+self.options.ws;
		            container.append('

'+msg+'>/p>
');
		        } else {
		            var pcoa = data[0]['data'];
		            var plen = pcoa['data'].length;
                    var x_pos = parseInt(self.options.x_axis, 10) - 1;
                    var y_pos = parseInt(self.options.y_axis, 10) - 1;
                    if ((x_pos < 0) || (x_pos > (plen-1)) || (y_pos < 0) || (y_pos > (plen-1))) {
                        x_pos = 0;
                        y_pos = 1;
                    }
		            // do grouping
		            var groups = {};
		            var x_all = new Array(plen);
		            var y_all = new Array(plen);
		            for (var i = 0; i < plen; i++) {
		                // group is id if no group given
		                var data = {
		                    'id': pcoa['data'][i]['id'],
		                    'x': pcoa['data'][i]['pco'][x_pos],
		                    'y': pcoa['data'][i]['pco'][y_pos]
		                }
		                x_all[i] = pcoa['data'][i]['pco'][x_pos];
		                y_all[i] = pcoa['data'][i]['pco'][y_pos];
		                if (pcoa['data'][i]['group'] == "") {
		                    groups[pcoa['data'][i]['id']] = [ data ];
		                } else {
		                    if (groups.hasOwnProperty(pcoa['data'][i]['group'])) {
		                        groups[pcoa['data'][i]['group']].push(data);
		                    } else {
		                        groups[pcoa['data'][i]['group']] = [ data ];
		                    }
		                }
	                }
	                // build series and points
	                var colors = GooglePalette(groups.length);
	                var plotdata = {
	                    'series': [],
	                    'points': []
	                };
	                var num = 0;
	                for (var group in groups) {
	                    var coords = [];
	                    for (var i = 0; i < groups[group].length; i++) {
	                        coords.push({'x': groups[group][i]['x'], 'y': groups[group][i]['y']});
                        }
                        plotdata['series'].push({'name': group, 'color': colors[num], 'shape': 'circle', 'filled': 1});
                        plotdata['points'].push(coords);
                        num += 1;
	                }
			        // PLOT
			        var x_min = Math.min.apply(null, x_all);
			        var x_max = Math.max.apply(null, x_all);
			        var y_min = Math.min.apply(null, y_all);
			        var y_max = Math.max.apply(null, y_all);
                    var plen = 0;
                    if (window.hasOwnProperty('rendererPlot') && rendererPlot.length) {
                        plen = rendererPlot.length;
                    }
                    container.append("

");
                    var plotTest = standalonePlot.create({index: plen});
                    plotTest.settings.target = document.getElementById("outputPlot"+plen);
                    plotTest.settings.data = plotdata;
                    plotTest.settings.x_title = 'PC'+(x_pos+1).toString();
                    plotTest.settings.y_title = 'PC'+(y_pos+1).toString();
                    plotTest.settings.x_min = x_min - Math.abs((x_max - x_min) * 0.1);
                    plotTest.settings.x_max = x_max + Math.abs((x_max - x_min) * 0.1);
                    plotTest.settings.y_min = y_min - Math.abs((y_max - y_min) * 0.1);
                    plotTest.settings.y_max = y_max + Math.abs((y_max - y_min) * 0.1);
			        plotTest.settings.connected = false;
			        plotTest.settings.show_dots = true;
			        plotTest.settings.show_legend = true;
                    plotTest.render(plen);
		        }
	        }, function(data) {
		        container.empty();
		        var main = $('
');
		        main.append($('
')
		            .css({'padding': '10px 20px'})
		            .text('[Error] '+data.error.message));
		        container.append(main);
	        });
	        return self;
        },

        loggedInCallback: function(event, auth) {
            this.token = auth.token;
            this.render();
            return this;
        },

        loggedOutCallback: function(event, auth) {
            this.token = null;
            this.render();
            return this;
        },

	    uuidv4: function(a,b) {
	        for (b=a=''; a++<36; b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');
	        return b;
	    }
    });
})(jQuery);
<commit_msg>fix broken drop-and-drag pcoa view<commit_after>/**
 * KBase widget to display table of BIOM data
 */
(function($, undefined) {
    $.KBWidget({
            name: 'AbundanceDataPcoa',
            parent: "kbaseAuthenticatedWidget",
            version: '1.0.0',
            token: null,
            options: {
	            id: null,
	            ws: null,
	            x_axis: "1",
	            y_axis: "2"
        },
	    ws_url: window.kbconfig.urls.workspace,
	    loading_image: "static/kbase/images/ajax-loader.gif",

	    init: function(options) {
            this._super(options);
            return this;
        },

        render: function() {
	        var self = this;
	        var pref = this.uuidv4();

	        var container = this.$elem;
	        container.empty();
            if (self.token == null) {
                container.append("
[Error] You're not logged in
");
                return;
            }
            container.append("
  loading data...
");

	        var kbws = new Workspace(self.ws_url, {'token': self.token});
	        kbws.get_objects([{ref: self.options.ws+"/"+self.options.id}], function(data) {
	            container.empty();
		        // parse data
		        if (data.length == 0) {
		            var msg = "[Error] Object "+self.options.id+" does not exist in workspace "+self.options.ws;
		            container.append('

'+msg+'>/p>
');
		        } else {
		            var pcoa = data[0]['data'];
		            var plen = pcoa['data'].length;
                    var x_pos = parseInt(self.options.x_axis, 10) - 1;
                    var y_pos = parseInt(self.options.y_axis, 10) - 1;
                    if (isNaN(x_pos) || isNaN(y_pos) || (x_pos < 0) || (x_pos > (plen-1)) || (y_pos < 0) || (y_pos > (plen-1))) {
                        x_pos = 0;
                        y_pos = 1;
                    }
		            // do grouping
		            var groups = {};
		            var x_all = new Array(plen);
		            var y_all = new Array(plen);
		            for (var i = 0; i < plen; i++) {
		                // group is id if no group given
		                var data = {
		                    'id': pcoa['data'][i]['id'],
		                    'x': pcoa['data'][i]['pco'][x_pos],
		                    'y': pcoa['data'][i]['pco'][y_pos]
		                }
		                x_all[i] = pcoa['data'][i]['pco'][x_pos];
		                y_all[i] = pcoa['data'][i]['pco'][y_pos];
		                if (pcoa['data'][i]['group'] == "") {
		                    groups[pcoa['data'][i]['id']] = [ data ];
		                } else {
		                    if (groups.hasOwnProperty(pcoa['data'][i]['group'])) {
		                        groups[pcoa['data'][i]['group']].push(data);
		                    } else {
		                        groups[pcoa['data'][i]['group']] = [ data ];
		                    }
		                }
	                }
	                // build series and points
	                var colors = GooglePalette(groups.length);
	                var plotdata = {
	                    'series': [],
	                    'points': []
	                };
	                var num = 0;
	                for (var group in groups) {
	                    var coords = [];
	                    for (var i = 0; i < groups[group].length; i++) {
	                        coords.push({'x': groups[group][i]['x'], 'y': groups[group][i]['y']});
                        }
                        plotdata['series'].push({'name': group, 'color': colors[num], 'shape': 'circle', 'filled': 1});
                        plotdata['points'].push(coords);
                        num += 1;
	                }
			        // PLOT
			        var x_min = Math.min.apply(null, x_all);
			        var x_max = Math.max.apply(null, x_all);
			        var y_min = Math.min.apply(null, y_all);
			        var y_max = Math.max.apply(null, y_all);
                    var plen = 0;
                    if (window.hasOwnProperty('rendererPlot') && rendererPlot.length) {
                        plen = rendererPlot.length;
                    }
                    container.append("

");
                    var plotTest = standalonePlot.create({index: plen});
                    plotTest.settings.target = document.getElementById("outputPlot"+plen);
                    plotTest.settings.data = plotdata;
                    plotTest.settings.x_title = 'PC'+(x_pos+1).toString();
                    plotTest.settings.y_title = 'PC'+(y_pos+1).toString();
                    plotTest.settings.x_min = x_min - Math.abs((x_max - x_min) * 0.1);
                    plotTest.settings.x_max = x_max + Math.abs((x_max - x_min) * 0.1);
                    plotTest.settings.y_min = y_min - Math.abs((y_max - y_min) * 0.1);
                    plotTest.settings.y_max = y_max + Math.abs((y_max - y_min) * 0.1);
			        plotTest.settings.connected = false;
			        plotTest.settings.show_dots = true;
			        plotTest.settings.show_legend = true;
                    plotTest.render(plen);
		        }
	        }, function(data) {
		        container.empty();
		        var main = $('
');
		        main.append($('
')
		            .css({'padding': '10px 20px'})
		            .text('[Error] '+data.error.message));
		        container.append(main);
	        });
	        return self;
        },

        loggedInCallback: function(event, auth) {
            this.token = auth.token;
            this.render();
            return this;
        },

        loggedOutCallback: function(event, auth) {
            this.token = null;
            this.render();
            return this;
        },

	    uuidv4: function(a,b) {
	        for (b=a=''; a++<36; b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');
	        return b;
	    }
    });
})(jQuery);
<|endoftext|>


<commit_before>import Base from './base'
import Git from './git'
import Paths from './paths'
import extend from 'extend'
import fs from 'fs'
import path from 'path'
import url from 'url'
import semver from 'semver'
import shelljs from 'shelljs'

const Default = {
  sourceCwd: shelljs.pwd(), // The base directory of the source e.g. the directory of the package.json (not usually necessary to specify, but useful for odd structures and tests)
  cwd: 'dist',        // The directory that contains your built code.
  branch: 'dist',     // The branch to commit to.
  remote: {
    repo: '../',      // The remote repo to push to (URL|RemoteName|FileSystemPath). Common examples include:
                      //   - `git@github.com:alienfast/foo.git` - your main project's remote (gh-pages branch)
                      //   - `../` - the local project repository itself

    // If token && login are provided, the remote.repo will be formatted to include these
    login: undefined,
    token: undefined,
    branch: undefined// The remote branch to push to. Common usage would be for Heroku's master branch requirement.
  },
  tag: {
    name: undefined   // fn or string.  Default will autoresolve from the package.json version if possible.  Pass false to avoid tagging.
  },
  push: true,        // Pushes `branch` to remote. If tag is set, pushes the specified tag as well. false will disable
  commit: {
    auto: true,      // Commits built code to `branch`. A new commit is only created if the built code has changed. false will disable

    // The commit template to use when committing. (special characters must be escaped)
    //  The following tokens are replaced:
    //    - %sourceName%:   the package.json name or the project directory name
    //    - %sourceTag%: the current tag i.e. v1.0.0
    //    - %sourceBranch%: the current branch
    //    - %sourceCommit%: the most recent commit
    template: `Built %sourceName% %sourceTag% from commit %sourceCommit% on branch %sourceBranch%`
  },
  connectCommits: true,// Make sure that every commit on the built code branch matches a commit on the main project branch. If the main project's working directory has uncommitted changes, a commit task will throw an error.
  fetch: {
    shallow: false    // Fetches branch from remote with the flag --depth=1. Which makes a shallow clone with a history truncated to the last revision. Might bring some boost on long-history repositories.
  },
  git: {
    config: {}         // [git config](http://git-scm.com/docs/git-config) settings for the repository when preparing the repository. e.g. `{'user.name': 'John Doe'}`
  },
  force: false     // Pushes branch to remote with the flag --force. This will NOT checkout the remote branch, and will OVERRIDE remote with the repo commits.  Use with caution.
}

const BuildControl = class extends Base {

  constructor(config = {}) {
    super(extend(true, {},
      Default,
      {tag: {name: () => this.autoResolveTagName()}}, // tag package version auto resolver
      config
    ))

    // modify

    // Build remote repo if sensitive information is passed in
    if (this.config.remote.login && this.config.remote.token) {
      let remote = url.parse(this.config.remote.repo)

      this.config.remote.repo = url.format({
        protocol: remote.protocol,
        auth: this.config.remote.login + ':' + this.config.remote.token,
        host: remote.host,
        pathname: remote.pathname
      })

      // configure sensitive information
      this.config.sensitive[`${this.config.remote.login}:${this.config.remote.token}`] = '<credentials>'
      this.config.sensitive[this.config.remote.token] = '<token>'
    }

    // get a fully resolved sourceCwd based on the process cwd (if not an absolute path)
    this.config.sourceCwd = Paths.resolveCwd(shelljs.pwd(), this.config.sourceCwd)
    // get a fully resolved cwd based on the sourceCwd (if not an absolute path)
    this.config.cwd = Paths.resolveCwd(this.config.sourceCwd, this.config.cwd)

    this.sourceGit = new Git({cwd: this.config.sourceCwd, debug: this.config.debug, sensitive: this.config.sensitive})
    this.git = new Git({cwd: this.config.cwd, debug: this.config.debug, sensitive: this.config.sensitive})
    this.package = this.readPackage()
  }

  /**
   * Convenience to resolve from a fn or string.  If tag already exists in a remote, it will return false (don't forget to bump your version in the package.json!)
   */
  tagName() {
    if (this._tagName !== undefined) {
      return this._tagName
    }

    if (this.config.tag.name === false) {
      this._tagName = false
    }
    else if (this.config.tag.name === undefined) {
      this._tagName = false
    }
    else {
      let name = null
      if (typeof this.config.tag.name === 'function') {
        name = this.config.tag.name()
      }
      else {
        name = this.config.tag.name
      }

      // If the tag exists, skip tagging
      if (this.tagExists(name)) {
        this.log(`The tag "${name}" already exists on ${this.config.remote.name}.`)
        name = false
      }

      this._tagName = name
    }

    return this._tagName
  }

  tagExists(name) {
    if (this.git.tagExists(name, this.config.remote.name)) {
      return true
    }
    else {
      return false
    }
  }

  resolveBranch() {
    return (this.config.remote.branch || this.config.branch)
  }

  /**
   * Resolver plugged into options as tag: {name: ()} that can be overridden by a string or other fn
   * @returns {*}
   */
  autoResolveTagName() {
    if (this.package && this.package.version) {
      return `v${this.package.version}`
    }
    else {
      return false
    }
  }

  readPackage() {
    let file = path.join(this.config.sourceCwd, 'package.json')
    if (shelljs.test('-f', file, {silent: true})) {
      this.debug(`Found package.json at ${file}`)
      return JSON.parse(fs.readFileSync(file, 'utf8'))
    }
    else {
      this.debug(`package.json not found at ${file}`)
      return null
    }
  }

  /**
   *
   */
  checkRequirements() {
    // Check if git version meets requirements
    let version = this.git.version()
    if (!version || semver.lt(version, '1.8.0')) {
      throw(`Current Git version is ${version}. This plugin requires Git >= 1.8.0.`)
    }

    // Check that build directory exists
    if (!fs.existsSync(this.config.cwd)) {
      throw(`Build directory ${this.config.cwd} doesn't exist. Nothing to version.`)
    }

    // Check that build directory contains files
    if (fs.readdirSync(this.config.cwd).length === 0) {
      throw(`Build directory ${this.config.cwd} is empty. Nothing to version.`)
    }

    // If connectCommits is true check that the main project's working directory is clean
    if (this.config.connectCommits) {
      let diff = this.git.diff()
      if (diff !== '') {
        this.notifyError('There are uncommitted changes in your working directory. Please commit changes to the main project before you commit to the built code.')
      }
      else {
        this.debug(`No diffs found.`)
      }
    }

    if (this.config.fetch.shallow && semver.lt(version, '1.9.0')) {
      this.notifyError(`Option "fetch.shallow" is supported on Git >= 1.9.0 and your version is ${version}.`)
    }
  }

  /**
   * Attempt to track a branch from origin. It may fail on times that the branch is already tracking another remote. There is no problem when that happens, nor does it have any affect
   */
  verifySourceBranchIsTracked() {
    this.sourceGit.track(this.config.branch)
  }

  /**
   * Initialize git repo if one doesn't exist
   */
  ensureGitInit() {
    let repo = path.join(this.config.cwd, '.git')
    if (!fs.existsSync(repo)) {
      this.log(`Creating git repository in ${this.config.cwd}.`)
      this.git.init()
    }
  }

  /**
   * Initialize the git config
   */
  configureGit() {

    this.debugDump(`this.config.git.config`, this.config.git.config)
    for (let key of Object.keys(this.config.git.config)) {
      this.git.configure(key, this.config.git.config[key])
    }
  }

  /**
   * Create a named remote if one doesn't exist
   */
  ensureRemote() {
    let remoteUrlRegex = new RegExp('[\/\\:]')
    if (remoteUrlRegex.test(this.config.remote.repo)) {
      this.config.remote.name = this.git.hash('remote', this.config.remote.repo)
      if (!this.git.remote().includes(this.config.remote.name)) {
        this.log(`Creating remote ${this.config.remote.name}`)
        this.git.remoteAdd(this.config.remote.name, this.config.remote.repo)
      }
    }
  }

  /**
   * Check if local branch can safely merge upstream (requires fetched refs)
   * @returns {boolean}
   */
  shouldUpdate() {
    // WARNING: With force, we're not even going to attempt to check out, We're just going to push the repo and override EVERYTHING in the remote
    if (this.config.force === true) return false

    let status = this.git.status()
    if (status) {
      let ahead = status.includes('ahead')
      let behind = status.includes('behind')

      if (ahead && behind) {
        throw('The remote and local branches have diverged please\n' +
        'resolve manually. Deleting the local **built code**\n' +
        '.git directory will usually fix things up.')
      }
      else if (ahead) {
        return false
      }
      else if (behind) {
        return true
      }
    }
  }

  /**
   * Fetch remote refs to a specific branch, equivalent to a pull without checkout
   * @param dest
   */
  fetch(dest) {
    let branch = this.resolveBranch() + (dest ? ':' + this.config.branch : '');
    this.log(`Fetching "${this.config.branch}" ${(this.config.fetch.shallow ? 'files' : 'history')} from ${this.config.remote.repo}.`);
    this.git.fetch(this.config.remote.name, branch, this.config.fetch.shallow)
  }

  /**
   * Set branch to track remote
   */
  ensureLocalBranchTracksRemote() {
    let remoteBranch = this.config.remote.branch || this.config.branch;
    if (this.git.configBranchRemote(this.config.branch) !== this.config.remote.name) {
      this.git.branchRemote(this.config.branch, this.config.remote.name, remoteBranch)
    }
  }

  sourceName() {
    if (this._sourceName) {
      return this._sourceName
    }
    else {
      if (this.package != null) {
        this._sourceName = this.package.name
      }
      else {
        this._sourceName = this.config.sourceCwd.split('/').pop()
      }

      return this._sourceName
    }
  }

  sourceCommit() {
    if (this._sourceCommit) {
      return this._sourceCommit
    }
    return this._sourceCommit = this.sourceGit.sourceCommit()
  }

  sourceCommitFull() {
    if (this._sourceCommitFull) {
      return this._sourceCommitFull
    }
    return this._sourceCommitFull = this.sourceGit.sourceCommitFull()
  }

  sourceCommitLink() {
    return `[\`%sourceCommit%\`](../../commit/%sourceCommitFull%)`
  }

  sourceBranch() {
    if (this._sourceBranch) {
      return this._sourceBranch
    }
    return this._sourceBranch = this.sourceGit.sourceBranch()
  }

  sourceTag() {
    if (this._sourceTag) {
      return this._sourceTag
    }

    let name = this.tagName()
    if (name) {
      this._sourceTag = name
    }
    else {
      this._sourceTag = ''
    }

    return this._sourceTag
  }

  sourceTagLink() {
    if (this.tagName()) {
      return `[\`%sourceTag%\`](../../releases/tag/%sourceTag%)`
    }
    else {
      return ''
    }
  }

  interpolate(template) {
    return template
      .replace(/%sourceName%/g, this.sourceName())
      .replace(/%sourceTag%/g, this.sourceTag())
      .replace(/%sourceTagLink%/g, this.sourceTagLink())
      .replace(/%sourceCommit%/g, this.sourceCommit())
      .replace(/%sourceCommitFull%/g, this.sourceCommitFull())
      .replace(/%sourceCommitLink%/g, this.sourceCommitLink())
      .replace(/%sourceBranch%/g, this.sourceBranch())
  }

  /**
   * Stage and commit to a branch
   */
  commit() {

    if (!this.config.commit.auto) {
      return
    }

    let message = this.interpolate(this.config.commit.template)

    // If there are no changes, skip commit
    if (!this.git.status()) {
      this.log('No changes to your branch. Skipping commit.')
      return
    }

    this.log(`Committing changes to "${this.config.branch}".`)
    this.git.add()
    this.git.commit(message)
  }

  /**
   * Tag local branch
   */
  tag() {
    let tagName = this.tagName()
    if (!tagName) {
      return
    }

    // #tagName does this check, but user can pass in their own tag resolution function so we need to ensure we do it here.
    if (this.tagExists(tagName)) {
      this.log(`The tag "${tagName}" already exists on ${this.config.remote.name}. Skipping tagging.`)
      return
    }

    this.log(`Tagging the local repository with ${tagName}`)
    this.git.tag(tagName)
  }

  /**
   * Push branch to remote
   */
  push() {
    if (!this.config.push) {
      return
    }

    let branch = this.config.branch

    if (this.config.remote.branch) {
      branch += `:${this.config.remote.branch}`
    }

    this.git.push(this.config.remote.name, branch, this.config.force)
    if (this.tagName()) {
      this.git.pushTag(this.config.remote.name, this.tagName())
    }
  }

  localBranchExists() {
    return this.git.branchExists(this.config.branch)
  }

  remoteBranchExists() {
    return this.git.branchRemoteExists(this.resolveBranch(), this.config.remote.name)
  }

  run() {
    // Run task
    this.log(this.interpolate(`Starting %sourceName% for commit %sourceCommit% on branch %sourceBranch% using directory ${this.config.cwd}...`))

    // Prepare
    this.checkRequirements()
    if (this.config.remote.repo === '../') this.verifySourceBranchIsTracked()

    // Set up repository
    this.ensureGitInit()
    this.configureGit()
    this.ensureRemote()

    // Set up local branch
    let localBranchExists = this.localBranchExists()
    let remoteBranchExists = this.remoteBranchExists()

    if (remoteBranchExists) {
      this.fetch()
    }

    if (remoteBranchExists && localBranchExists) {
      // Make sure local is tracking remote
      this.ensureLocalBranchTracksRemote()

      // Update local branch history if necessary
      if (this.shouldUpdate()) {
        this.fetch(true)
      }
    }
    else if (remoteBranchExists && !localBranchExists) { //// TEST THIS ONE
      // Create local branch that tracks remote
      this.git.track(this.config.branch, this.config.remote.name, this.resolveBranch())
    }
    else if (!remoteBranchExists && !localBranchExists) {
      // Create local branch
      this.log(`Creating branch "${this.config.branch}".`)
      this.git.checkout(this.config.branch)
    }

    // Perform actions
    this.git.symbolicRefHead(this.config.branch)
    this.git.reset()

    this.commit()
    this.tag()
    this.push()
  }
}

export default BuildControl
<commit_msg>fixed some tagName related problems<commit_after>import Base from './base'
import Git from './git'
import Paths from './paths'
import extend from 'extend'
import fs from 'fs'
import path from 'path'
import url from 'url'
import semver from 'semver'
import shelljs from 'shelljs'

const Default = {
  sourceCwd: shelljs.pwd(), // The base directory of the source e.g. the directory of the package.json (not usually necessary to specify, but useful for odd structures and tests)
  cwd: 'dist',        // The directory that contains your built code.
  branch: 'dist',     // The branch to commit to.
  remote: {
    repo: '../',      // The remote repo to push to (URL|RemoteName|FileSystemPath). Common examples include:
                      //   - `git@github.com:alienfast/foo.git` - your main project's remote (gh-pages branch)
                      //   - `../` - the local project repository itself

    // If token && login are provided, the remote.repo will be formatted to include these
    login: undefined,
    token: undefined,
    branch: undefined// The remote branch to push to. Common usage would be for Heroku's master branch requirement.
  },
  tag: {
    name: undefined   // fn or string.  Default will autoresolve from the package.json version if possible.  Pass false to avoid tagging.
  },
  push: true,        // Pushes `branch` to remote. If tag is set, pushes the specified tag as well. false will disable
  commit: {
    auto: true,      // Commits built code to `branch`. A new commit is only created if the built code has changed. false will disable

    // The commit template to use when committing. (special characters must be escaped)
    //  The following tokens are replaced:
    //    - %sourceName%:   the package.json name or the project directory name
    //    - %sourceTag%: the current tag i.e. v1.0.0
    //    - %sourceBranch%: the current branch
    //    - %sourceCommit%: the most recent commit
    template: `Built %sourceName% %sourceTag% from commit %sourceCommit% on branch %sourceBranch%`
  },
  connectCommits: true,// Make sure that every commit on the built code branch matches a commit on the main project branch. If the main project's working directory has uncommitted changes, a commit task will throw an error.
  fetch: {
    shallow: false    // Fetches branch from remote with the flag --depth=1. Which makes a shallow clone with a history truncated to the last revision. Might bring some boost on long-history repositories.
  },
  git: {
    config: {}         // [git config](http://git-scm.com/docs/git-config) settings for the repository when preparing the repository. e.g. `{'user.name': 'John Doe'}`
  },
  force: false     // Pushes branch to remote with the flag --force. This will NOT checkout the remote branch, and will OVERRIDE remote with the repo commits.  Use with caution.
}

const BuildControl = class extends Base {

  constructor(config = {}) {
    super(extend(true, {},
      Default,
      {tag: {name: () => this.autoResolveTagName()}}, // tag package version auto resolver
      config
    ))

    // modify

    // Build remote repo if sensitive information is passed in
    if (this.config.remote.login && this.config.remote.token) {
      let remote = url.parse(this.config.remote.repo)

      this.config.remote.repo = url.format({
        protocol: remote.protocol,
        auth: this.config.remote.login + ':' + this.config.remote.token,
        host: remote.host,
        pathname: remote.pathname
      })

      // configure sensitive information
      this.config.sensitive[`${this.config.remote.login}:${this.config.remote.token}`] = '<credentials>'
      this.config.sensitive[this.config.remote.token] = '<token>'
    }

    // get a fully resolved sourceCwd based on the process cwd (if not an absolute path)
    this.config.sourceCwd = Paths.resolveCwd(shelljs.pwd(), this.config.sourceCwd)
    // get a fully resolved cwd based on the sourceCwd (if not an absolute path)
    this.config.cwd = Paths.resolveCwd(this.config.sourceCwd, this.config.cwd)

    this.sourceGit = new Git({cwd: this.config.sourceCwd, debug: this.config.debug, sensitive: this.config.sensitive})
    this.git = new Git({cwd: this.config.cwd, debug: this.config.debug, sensitive: this.config.sensitive})
    this.package = this.readPackage()
  }

  resolveBranch() {
    return (this.config.remote.branch || this.config.branch)
  }

  readPackage() {
    let file = path.join(this.config.sourceCwd, 'package.json')
    if (shelljs.test('-f', file, {silent: true})) {
      this.debug(`Found package.json at ${file}`)
      return JSON.parse(fs.readFileSync(file, 'utf8'))
    }
    else {
      this.debug(`package.json not found at ${file}`)
      return null
    }
  }

  /**
   *
   */
  checkRequirements() {
    // Check if git version meets requirements
    let version = this.git.version()
    if (!version || semver.lt(version, '1.8.0')) {
      throw(`Current Git version is ${version}. This plugin requires Git >= 1.8.0.`)
    }

    // Check that build directory exists
    if (!fs.existsSync(this.config.cwd)) {
      throw(`Build directory ${this.config.cwd} doesn't exist. Nothing to version.`)
    }

    // Check that build directory contains files
    if (fs.readdirSync(this.config.cwd).length === 0) {
      throw(`Build directory ${this.config.cwd} is empty. Nothing to version.`)
    }

    // If connectCommits is true check that the main project's working directory is clean
    if (this.config.connectCommits) {
      let diff = this.git.diff()
      if (diff !== '') {
        this.notifyError('There are uncommitted changes in your working directory. Please commit changes to the main project before you commit to the built code.')
      }
      else {
        this.debug(`No diffs found.`)
      }
    }

    if (this.config.fetch.shallow && semver.lt(version, '1.9.0')) {
      this.notifyError(`Option "fetch.shallow" is supported on Git >= 1.9.0 and your version is ${version}.`)
    }
  }

  /**
   * Attempt to track a branch from origin. It may fail on times that the branch is already tracking another remote. There is no problem when that happens, nor does it have any affect
   */
  verifySourceBranchIsTracked() {
    this.sourceGit.track(this.config.branch)
  }

  /**
   * Initialize git repo if one doesn't exist
   */
  ensureGitInit() {
    let repo = path.join(this.config.cwd, '.git')
    if (!fs.existsSync(repo)) {
      this.log(`Creating git repository in ${this.config.cwd}.`)
      this.git.init()
    }
  }

  /**
   * Initialize the git config
   */
  configureGit() {

    this.debugDump(`this.config.git.config`, this.config.git.config)
    for (let key of Object.keys(this.config.git.config)) {
      this.git.configure(key, this.config.git.config[key])
    }
  }

  /**
   * Create a named remote if one doesn't exist
   */
  ensureRemote() {
    let remoteUrlRegex = new RegExp('[\/\\:]')
    if (remoteUrlRegex.test(this.config.remote.repo)) {
      this.config.remote.name = this.git.hash('remote', this.config.remote.repo)
      if (!this.git.remote().includes(this.config.remote.name)) {
        this.log(`Creating remote ${this.config.remote.name}`)
        this.git.remoteAdd(this.config.remote.name, this.config.remote.repo)
      }
    }
  }

  /**
   * Check if local branch can safely merge upstream (requires fetched refs)
   * @returns {boolean}
   */
  shouldUpdate() {
    // WARNING: With force, we're not even going to attempt to check out, We're just going to push the repo and override EVERYTHING in the remote
    if (this.config.force === true) return false

    let status = this.git.status()
    if (status) {
      let ahead = status.includes('ahead')
      let behind = status.includes('behind')

      if (ahead && behind) {
        throw('The remote and local branches have diverged please\n' +
        'resolve manually. Deleting the local **built code**\n' +
        '.git directory will usually fix things up.')
      }
      else if (ahead) {
        return false
      }
      else if (behind) {
        return true
      }
    }
  }

  /**
   * Fetch remote refs to a specific branch, equivalent to a pull without checkout
   * @param dest
   */
  fetch(dest) {
    let branch = this.resolveBranch() + (dest ? ':' + this.config.branch : '');
    this.log(`Fetching "${this.config.branch}" ${(this.config.fetch.shallow ? 'files' : 'history')} from ${this.config.remote.repo}.`);
    this.git.fetch(this.config.remote.name, branch, this.config.fetch.shallow)
  }

  /**
   * Set branch to track remote
   */
  ensureLocalBranchTracksRemote() {
    let remoteBranch = this.config.remote.branch || this.config.branch;
    if (this.git.configBranchRemote(this.config.branch) !== this.config.remote.name) {
      this.git.branchRemote(this.config.branch, this.config.remote.name, remoteBranch)
    }
  }

  sourceName() {
    if (this._sourceName) {
      return this._sourceName
    }
    else {
      if (this.package != null) {
        this._sourceName = this.package.name
      }
      else {
        this._sourceName = this.config.sourceCwd.split('/').pop()
      }

      return this._sourceName
    }
  }

  sourceCommit() {
    if (this._sourceCommit) {
      return this._sourceCommit
    }
    return this._sourceCommit = this.sourceGit.sourceCommit()
  }

  sourceCommitFull() {
    if (this._sourceCommitFull) {
      return this._sourceCommitFull
    }
    return this._sourceCommitFull = this.sourceGit.sourceCommitFull()
  }

  sourceCommitLink() {
    return `[\`%sourceCommit%\`](../../commit/%sourceCommitFull%)`
  }

  sourceBranch() {
    if (this._sourceBranch) {
      return this._sourceBranch
    }
    return this._sourceBranch = this.sourceGit.sourceBranch()
  }

  sourceTag() {
    if (this._sourceTag) {
      return this._sourceTag
    }

    let name = this.tagName()
    if (name) {
      this._sourceTag = name
    }
    else {
      this._sourceTag = ''
    }

    return this._sourceTag
  }

  sourceTagLink() {
    if (this.tagName()) {
      return `[\`%sourceTag%\`](../../releases/tag/%sourceTag%)`
    }
    else {
      return ''
    }
  }

  interpolate(template) {
    return template
      .replace(/%sourceName%/g, this.sourceName())
      .replace(/%sourceTag%/g, this.sourceTag())
      .replace(/%sourceTagLink%/g, this.sourceTagLink())
      .replace(/%sourceCommit%/g, this.sourceCommit())
      .replace(/%sourceCommitFull%/g, this.sourceCommitFull())
      .replace(/%sourceCommitLink%/g, this.sourceCommitLink())
      .replace(/%sourceBranch%/g, this.sourceBranch())
  }

  /**
   * Stage and commit to a branch
   */
  commit() {

    if (!this.config.commit.auto) {
      return
    }

    let message = this.interpolate(this.config.commit.template)

    // If there are no changes, skip commit
    if (!this.git.status()) {
      this.log('No changes to your branch. Skipping commit.')
      return
    }

    this.log(`Committing changes to "${this.config.branch}".`)
    this.git.add()
    this.git.commit(message)
  }

  /**
   * Tag local branch
   */
  tag() {
    let tagName = this.tagName()
    if (!tagName) {
      return
    }

    this.log(`Tagging the local repository with ${tagName}`)
    this.git.tag(tagName)
  }

  /**
   * Convenience to resolve from a fn or string.  If tag already exists in a remote, it will return false (don't forget to bump your version in the package.json!)
   */
  tagName() {
    if (this._tagName !== undefined) {
      return this._tagName
    }

    if (this.config.tag.name === false) {
      this._tagName = false
    }
    else if (this.config.tag.name === undefined) {
      this._tagName = false
    }
    else {
      let name = null
      if (typeof this.config.tag.name === 'function') {
        name = this.config.tag.name()
      }
      else {
        name = this.config.tag.name
      }

      // If the tag exists, skip tagging
      if (name && this.tagExists(name)) {
        this.log(`WARNING: The tag "${name}" already exists on ${this.config.remote.name}, skipping tagging.`)
        name = false
      }

      this._tagName = name
    }

    return this._tagName
  }

  /**
   * Resolver plugged into options as tag: {name: ()} that can be overridden by a string or other fn
   * @returns {*}
   */
  autoResolveTagName() {
    if (this.package && this.package.version) {
      return `v${this.package.version}`
    }
    else {
      return false
    }
  }

  tagExists(name) {
    if (this.git.tagExists(name, this.config.remote.name)) {
      return true
    }
    else {
      return false
    }
  }

  /**
   * Push branch to remote
   */
  push() {
    if (!this.config.push) {
      return
    }

    let branch = this.config.branch

    if (this.config.remote.branch) {
      branch += `:${this.config.remote.branch}`
    }

    this.git.push(this.config.remote.name, branch, this.config.force)
    if (this.tagName()) {
      this.git.pushTag(this.config.remote.name, this.tagName())
    }
  }

  localBranchExists() {
    return this.git.branchExists(this.config.branch)
  }

  remoteBranchExists() {
    return this.git.branchRemoteExists(this.resolveBranch(), this.config.remote.name)
  }

  run() {
    // Run task
    this.log(this.interpolate(`Starting %sourceName% for commit %sourceCommit% on branch %sourceBranch% using directory ${this.config.cwd}...`))

    // Prepare
    this.checkRequirements()
    if (this.config.remote.repo === '../') this.verifySourceBranchIsTracked()

    // Set up repository
    this.ensureGitInit()
    this.configureGit()
    this.ensureRemote()

    // Set up local branch
    let localBranchExists = this.localBranchExists()
    let remoteBranchExists = this.remoteBranchExists()

    if (remoteBranchExists) {
      this.fetch()
    }

    if (remoteBranchExists && localBranchExists) {
      // Make sure local is tracking remote
      this.ensureLocalBranchTracksRemote()

      // Update local branch history if necessary
      if (this.shouldUpdate()) {
        this.fetch(true)
      }
    }
    else if (remoteBranchExists && !localBranchExists) { //// TEST THIS ONE
      // Create local branch that tracks remote
      this.git.track(this.config.branch, this.config.remote.name, this.resolveBranch())
    }
    else if (!remoteBranchExists && !localBranchExists) {
      // Create local branch
      this.log(`Creating branch "${this.config.branch}".`)
      this.git.checkout(this.config.branch)
    }

    // Perform actions
    this.git.symbolicRefHead(this.config.branch)
    this.git.reset()

    this.commit()
    this.tag()
    this.push()
  }
}

export default BuildControl
<|endoftext|>


<commit_before>/**
 * ownCloud - core
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Bernhard Posselt <dev@bernhard-posselt.com>
 * @copyright Bernhard Posselt 2014
 */

(function (document, $, exports) {

	'use strict';

	var dynamicSlideToggleEnabled = false;

	exports.Apps = {
		enableDynamicSlideToggle: function () {
			dynamicSlideToggleEnabled = true;
		}
	};

	/**
	 * Shows the #app-sidebar and add .with-app-sidebar to subsequent siblings
	 *
	 * @param {Object} [$el] sidebar element to show, defaults to $('#app-sidebar')
	 */
	exports.Apps.showAppSidebar = function($el) {
		var $appSidebar = $el || $('#app-sidebar');
		$appSidebar.removeClass('disappear');
		$('#app-content').addClass('with-app-sidebar').trigger(new $.Event('appresized'));

	};

	/**
	 * Shows the #app-sidebar and removes .with-app-sidebar from subsequent
	 * siblings
	 *
	 * @param {Object} [$el] sidebar element to hide, defaults to $('#app-sidebar')
	 */
	exports.Apps.hideAppSidebar = function($el) {
		var $appSidebar = $el || $('#app-sidebar');
		$appSidebar.addClass('disappear');
		$('#app-content').removeClass('with-app-sidebar').trigger(new $.Event('appresized'));
	};

	/**
	 * Provides a way to slide down a target area through a button and slide it
	 * up if the user clicks somewhere else. Used for the news app settings and
	 * add new field.
	 *
	 * Usage:
	 * <button data-apps-slide-toggle=".slide-area">slide</button>
	 *
I'm sliding up

	 */
	var registerAppsSlideToggle = function () {
		var buttons = $('[data-apps-slide-toggle]');

		$(document).click(function (event) {

			if (dynamicSlideToggleEnabled) {
				buttons = $('[data-apps-slide-toggle]');
			}

			buttons.each(function (index, button) {

				var areaSelector = $(button).data('apps-slide-toggle');
				var area = $(areaSelector);

				function hideArea() {
					area.slideUp(OC.menuSpeed*4, function() {
						area.trigger(new $.Event('hide'));
					});
				}
				function showArea() {
					area.slideDown(OC.menuSpeed*4, function() {
						area.trigger(new $.Event('show'));
					});
				}

				// do nothing if the area is animated
				if (!area.is(':animated')) {

					// button toggles the area
					if ($(button).is($(event.target).closest('[data-apps-slide-toggle]'))) {
						if (area.is(':visible')) {
							hideArea();
						} else {
							showArea();
						}

					// all other areas that have not been clicked but are open
					// should be slid up
					} else {
						var closest = $(event.target).closest(areaSelector);
						if (area.is(':visible') && closest[0] !== area[0]) {
							hideArea();
						}
					}
				}
			});

		});
	};

	$(document).ready(function () {
		registerAppsSlideToggle();
	});

}(document, jQuery, OC));
<commit_msg>slight animation for the sidebar for better feedback what happens<commit_after>/**
 * ownCloud - core
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Bernhard Posselt <dev@bernhard-posselt.com>
 * @copyright Bernhard Posselt 2014
 */

(function (document, $, exports) {

	'use strict';

	var dynamicSlideToggleEnabled = false;

	exports.Apps = {
		enableDynamicSlideToggle: function () {
			dynamicSlideToggleEnabled = true;
		}
	};

	/**
	 * Shows the #app-sidebar and add .with-app-sidebar to subsequent siblings
	 *
	 * @param {Object} [$el] sidebar element to show, defaults to $('#app-sidebar')
	 */
	exports.Apps.showAppSidebar = function($el) {
		var $appSidebar = $el || $('#app-sidebar');
		$appSidebar.removeClass('disappear')
			.show('slide', { direction: 'right' }, 200);
		$('#app-content').addClass('with-app-sidebar').trigger(new $.Event('appresized'));
	};

	/**
	 * Shows the #app-sidebar and removes .with-app-sidebar from subsequent
	 * siblings
	 *
	 * @param {Object} [$el] sidebar element to hide, defaults to $('#app-sidebar')
	 */
	exports.Apps.hideAppSidebar = function($el) {
		var $appSidebar = $el || $('#app-sidebar');
		$appSidebar.hide('slide', { direction: 'right' }, 100,
			function() {
				$appSidebar.addClass('disappear');
			});
		$('#app-content').removeClass('with-app-sidebar').trigger(new $.Event('appresized'));
	};

	/**
	 * Provides a way to slide down a target area through a button and slide it
	 * up if the user clicks somewhere else. Used for the news app settings and
	 * add new field.
	 *
	 * Usage:
	 * <button data-apps-slide-toggle=".slide-area">slide</button>
	 *
I'm sliding up

	 */
	var registerAppsSlideToggle = function () {
		var buttons = $('[data-apps-slide-toggle]');

		$(document).click(function (event) {

			if (dynamicSlideToggleEnabled) {
				buttons = $('[data-apps-slide-toggle]');
			}

			buttons.each(function (index, button) {

				var areaSelector = $(button).data('apps-slide-toggle');
				var area = $(areaSelector);

				function hideArea() {
					area.slideUp(OC.menuSpeed*4, function() {
						area.trigger(new $.Event('hide'));
					});
				}
				function showArea() {
					area.slideDown(OC.menuSpeed*4, function() {
						area.trigger(new $.Event('show'));
					});
				}

				// do nothing if the area is animated
				if (!area.is(':animated')) {

					// button toggles the area
					if ($(button).is($(event.target).closest('[data-apps-slide-toggle]'))) {
						if (area.is(':visible')) {
							hideArea();
						} else {
							showArea();
						}

					// all other areas that have not been clicked but are open
					// should be slid up
					} else {
						var closest = $(event.target).closest(areaSelector);
						if (area.is(':visible') && closest[0] !== area[0]) {
							hideArea();
						}
					}
				}
			});

		});
	};

	$(document).ready(function () {
		registerAppsSlideToggle();
	});

}(document, jQuery, OC));
<|endoftext|>


<commit_before>var bunyan = require('bunyan');
var logger;
if (bunyan) {
    logger = bunyan.createLogger({
        name: engine.repo ?  engine.repo.split('/').slice(-2, -1) : 'client',
        streams: [
            {
              level: 'info',
              stream: process.stdout
            },
            {
              level: 'debug',
              stream: process.stdout
            },
            {
              level: 'error',
              stream: process.stdout
            }
        ],
        serializers: bunyan.stdSerializers
    });
}

// TODO
module.exports = function (level, data, message, callback) {

    if (arguments.length < 2) {
        return;
    }

    // esure callback
    callback = [].slice.apply(arguments).pop();
    if (typeof callback !== 'function') {
        callback = function () {};
    }

    if (typeof data === 'string') {
        message = data;
        data = {};
    }

    if (typeof message !== 'string' && typeof message !== 'number') {
        message = data.message || data.msg || '';
    }

    // server logs
    switch (level) {
      case 'F':
        level = 'fatal';
        break;
      case 'E':
        level = 'error';
        break;
      case 'W':
        level = 'warn';
        break;
      case 'I':
        level = 'info';
        break;
      case 'D':
        level = 'debug';
        break;
      case 'T':
        level = 'trace';
        break;
    }

    // client console logs
    if (engine.client) {

        if (message) {
            data.msg = message;
        }

        data.level = level;

        console.log(data);

        return callback();
    }

    // create a child logger for every instance
    if (logger && !this._log) {
        this._log = logger.child({
            module: this._module || 'engine',
            instance: this._name || 'engine'
        });
    }

    if (!this._log[level]) {
        return callback();
    }

    this._log[level](data, message);

    callback();
};
<commit_msg>define log streams<commit_after>var bunyan = require('bunyan');
var logger;
if (bunyan) {
    logger = bunyan.createLogger({
        name: engine.repo ?  engine.repo.split('/').slice(-2, -1) : 'client',

        // TODO make log streams configurable with CLI arguments
        streams: [
            {
              level: 'fatal',
              stream: process.stderr
            },
            {
              level: 'error',
              stream: process.stderr
            },
            {
              level: 'warn',
              stream: process.stderr
            },
            {
              level: 'info',
              stream: process.stdout
            },
            {
              level: 'debug',
              stream: process.stdout
            },
            {
              level: 'trace',
              stream: process.stdout
            }
        ],
        serializers: bunyan.stdSerializers
    });
}

module.exports = function (level, data, message, callback) {

    if (arguments.length < 2) {
        return;
    }

    // esure callback
    callback = [].slice.apply(arguments).pop();
    if (typeof callback !== 'function') {
        callback = function () {};
    }

    if (typeof data === 'string') {
        message = data;
        data = {};
    }

    if (typeof message !== 'string' && typeof message !== 'number') {
        message = data.message || data.msg || '';
    }

    // server logs
    switch (level) {
      case 'F':
        level = 'fatal';
        break;
      case 'E':
        level = 'error';
        break;
      case 'W':
        level = 'warn';
        break;
      case 'I':
        level = 'info';
        break;
      case 'D':
        level = 'debug';
        break;
      case 'T':
        level = 'trace';
        break;
    }

    // client console logs
    if (engine.client) {

        if (message) {
            data.msg = message;
        }

        data.level = level;

        console.log(data);

        return callback();
    }

    // create a child logger for every instance
    if (logger && !this._log) {
        this._log = logger.child({
            module: this._module || 'engine',
            instance: this._name || 'engine'
        });
    }

    if (!this._log[level]) {
        return callback();
    }

    this._log[level](data, message);

    callback();
};
<|endoftext|>