<commit_before>$(function() {

        //~~ Initialize view models
        var loginStateViewModel = new LoginStateViewModel();
        var usersViewModel = new UsersViewModel(loginStateViewModel);
        var settingsViewModel = new SettingsViewModel(loginStateViewModel, usersViewModel);
        var connectionViewModel = new ConnectionViewModel(loginStateViewModel, settingsViewModel);
        var printerStateViewModel = new PrinterStateViewModel(loginStateViewModel);
        var appearanceViewModel = new AppearanceViewModel(settingsViewModel);
        var temperatureViewModel = new TemperatureViewModel(loginStateViewModel, settingsViewModel);
        var controlViewModel = new ControlViewModel(loginStateViewModel, settingsViewModel);
        var terminalViewModel = new TerminalViewModel(loginStateViewModel);
        var gcodeFilesViewModel = new GcodeFilesViewModel(printerStateViewModel, loginStateViewModel);
        var timelapseViewModel = new TimelapseViewModel(loginStateViewModel);
        var gcodeViewModel = new GcodeViewModel(loginStateViewModel);
        var navigationViewModel = new NavigationViewModel(loginStateViewModel, appearanceViewModel, settingsViewModel, usersViewModel);

        var dataUpdater = new DataUpdater(
            loginStateViewModel,
            connectionViewModel,
            printerStateViewModel,
            temperatureViewModel,
            controlViewModel,
            terminalViewModel,
            gcodeFilesViewModel,
            timelapseViewModel,
            gcodeViewModel
        );

        // work around a stupid iOS6 bug where ajax requests get cached and only work once, as described at
        // http://stackoverflow.com/questions/12506897/is-safari-on-ios-6-caching-ajax-results
        $.ajaxSetup({
            type: 'POST',
            headers: { "cache-control": "no-cache" }
        });

        //~~ Show settings - to ensure centered
        $('#navbar_show_settings').click(function() {
            $('#settings_dialog').modal()
                 .css({
                     width: 'auto',
                     'margin-left': function() { return -($(this).width() /2); }
                  });
            return false;
        });

        //~~ Temperature

        $('#tabs a[data-toggle="tab"]').on('shown', function (e) {
            temperatureViewModel.updatePlot();
            terminalViewModel.updateOutput();
        });

        //~~ Gcode upload

        function gcode_upload_done(e, data) {
            gcodeFilesViewModel.fromResponse(data.result);
            $("#gcode_upload_progress .bar").css("width", "0%");
            $("#gcode_upload_progress").removeClass("progress-striped").removeClass("active");
            $("#gcode_upload_progress .bar").text("");
        }

        function gcode_upload_progress(e, data) {
            var progress = parseInt(data.loaded / data.total * 100, 10);
            $("#gcode_upload_progress .bar").css("width", progress + "%");
            $("#gcode_upload_progress .bar").text("Uploading ...");
            if (progress >= 100) {
                $("#gcode_upload_progress").addClass("progress-striped").addClass("active");
                $("#gcode_upload_progress .bar").text("Saving ...");
            }
        }

        var localTarget;
        if (CONFIG_SD_SUPPORT) {
            localTarget = $("#drop_locally");
        } else {
            localTarget = $("#drop");
        }

        $("#gcode_upload").fileupload({
            dataType: "json",
            dropZone: localTarget,
            formData: {target: "local"},
            done: gcode_upload_done,
            progressall: gcode_upload_progress
        });

        if (CONFIG_SD_SUPPORT) {
            $("#gcode_upload_sd").fileupload({
                dataType: "json",
                dropZone: $("#drop_sd"),
                formData: {target: "sd"},
                done: gcode_upload_done,
                progressall: gcode_upload_progress
            });
        }

        $(document).bind("dragover", function (e) {
            var dropOverlay = $("#drop_overlay");
            var dropZone = $("#drop");
            var dropZoneLocal = $("#drop_locally");
            var dropZoneSd = $("#drop_sd");
            var dropZoneBackground = $("#drop_background");
            var dropZoneLocalBackground = $("#drop_locally_background");
            var dropZoneSdBackground = $("#drop_sd_background");
            var timeout = window.dropZoneTimeout;

            if (!timeout) {
                dropOverlay.addClass('in');
            } else {
                clearTimeout(timeout);
            }

            var foundLocal = false;
            var foundSd = false;
            var found = false
            var node = e.target;
            do {
                if (dropZoneLocal && node === dropZoneLocal[0]) {
                    foundLocal = true;
                    break;
                } else if (dropZoneSd && node === dropZoneSd[0]) {
                    foundSd = true;
                    break;
                } else if (dropZone && node === dropZone[0]) {
                    found = true;
                    break;
                }
                node = node.parentNode;
            } while (node != null);

            if (foundLocal) {
                dropZoneLocalBackground.addClass("hover");
                dropZoneSdBackground.removeClass("hover");
            } else if (foundSd) {
                dropZoneSdBackground.addClass("hover");
                dropZoneLocalBackground.removeClass("hover");
            } else if (found) {
                dropZoneBackground.addClass("hover");
            } else {
                if (dropZoneLocalBackground) dropZoneLocalBackground.removeClass("hover");
                if (dropZoneSdBackground) dropZoneSdBackground.removeClass("hover");
                if (dropZoneBackground) dropZoneBackground.removeClass("hover");
            }

            window.dropZoneTimeout = setTimeout(function () {
                window.dropZoneTimeout = null;
                dropOverlay.removeClass("in");
                if (dropZoneLocal) dropZoneLocalBackground.removeClass("hover");
                if (dropZoneSd) dropZoneSdBackground.removeClass("hover");
                if (dropZone) dropZoneBackground.removeClass("hover");
            }, 100);
        });

        //~~ Offline overlay
        $("#offline_overlay_reconnect").click(function() {dataUpdater.reconnect()});

        //~~ knockout.js bindings

        ko.bindingHandlers.popover = {
            init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                var val = ko.utils.unwrapObservable(valueAccessor());

                var options = {
                    title: val.title,
                    animation: val.animation,
                    placement: val.placement,
                    trigger: val.trigger,
                    delay: val.delay,
                    content: val.content,
                    html: val.html
                };
                $(element).popover(options);
            }
        }

        ko.applyBindings(connectionViewModel, document.getElementById("connection_accordion"));
        ko.applyBindings(printerStateViewModel, document.getElementById("state_accordion"));
        ko.applyBindings(gcodeFilesViewModel, document.getElementById("files_accordion"));
        ko.applyBindings(temperatureViewModel, document.getElementById("temp"));
        ko.applyBindings(controlViewModel, document.getElementById("control"));
        ko.applyBindings(terminalViewModel, document.getElementById("term"));
        ko.applyBindings(gcodeViewModel, document.getElementById("gcode"));
        ko.applyBindings(settingsViewModel, document.getElementById("settings_dialog"));
        ko.applyBindings(navigationViewModel, document.getElementById("navbar"));
        ko.applyBindings(appearanceViewModel, document.getElementsByTagName("head")[0]);

        var timelapseElement = document.getElementById("timelapse");
        if (timelapseElement) {
            ko.applyBindings(timelapseViewModel, timelapseElement);
        }
        var gCodeVisualizerElement = document.getElementById("gcode");
        if (gCodeVisualizerElement) {
            gcodeViewModel.initialize();
        }

        //~~ startup commands

        loginStateViewModel.requestData();
        connectionViewModel.requestData();
        controlViewModel.requestData();
        gcodeFilesViewModel.requestData();
        timelapseViewModel.requestData();

        loginStateViewModel.subscribe(function(change, data) {
            if ("login" == change) {
                $("#gcode_upload").fileupload("enable");

                settingsViewModel.requestData();
                if (data.admin) {
                    usersViewModel.requestData();
                }
            } else {
                $("#gcode_upload").fileupload("disable");
            }
        });

        //~~ UI stuff

        $(".accordion-toggle[href='#files']").click(function() {
            if ($("#files").hasClass("in")) {
                $("#files").removeClass("overflow_visible");
            } else {
                setTimeout(function() {
                    $("#files").addClass("overflow_visible");
                }, 1000);
            }
        })

        $.pnotify.defaults.history = false;

        $.fn.modal.defaults.maxHeight = function(){
            // subtract the height of the modal header and footer
            return $(window).height() - 165;
        }

        // Fix input element click problem on login dialog
        $(".dropdown input, .dropdown label").click(function(e) {
            e.stopPropagation();
        });

        $(document).bind("drop dragover", function (e) {
            e.preventDefault();
        });

        if (CONFIG_FIRST_RUN) {
            var firstRunViewModel = new FirstRunViewModel();
            ko.applyBindings(firstRunViewModel, document.getElementById("first_run_dialog"));
            firstRunViewModel.showDialog();
        }
    }
);

<commit_msg>Properly handle failed uploads: display message, reset upload status<commit_after>$(function() {

        //~~ Initialize view models
        var loginStateViewModel = new LoginStateViewModel();
        var usersViewModel = new UsersViewModel(loginStateViewModel);
        var settingsViewModel = new SettingsViewModel(loginStateViewModel, usersViewModel);
        var connectionViewModel = new ConnectionViewModel(loginStateViewModel, settingsViewModel);
        var printerStateViewModel = new PrinterStateViewModel(loginStateViewModel);
        var appearanceViewModel = new AppearanceViewModel(settingsViewModel);
        var temperatureViewModel = new TemperatureViewModel(loginStateViewModel, settingsViewModel);
        var controlViewModel = new ControlViewModel(loginStateViewModel, settingsViewModel);
        var terminalViewModel = new TerminalViewModel(loginStateViewModel);
        var gcodeFilesViewModel = new GcodeFilesViewModel(printerStateViewModel, loginStateViewModel);
        var timelapseViewModel = new TimelapseViewModel(loginStateViewModel);
        var gcodeViewModel = new GcodeViewModel(loginStateViewModel);
        var navigationViewModel = new NavigationViewModel(loginStateViewModel, appearanceViewModel, settingsViewModel, usersViewModel);

        var dataUpdater = new DataUpdater(
            loginStateViewModel,
            connectionViewModel,
            printerStateViewModel,
            temperatureViewModel,
            controlViewModel,
            terminalViewModel,
            gcodeFilesViewModel,
            timelapseViewModel,
            gcodeViewModel
        );

        // work around a stupid iOS6 bug where ajax requests get cached and only work once, as described at
        // http://stackoverflow.com/questions/12506897/is-safari-on-ios-6-caching-ajax-results
        $.ajaxSetup({
            type: 'POST',
            headers: { "cache-control": "no-cache" }
        });

        //~~ Show settings - to ensure centered
        $('#navbar_show_settings').click(function() {
            $('#settings_dialog').modal()
                 .css({
                     width: 'auto',
                     'margin-left': function() { return -($(this).width() /2); }
                  });
            return false;
        });

        //~~ Temperature

        $('#tabs a[data-toggle="tab"]').on('shown', function (e) {
            temperatureViewModel.updatePlot();
            terminalViewModel.updateOutput();
        });

        //~~ Gcode upload

        function gcode_upload_done(e, data) {
            gcodeFilesViewModel.fromResponse(data.result);
            $("#gcode_upload_progress .bar").css("width", "0%");
            $("#gcode_upload_progress").removeClass("progress-striped").removeClass("active");
            $("#gcode_upload_progress .bar").text("");
        }

        function gcode_upload_fail(e, data) {
            $.pnotify({
                title: "Upload failed",
                text: "
Could not upload the file. Make sure it is a GCODE file and has one of the following extensions: .gcode, .gco

Server reported:
" + data.jqXHR.responseText + "

",
                type: "error",
                hide: false
            });
            $("#gcode_upload_progress .bar").css("width", "0%");
            $("#gcode_upload_progress").removeClass("progress-striped").removeClass("active");
            $("#gcode_upload_progress .bar").text("");
        }

        function gcode_upload_progress(e, data) {
            var progress = parseInt(data.loaded / data.total * 100, 10);
            $("#gcode_upload_progress .bar").css("width", progress + "%");
            $("#gcode_upload_progress .bar").text("Uploading ...");
            if (progress >= 100) {
                $("#gcode_upload_progress").addClass("progress-striped").addClass("active");
                $("#gcode_upload_progress .bar").text("Saving ...");
            }
        }

        var localTarget;
        if (CONFIG_SD_SUPPORT) {
            localTarget = $("#drop_locally");
        } else {
            localTarget = $("#drop");
        }

        $("#gcode_upload").fileupload({
            dataType: "json",
            dropZone: localTarget,
            formData: {target: "local"},
            done: gcode_upload_done,
            fail: gcode_upload_fail,
            progressall: gcode_upload_progress
        });

        if (CONFIG_SD_SUPPORT) {
            $("#gcode_upload_sd").fileupload({
                dataType: "json",
                dropZone: $("#drop_sd"),
                formData: {target: "sd"},
                done: gcode_upload_done,
                fail: gcode_upload_fail,
                progressall: gcode_upload_progress
            });
        }

        $(document).bind("dragover", function (e) {
            var dropOverlay = $("#drop_overlay");
            var dropZone = $("#drop");
            var dropZoneLocal = $("#drop_locally");
            var dropZoneSd = $("#drop_sd");
            var dropZoneBackground = $("#drop_background");
            var dropZoneLocalBackground = $("#drop_locally_background");
            var dropZoneSdBackground = $("#drop_sd_background");
            var timeout = window.dropZoneTimeout;

            if (!timeout) {
                dropOverlay.addClass('in');
            } else {
                clearTimeout(timeout);
            }

            var foundLocal = false;
            var foundSd = false;
            var found = false
            var node = e.target;
            do {
                if (dropZoneLocal && node === dropZoneLocal[0]) {
                    foundLocal = true;
                    break;
                } else if (dropZoneSd && node === dropZoneSd[0]) {
                    foundSd = true;
                    break;
                } else if (dropZone && node === dropZone[0]) {
                    found = true;
                    break;
                }
                node = node.parentNode;
            } while (node != null);

            if (foundLocal) {
                dropZoneLocalBackground.addClass("hover");
                dropZoneSdBackground.removeClass("hover");
            } else if (foundSd) {
                dropZoneSdBackground.addClass("hover");
                dropZoneLocalBackground.removeClass("hover");
            } else if (found) {
                dropZoneBackground.addClass("hover");
            } else {
                if (dropZoneLocalBackground) dropZoneLocalBackground.removeClass("hover");
                if (dropZoneSdBackground) dropZoneSdBackground.removeClass("hover");
                if (dropZoneBackground) dropZoneBackground.removeClass("hover");
            }

            window.dropZoneTimeout = setTimeout(function () {
                window.dropZoneTimeout = null;
                dropOverlay.removeClass("in");
                if (dropZoneLocal) dropZoneLocalBackground.removeClass("hover");
                if (dropZoneSd) dropZoneSdBackground.removeClass("hover");
                if (dropZone) dropZoneBackground.removeClass("hover");
            }, 100);
        });

        //~~ Offline overlay
        $("#offline_overlay_reconnect").click(function() {dataUpdater.reconnect()});

        //~~ knockout.js bindings

        ko.bindingHandlers.popover = {
            init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                var val = ko.utils.unwrapObservable(valueAccessor());

                var options = {
                    title: val.title,
                    animation: val.animation,
                    placement: val.placement,
                    trigger: val.trigger,
                    delay: val.delay,
                    content: val.content,
                    html: val.html
                };
                $(element).popover(options);
            }
        }

        ko.applyBindings(connectionViewModel, document.getElementById("connection_accordion"));
        ko.applyBindings(printerStateViewModel, document.getElementById("state_accordion"));
        ko.applyBindings(gcodeFilesViewModel, document.getElementById("files_accordion"));
        ko.applyBindings(temperatureViewModel, document.getElementById("temp"));
        ko.applyBindings(controlViewModel, document.getElementById("control"));
        ko.applyBindings(terminalViewModel, document.getElementById("term"));
        ko.applyBindings(gcodeViewModel, document.getElementById("gcode"));
        ko.applyBindings(settingsViewModel, document.getElementById("settings_dialog"));
        ko.applyBindings(navigationViewModel, document.getElementById("navbar"));
        ko.applyBindings(appearanceViewModel, document.getElementsByTagName("head")[0]);

        var timelapseElement = document.getElementById("timelapse");
        if (timelapseElement) {
            ko.applyBindings(timelapseViewModel, timelapseElement);
        }
        var gCodeVisualizerElement = document.getElementById("gcode");
        if (gCodeVisualizerElement) {
            gcodeViewModel.initialize();
        }

        //~~ startup commands

        loginStateViewModel.requestData();
        connectionViewModel.requestData();
        controlViewModel.requestData();
        gcodeFilesViewModel.requestData();
        timelapseViewModel.requestData();

        loginStateViewModel.subscribe(function(change, data) {
            if ("login" == change) {
                $("#gcode_upload").fileupload("enable");

                settingsViewModel.requestData();
                if (data.admin) {
                    usersViewModel.requestData();
                }
            } else {
                $("#gcode_upload").fileupload("disable");
            }
        });

        //~~ UI stuff

        $(".accordion-toggle[href='#files']").click(function() {
            if ($("#files").hasClass("in")) {
                $("#files").removeClass("overflow_visible");
            } else {
                setTimeout(function() {
                    $("#files").addClass("overflow_visible");
                }, 1000);
            }
        })

        $.pnotify.defaults.history = false;

        $.fn.modal.defaults.maxHeight = function(){
            // subtract the height of the modal header and footer
            return $(window).height() - 165;
        }

        // Fix input element click problem on login dialog
        $(".dropdown input, .dropdown label").click(function(e) {
            e.stopPropagation();
        });

        $(document).bind("drop dragover", function (e) {
            e.preventDefault();
        });

        if (CONFIG_FIRST_RUN) {
            var firstRunViewModel = new FirstRunViewModel();
            ko.applyBindings(firstRunViewModel, document.getElementById("first_run_dialog"));
            firstRunViewModel.showDialog();
        }
    }
);

<|endoftext|>


<commit_before>/* eslint-env node */

'use strict';

var _ = require('lodash');

module.exports = function(config) {
  var customLaunchers;
  var options;
  var karmaConfig = {
    'coverageReporter': {
      'reporters': [
        {'type': 'lcov', 'dir': 'test/coverage/', 'subdir': '.'},
        {'type': 'text'}
      ]
    },
    'frameworks': [
      'mocha',
      'sinon-chai'
    ],
    'plugins': [
      'karma-coverage',
      'karma-mocha',
      'karma-mocha-reporter',
      'karma-notify-reporter',
      'karma-phantomjs-launcher',
      'karma-sinon-chai'
    ]
  };

  if (process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY && (process.env.TRAVIS || process.env.FORCE_SAUCE)) {
    customLaunchers = require('./test/sauce-browsers');
    options = {
      'browsers': Object.keys(customLaunchers),
      'captureTimeout': 120000,
      'customLaunchers': customLaunchers,
      'plugins': ['karma-sauce-launcher'],
      'reporters': [
        'saucelabs',
        'coverage'
      ],
      'sauceLabs': {
        'recordScreenshots': false,
        'testName': require('./package.json').name
      }
    };

    if (!process.env.TRAVIS) {
      // Assumes a local Source Connect connection is already active
      // https://docs.saucelabs.com/tutorials/js-unit-testing/#running-javascript-unit-tests-on-sauce-locally
      options.sauceLabs.startConnect = false;
    }
  } else {
    options = {
      'browsers': ['PhantomJS'],
      'reporters': [
        'mocha',
        'notify',
        'coverage'
      ],
      'plugins': [
        'karma-notify-reporter',
        'karma-phantomjs-launcher'
      ]
    };
  }

  config.set(_.merge({}, karmaConfig, options, function(a, b) {
    return _.isArray(a)
      ? a.concat(b)
      : void 0;
  }));
};
<commit_msg>Simplify karma reporter config<commit_after>/* eslint-env node */

'use strict';

var _ = require('lodash');

module.exports = function(config) {
  var customLaunchers;
  var options;
  var karmaConfig = {
    'coverageReporter': {
      'reporters': [
        {
          'type': 'lcov',
          'dir': 'test',
          'subdir': 'coverage'
        },
        {'type': 'text'}
      ]
    },
    'frameworks': [
      'mocha',
      'sinon-chai'
    ],
    'plugins': [
      'karma-coverage',
      'karma-mocha',
      'karma-mocha-reporter',
      'karma-notify-reporter',
      'karma-phantomjs-launcher',
      'karma-sinon-chai'
    ]
  };

  if (process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY && (process.env.TRAVIS || process.env.FORCE_SAUCE)) {
    customLaunchers = require('./test/sauce-browsers');
    options = {
      'browsers': Object.keys(customLaunchers),
      'captureTimeout': 120000,
      'customLaunchers': customLaunchers,
      'plugins': ['karma-sauce-launcher'],
      'reporters': [
        'saucelabs',
        'coverage'
      ],
      'sauceLabs': {
        'recordScreenshots': false,
        'testName': require('./package.json').name
      }
    };

    if (!process.env.TRAVIS) {
      // Assumes a local Source Connect connection is already active
      // https://docs.saucelabs.com/tutorials/js-unit-testing/#running-javascript-unit-tests-on-sauce-locally
      options.sauceLabs.startConnect = false;
    }
  } else {
    options = {
      'browsers': ['PhantomJS'],
      'reporters': [
        'mocha',
        'notify',
        'coverage'
      ],
      'plugins': [
        'karma-notify-reporter',
        'karma-phantomjs-launcher'
      ]
    };
  }

  config.set(_.merge({}, karmaConfig, options, function(a, b) {
    return _.isArray(a)
      ? a.concat(b)
      : void 0;
  }));
};
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Sun Jun 18 2017 16:28:13 GMT+0300 (Jerusalem Daylight Time)

const webpack = require('./webpack.config');
const { testGlob } = require('./package.json');

const sauceLabsLaunchers = { // Check out https://saucelabs.com/platforms for all browser/platform combos
    slSafari7: {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.9'
    },
    slIE10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '10'
    },
    slIE11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '11'
    },
    slChrome: {
        base: 'SauceLabs',
        browserName: 'chrome'
    },
    slFirefox: {
        base: 'SauceLabs',
        browserName: 'firefox'
    },
    slAndroid5: {
        base: 'SauceLabs',
        browserName: 'android',
        version: '5.1'
    },
    slAndroid4: {
        base: 'SauceLabs',
        browserName: 'android',
        version: '4.4'
    }
};

module.exports = function (config) {
    config.set({
        // this key is used by karma-webpack, see preprocessors below
        webpack,

        // the default mime type for ts files is video/mp2t, which Chrome won't execute, so force correct mime type
        mime: {
            "text/x-typescript": ["ts", "tsx"],
        },

        customLaunchers: sauceLabsLaunchers,

        sauceLabs: {
            startConnect: false,
            build: 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')',
            tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
        },
        captureTimeout: 120000,
        browserNoActivityTimeout: 25000,

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['mocha'],

        // list of files / patterns to load in the browser
        files: [
            './node_modules/core-js/client/shim.min.js',
            testGlob
        ],

        // list of files to exclude
        exclude: [
        ],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            [testGlob]: ['webpack']
        },

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: process.env.TRAVIS ? ['progress', 'saucelabs'] : ['progress'],

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: process.env.TRAVIS ? Object.keys(sauceLabsLaunchers) : ['Chrome'],

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false,

        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: Infinity
    })
}
<commit_msg>Use dots reporter so that the log will only include failures.<commit_after>// Karma configuration
// Generated on Sun Jun 18 2017 16:28:13 GMT+0300 (Jerusalem Daylight Time)

const webpack = require('./webpack.config');
const { testGlob } = require('./package.json');

const sauceLabsLaunchers = { // Check out https://saucelabs.com/platforms for all browser/platform combos
    slSafari7: {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.9'
    },
    slIE10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '10'
    },
    slIE11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '11'
    },
    slChrome: {
        base: 'SauceLabs',
        browserName: 'chrome'
    },
    slFirefox: {
        base: 'SauceLabs',
        browserName: 'firefox'
    },
    slAndroid5: {
        base: 'SauceLabs',
        browserName: 'android',
        version: '5.1'
    },
    slAndroid4: {
        base: 'SauceLabs',
        browserName: 'android',
        version: '4.4'
    }
};

module.exports = function (config) {
    config.set({
        // this key is used by karma-webpack, see preprocessors below
        webpack,

        // the default mime type for ts files is video/mp2t, which Chrome won't execute, so force correct mime type
        mime: {
            "text/x-typescript": ["ts", "tsx"],
        },

        customLaunchers: sauceLabsLaunchers,

        sauceLabs: {
            startConnect: false,
            build: 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')',
            tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
        },
        captureTimeout: 120000,
        browserNoActivityTimeout: 25000,

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['mocha'],

        // list of files / patterns to load in the browser
        files: [
            './node_modules/core-js/client/shim.min.js',
            testGlob
        ],

        // list of files to exclude
        exclude: [
        ],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            [testGlob]: ['webpack']
        },

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: process.env.TRAVIS ? ['dots', 'saucelabs'] : ['dots'],

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: process.env.TRAVIS ? Object.keys(sauceLabsLaunchers) : ['Chrome'],

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false,

        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: Infinity
    })
}
<|endoftext|>


<commit_before>import ocamlDocCss from './css/ocamlDoc.css';
import ocamlLogo from './images/ocamlLogo128.png';
import reasonLogo from './images/logo128.png';

const ocamlDocStyleTag = document.createElement('link');
const syntaxSwap = document.createElement('div');
const cssSwap = document.createElement('div');

ocamlDocStyleTag.type = 'text/css';
ocamlDocStyleTag.rel = 'stylesheet';
ocamlDocStyleTag.href = chrome.extension.getURL(ocamlDocCss);

let styleTags = [ocamlDocStyleTag];

function hasClassName(className) {
  const els = document.getElementsByClassName(className);
  return els.length > 0;
}

const ocamlishRels = [
  'Start',
  'previous',
  'next',
  'Up',
  'Appendix',
  'Chapter',
  'Section',
  'Subsection',
];

function hasOcamlRels() {
  return Array.prototype.map.call(
    document.getElementsByTagName('link'),
    (link) => ocamlishRels.indexOf(link.getAttribute('rel')) > -1,
  ).filter(Boolean).length >= 3;
}

function hasCommonClassNames() {
  return [
    'keyword',
    'type',
    'deprecated',
    'mod',
    'modt',
    'typ',
    'spec',
    'def',
    'val',
    'ext',
    'exn',
    'cls',
    'clst',
    'include',
    'cons',
    'paramstable',
    'sig_block',
  ].map(hasClassName).filter(Boolean).length >= 3;
}

function hasUniqueClassNames() {
  return [
    'odoc-doc',
    'package-index',
  ].map(hasClassName).filter(Boolean).length > 0;
}

function mightBeOcamlDoc() {
  return hasUniqueClassNames() || hasOcamlRels() || hasCommonClassNames();
}

function swapStyleSheets() {
  const stylesheets = document.getElementsByTagName('link');
  const tempSheets = [];

  for(let sheet of stylesheets) {
    if(sheet.getAttribute('rel') === 'stylesheet') {
      tempSheets.push(sheet);
      removeEl(sheet);
    }
  }

  for(let tag of styleTags) {
    document.head.appendChild(tag);
  }

  styleTags = tempSheets;
}

function normalizeText(text) {
  return text.trim().replace(/[^\x00-\x7F]/g, ' ').replace(String.fromCharCode(65533), '');
}

function getNormalizedLinks(pre) {
  let anchors = pre.getElementsByTagName('a');
  const textToHref = {};
  for (var a of anchors) {
    textToHref[normalizeText(a.innerText)] = a.href;
  }
  return textToHref;
}

function getNormalizedIds(pre) {
  let spans = pre.querySelectorAll('[id]');
  const textToId = {};
  for (var span of spans) {
    const words = normalizeText(span.innerText).split(' ')
    const lastWord = words[words.length - 1];
    textToId[lastWord] = span.id;
  }
  return textToId;
}

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

function swapSyntax() {
  let pres = document.getElementsByTagName('pre');
  let usesFakePres = false;
  if (!pres.length) {
    pres = document.getElementsByClassName('def'); // why is this so hard?
    usesFakePres = true;
  }
  for (var p of pres) {
    const pre = p;
    const hrefs = getNormalizedLinks(pre);
    const ids = getNormalizedIds(pre);
    let maybeTextSibilng;
    let usesTypeTable = false;

    const maybeTypeTable = pre.nextSibling;
    let text = pre.innerText;
    if (maybeTypeTable && maybeTypeTable.classList && maybeTypeTable.classList.contains('typetable')) {
      // who came up with this markup??
      usesTypeTable = true;
      text += maybeTypeTable.innerText;
      if (maybeTypeTable.nextSibling && maybeTypeTable.nextSibling.nodeType === Node.TEXT_NODE) {
        maybeTextSibilng = maybeTypeTable.nextSibling;
        text += maybeTextSibilng.nodeValue;
      }
    }
    chrome.runtime.sendMessage({in: normalizeText(text)},
      ({out: [conversionType, out]}) => {
        if (conversionType !== 'Failure') {
          if (usesTypeTable) {
            removeEl(maybeTypeTable);
            maybeTextSibilng && removeEl(maybeTextSibilng);
          }
          Object.keys(hrefs).forEach((text) => {
            out = out.replace(
              new RegExp(`\\b${escapeRegExp(text)}\\b`, 'g'),
              `<a href=${hrefs[text]}>${text}</a>`,
            );
          });
          Object.keys(ids).forEach((text) => {
            out = out.replace(
              new RegExp(`\\b${escapeRegExp(text)}\\b`, 'g'),
              `<span class="reason_tools_anchor" id=${ids[text]}>${text}</span>`,
            );
          });
          pre.innerHTML = usesFakePres
            ? `<pre>${out}</pre>`
            : out;
        }
      }
    )
  }
  syntaxSwap.style.backgroundImage =
    syntaxSwap.style.backgroundImage === `url("${chrome.extension.getURL(reasonLogo)}")`
      ? `url("${chrome.extension.getURL(ocamlLogo)}")`
      : `url("${chrome.extension.getURL(reasonLogo)}")`
}

function insertEl(el) {
  document.body.appendChild(el);
}

function removeEl(el) {
  el.parentNode.removeChild(el);
}

function addSwappers() {
  const styleTag = document.createElement('style');
  styleTag.type = 'text/css';
  styleTag.innerText = `
  .reason_tools_button.reason_tools_button.reason_tools_button {
    position: fixed;
    right: 0;
    height: 50px;
    width: 50px;
    background-color: black;
    color: white;
    font-family: monospace;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: 900;
    opacity: 0.6;
  }
  .reason_tools_button.reason_tools_button.reason_tools_button:hover {
    opacity: 1;
    cursor: pointer;
  }
  .reason_tools_anchor {
    position: relative;
    margin-top: 50px;
  }
  `;
  insertEl(styleTag);
  cssSwap.style.top = '90px';
  cssSwap.innerText = '</>';
  cssSwap.className = 'reason_tools_button';
  cssSwap.onclick = swapStyleSheets;
  insertEl(cssSwap);

  syntaxSwap.style.top = '40px';
  syntaxSwap.className = 'reason_tools_button';
  syntaxSwap.onclick = swapSyntax;
  syntaxSwap.style.backgroundImage = `url("${chrome.extension.getURL(reasonLogo)}")`
  syntaxSwap.style.backgroundSize = 'cover';
  insertEl(syntaxSwap);
}

if (mightBeOcamlDoc()) {
  swapStyleSheets();
  swapSyntax();
  addSwappers();
}
<commit_msg>remove Chapter as ocamlref because it causes false positives<commit_after>import ocamlDocCss from './css/ocamlDoc.css';
import ocamlLogo from './images/ocamlLogo128.png';
import reasonLogo from './images/logo128.png';

const ocamlDocStyleTag = document.createElement('link');
const syntaxSwap = document.createElement('div');
const cssSwap = document.createElement('div');

ocamlDocStyleTag.type = 'text/css';
ocamlDocStyleTag.rel = 'stylesheet';
ocamlDocStyleTag.href = chrome.extension.getURL(ocamlDocCss);

let styleTags = [ocamlDocStyleTag];

function hasClassName(className) {
  const els = document.getElementsByClassName(className);
  return els.length > 0;
}

const ocamlishRels = [
  'Start',
  'previous',
  'next',
  'Up',
  'Appendix',
  'Section',
  'Subsection',
];

function hasOcamlRels() {
  return Array.prototype.map.call(
    document.getElementsByTagName('link'),
    (link) => ocamlishRels.indexOf(link.getAttribute('rel')) > -1,
  ).filter(Boolean).length >= 3;
}

function hasCommonClassNames() {
  return [
    'keyword',
    'type',
    'deprecated',
    'mod',
    'modt',
    'typ',
    'spec',
    'def',
    'val',
    'ext',
    'exn',
    'cls',
    'clst',
    'include',
    'cons',
    'paramstable',
    'sig_block',
  ].map(hasClassName).filter(Boolean).length >= 3;
}

function hasUniqueClassNames() {
  return [
    'odoc-doc',
    'package-index',
  ].map(hasClassName).filter(Boolean).length > 0;
}

function mightBeOcamlDoc() {
  return hasUniqueClassNames() || hasOcamlRels() || hasCommonClassNames();
}

function swapStyleSheets() {
  const stylesheets = document.getElementsByTagName('link');
  const tempSheets = [];

  for(let sheet of stylesheets) {
    if(sheet.getAttribute('rel') === 'stylesheet') {
      tempSheets.push(sheet);
      removeEl(sheet);
    }
  }

  for(let tag of styleTags) {
    document.head.appendChild(tag);
  }

  styleTags = tempSheets;
}

function normalizeText(text) {
  return text.trim().replace(/[^\x00-\x7F]/g, ' ').replace(String.fromCharCode(65533), '');
}

function getNormalizedLinks(pre) {
  let anchors = pre.getElementsByTagName('a');
  const textToHref = {};
  for (var a of anchors) {
    textToHref[normalizeText(a.innerText)] = a.href;
  }
  return textToHref;
}

function getNormalizedIds(pre) {
  let spans = pre.querySelectorAll('[id]');
  const textToId = {};
  for (var span of spans) {
    const words = normalizeText(span.innerText).split(' ')
    const lastWord = words[words.length - 1];
    textToId[lastWord] = span.id;
  }
  return textToId;
}

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

function swapSyntax() {
  let pres = document.getElementsByTagName('pre');
  let usesFakePres = false;
  if (!pres.length) {
    pres = document.getElementsByClassName('def'); // why is this so hard?
    usesFakePres = true;
  }
  for (var p of pres) {
    const pre = p;
    const hrefs = getNormalizedLinks(pre);
    const ids = getNormalizedIds(pre);
    let maybeTextSibilng;
    let usesTypeTable = false;

    const maybeTypeTable = pre.nextSibling;
    let text = pre.innerText;
    if (maybeTypeTable && maybeTypeTable.classList && maybeTypeTable.classList.contains('typetable')) {
      // who came up with this markup??
      usesTypeTable = true;
      text += maybeTypeTable.innerText;
      if (maybeTypeTable.nextSibling && maybeTypeTable.nextSibling.nodeType === Node.TEXT_NODE) {
        maybeTextSibilng = maybeTypeTable.nextSibling;
        text += maybeTextSibilng.nodeValue;
      }
    }
    chrome.runtime.sendMessage({in: normalizeText(text)},
      ({out: [conversionType, out]}) => {
        if (conversionType !== 'Failure') {
          if (usesTypeTable) {
            removeEl(maybeTypeTable);
            maybeTextSibilng && removeEl(maybeTextSibilng);
          }
          Object.keys(hrefs).forEach((text) => {
            out = out.replace(
              new RegExp(`\\b${escapeRegExp(text)}\\b`, 'g'),
              `<a href=${hrefs[text]}>${text}</a>`,
            );
          });
          Object.keys(ids).forEach((text) => {
            out = out.replace(
              new RegExp(`\\b${escapeRegExp(text)}\\b`, 'g'),
              `<span class="reason_tools_anchor" id=${ids[text]}>${text}</span>`,
            );
          });
          pre.innerHTML = usesFakePres
            ? `<pre>${out}</pre>`
            : out;
        }
      }
    )
  }
  syntaxSwap.style.backgroundImage =
    syntaxSwap.style.backgroundImage === `url("${chrome.extension.getURL(reasonLogo)}")`
      ? `url("${chrome.extension.getURL(ocamlLogo)}")`
      : `url("${chrome.extension.getURL(reasonLogo)}")`
}

function insertEl(el) {
  document.body.appendChild(el);
}

function removeEl(el) {
  el.parentNode.removeChild(el);
}

function addSwappers() {
  const styleTag = document.createElement('style');
  styleTag.type = 'text/css';
  styleTag.innerText = `
  .reason_tools_button.reason_tools_button.reason_tools_button {
    position: fixed;
    right: 0;
    height: 50px;
    width: 50px;
    background-color: black;
    color: white;
    font-family: monospace;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: 900;
    opacity: 0.6;
  }
  .reason_tools_button.reason_tools_button.reason_tools_button:hover {
    opacity: 1;
    cursor: pointer;
  }
  .reason_tools_anchor {
    position: relative;
    margin-top: 50px;
  }
  `;
  insertEl(styleTag);
  cssSwap.style.top = '90px';
  cssSwap.innerText = '</>';
  cssSwap.className = 'reason_tools_button';
  cssSwap.onclick = swapStyleSheets;
  insertEl(cssSwap);

  syntaxSwap.style.top = '40px';
  syntaxSwap.className = 'reason_tools_button';
  syntaxSwap.onclick = swapSyntax;
  syntaxSwap.style.backgroundImage = `url("${chrome.extension.getURL(reasonLogo)}")`
  syntaxSwap.style.backgroundSize = 'cover';
  insertEl(syntaxSwap);
}

if (mightBeOcamlDoc()) {
  swapStyleSheets();
  swapSyntax();
  addSwappers();
}
<|endoftext|>


<commit_before>
/*
* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file.
*/

/// <reference path='../App.js' />

(function () {
    'use strict';

    // The Office initialize function must be run each time a new page is loaded
    Office.initialize = function (reason) {
        $(document).ready(function () {
            app.initialize();
            detectActionsForMe();
        });
    };

    function detectActionsForMe() {
        var item = Office.cast.item.toItemRead(Office.context.mailbox.item);
        if (item.itemType === Office.MailboxEnums.ItemType.Message) {

            var myInfo = Office.context.mailbox.userProfile;

            // If the message is from me, no point in checking any further
            if (item.from.emailAddress === myInfo.emailAddress) {
                app.showNotification('Mail Not Scanned', 'It\'s from you, so we didn\'t think there was any point.');
            }
            else {
                var nameParts = myInfo.displayName.split(' ');

                // Make an assumption that the displayName is in the form 'firstName lastName'
                var myFirstName = nameParts[0];

                // Check whether I was cc'd on this email
                for (var i = 0; i < item.cc.length; i++) {
                    if (item.cc[i].emailAddress === myInfo.emailAddress) {
                        $('#cc-result').text('yes');
                        break;
                    }
                }

                // Check whether I am on the To line
                for (var i = 0; i < item.to.length; i++) {
                    if (item.to[i].emailAddress === myInfo.emailAddress) {
                        $('#to-result').text('yes');
                        break;
                    }
                }

                // Check whether I am mentioned in the body of the email by name
                // In this sample we scan the email body as plain text. You can also
                // set the coercionType on the getAsync() method to retrieve the body as HTML.
                // For an example of retrieving the body as HTML and parsing the result,
                // see https://github.com/OfficeDev/Outlook-Add-in-LinkRevealer/blob/master/LinkRevealerWeb/AppRead/Home/Home.js
                Office.context.mailbox.item.body.getAsync('text', function (asyncResult) {
                    var bodyText = asyncResult.value;

                    // Create regular expression to find all matches of the first name
                    // i => ignore case
                    // g => global match, i.e., doesn't stop after first match
                    var regex = new RegExp(myFirstName, 'gi');
                    var matchingArray = new Array();
                    while (regex.exec(bodyText)) {
                        matchingArray.push(regex.lastIndex);
                    }

                    var result = 'Scan complete.';

                    if (matchingArray.length > 0) {
                        app.showNotification('Scan Complete', 'It looks like you are mentioned by name in this email');
                    }
                    else {
                        app.showNotification('Scan Complete', 'It doesn\'t look like you are mentioned by name in this email');
                    }

                });
            }

        }
    }

})();

// *********************************************************
//
// Outlook-Add-in-ScanForMe, https://github.com/OfficeDev/Outlook-Add-in-ScanForMe
//
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// MIT License:
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// 'Software'), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// *********************************************************<commit_msg>Preparing for pull request merge<commit_after>
/*
* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file.
*/

/// <reference path="../App.js" />

(function () {
    "use strict";

    // The Office initialize function must be run each time a new page is loaded
    Office.initialize = function (reason) {
        $(document).ready(function () {
            app.initialize();

            detectActionsForMe();
        });
    };

    function detectActionsForMe() {
        var item = Office.cast.item.toItemRead(Office.context.mailbox.item);

        if (item.itemType === Office.MailboxEnums.ItemType.Message) {

            var myInfo = Office.context.mailbox.userProfile;
            var nameParts = myInfo.displayName.split(" ");

            // Make an assumption that the displayName is in the form "firstName lastName"
            var myFirstName = nameParts[0];

            // Check whether I was cc'd on this email
            for (var i = 0; i < item.cc.length; i++) {
                if (item.cc[i].emailAddress == myInfo.emailAddress) {
                    $("#cc-result").text("yes");
                    break;
                }
            }

            // Check whether I am on the To line
            for (var i = 0; i < item.to.length; i++) {
                if (item.to[i].emailAddress == myInfo.emailAddress) {
                    $("#to-result").text("yes");
                    break;
                }
            }

            // Check whether I am mentioned in the body of the email by name
            // In this sample we scan the email body as plain text. You can also
            // set the coercionType on the getAsync() method to retrieve the body as HTML.
            // For an example of retrieving the body as HTML and parsing the result,
            // see https://github.com/OfficeDev/Outlook-Add-in-LinkRevealer/blob/master/LinkRevealerWeb/AppRead/Home/Home.js
            Office.context.mailbox.item.body.getAsync(function (asyncResult) {
                var bodyText = asyncResult.value;

                // Create regular expression to find all matches of the first name
                // i => ignore case
                // g => global match, i.e., doesn't stop after first match
                var regex = new RegExp(myFirstName, 'gi');
                var matchingArray = new Array();
                while (regex.exec(bodyText)) {
                    matchingArray.push(regex.lastIndex);
                }

                var result = "Scan complete.";

                if (matchingArray.length > 0)
                {
                    $("#body-result").text("yes");
                    result += " It looks like you were mentioned by name in this email";
                }

                $("#result").text(result);

            });

        }
    }

})();

// *********************************************************
//
// Outlook-Add-in-ScanForMe, https://github.com/OfficeDev/Outlook-Add-in-ScanForMe
//
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// MIT License:
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// *********************************************************<|endoftext|>


<commit_before>-// Developed by Ernesto Vargas
-// me@netoxico.com
-
$(function() {
    // Animations
    $('.welcome-h2').addClass('animated fadeInDown');
    $('.welcome-p').addClass('animated fadeInUp');
    $('.feature-box').addClass('animated fadeInUp');

   // Add new subscription
    $('#newsletter-form').submit(function() {
        $.ajax({
            type: 'POST',
            url: '/subscribe',
            data: $('#newsletter-form').serialize(),
            success: function(data) {
                if (data.success === true) {
                    var button = $('#subscribe-button');
                    button.html('');
                    button.attr('type', 'button');
                    $("input[name='email_field']").val('');

                } else {
                    $('#newsletter-form').addClass('animated bounce');
                    setTimeout(function(){$('#newsletter-form').removeClass('animated bounce')}, 1000)
                }
            }
        });
        return false;
    });

    var job_success = '
' +
      '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' +
      'Bien hecho! Hemos recibido su oferta de trabajo. Por favor espere a que ' +
      'nuestros administradores lo verifiquen para ser mostrado en los resultados
'

    $('#add-job').click(function(){
        $('.modal').modal('toggle')
    });
    // Add new job form
    $('#add-job-form').submit(function() {
        var fields = ['title', 'content', 'contact']
        $.ajax({
            type: 'POST',
            url: '/ofertas/nueva',
            data: $('#add-job-form').serialize(),
            success: function(data) {
                if (data.success === true) {
                    $('#notification').html(job_success);
                    setTimeout(function(){$('#notification').html("")}, 10000)
                    $('.modal').modal('toggle')
                } else {
                    $.each(fields, function( index, value ) {
                        $("label[for='" + value + "']").parent().removeClass('label-error');
                    });
                    $.each(data.errors, function( index, value ) {
                        $("label[for='" + value + "']").parent().addClass('label-error');
                        $('#add-job-form').addClass('animated bounce');
                        setTimeout(function(){$('#add-job-form').removeClass('animated bounce')}, 1000)
                    });
                }
            }
        });
        return false;
    });
});
<commit_msg>Minor fixes in jobs page<commit_after>// Developed by Ernesto Vargas
// me@netoxico.com

$(function() {
    // Animations
    $('.welcome-h2').addClass('animated fadeInDown');
    $('.welcome-p').addClass('animated fadeInUp');
    $('.feature-box').addClass('animated fadeInUp');

   // Add new subscription
    $('#newsletter-form').submit(function() {
        $.ajax({
            type: 'POST',
            url: '/subscribe',
            data: $('#newsletter-form').serialize(),
            success: function(data) {
                if (data.success === true) {
                    var button = $('#subscribe-button');
                    button.html('');
                    button.attr('type', 'button');
                    $("input[name='email_field']").val('');

                } else {
                    $('#newsletter-form').addClass('animated bounce');
                    setTimeout(function(){$('#newsletter-form').removeClass('animated bounce')}, 1000)
                }
            }
        });
        return false;
    });

    var job_success = '
' +
      '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' +
      'Bien hecho! Hemos recibido su oferta de trabajo. Por favor espere a que ' +
      'nuestros administradores lo verifiquen para ser mostrado en los resultados
'

    $('#add-job').click(function(){
        $('.modal').modal('toggle')
    });
    // Add new job form
    $('#add-job-form').submit(function() {
        var fields = ['title', 'content', 'contact']
        $.ajax({
            type: 'POST',
            url: '/ofertas/nueva',
            data: $('#add-job-form').serialize(),
            success: function(data) {
                if (data.success === true) {
                    $('#notification').html(job_success);
                    setTimeout(function(){$('#notification').html("")}, 10000)
                    $('.modal').modal('toggle')
                } else {
                    $.each(fields, function( index, value ) {
                        $("label[for='" + value + "']").parent().removeClass('label-error');
                    });
                    $.each(data.errors, function( index, value ) {
                        $("label[for='" + value + "']").parent().addClass('label-error');
                        $('#add-job-form').addClass('animated bounce');
                        setTimeout(function(){$('#add-job-form').removeClass('animated bounce')}, 1000)
                    });
                }
            }
        });
        return false;
    });
});
<|endoftext|>


<commit_before>DateOperators.millisecondsToHours = 1/(1000*60*60);
DateOperators.millisecondsToDays = 1/(1000*60*60*24);
DateOperators.millisecondsToYears = 0.00000000003169;

DateOperators.MONTH_NAMES_SHORT = ['jan','feb','mar','apr','mai','jun','jul','aug','sep','oct','nov','dec'];
/**
* DateOperators
* @constructor
*/
function DateOperators(){};

/**
 * format cases
 * 0: MM-DD-YYYY
 * 1: YYYY-MM-DD
 * 2: MM-DD-YY
 * 3: YY-MM-DD
 */
DateOperators.stringToDate=function(string, formatCase, separator){
	separator = separator==null?"-":separator;
	formatCase = formatCase==null?0:formatCase;

	var y;

	var parts = string.split(separator);
	switch(formatCase){
		case 0://MM-DD-YYYY
			return new Date(Number(parts[2]), Number(parts[0])-1, Number(parts[1]));
			break;
		case 1://YYYY-MM-DD
			return new Date(Number(parts[0]), Number(parts[1])-1, Number(parts[2]));
			break;
		case 2://MM-DD-YY
			y = Number(parts[2]);
			y = y>=0?y+2000:y+1900;
			return new Date(y, Number(parts[0])-1, Number(parts[1]));
			break;
		case 3://YY-MM-DD
			y = Number(parts[0]);
			y = y>=0?y+2000:y+1900;
			return new Date(y, Number(parts[1])-1, Number(parts[2]));
			break;
	}
}

/**
 * format cases
 * 0: MM-DD-YYYY
 * 1: YYYY-MM-DD
 */
DateOperators.dateToString=function(date, formatCase, separator){
	separator = separator==null?"-":separator;
	formatCase = formatCase==null?0:formatCase;
	var year = date.getFullYear();
	var month = date.getMonth()+1;
	var day = date.getDate();

	switch(formatCase){
		case 0://MM-DD-YYYY
			return month+separator+day+separator+year;
			break;
		case 1://YYYY-MM-DD
			return year+separator+month+separator+day;
			break;
	}
}

/**
 * generates current date Date
 * @return {Date}
 * tags:generate
 */
DateOperators.currentDate = function(){
	return new Date();
}

DateOperators.addDaysToDate=function(date, nDays){
	return new Date(date.getTime()+(nDays/DateOperators.millisecondsToDays));
}

DateOperators.parseDate=function(string){
	return new Date(Date.parse(string.replace(/\./g,"-")));
}

DateOperators.parseDates=function(stringList){
	var dateList = new DateList();
	var i;
	for(i=0;stringList[i]!=null;i++){
		dateList.push(this.parseDate(stringList[i]));
	}
	return dateList;
}

DateOperators.getHoursBetweenDates=function(date0, date1){
	return (date1.getTime() - date0.getTime())*DateOperators.millisecondsToHours;
}
DateOperators.getDaysBetweenDates=function(date0, date1){
	return (date1.getTime() - date0.getTime())*DateOperators.millisecondsToDays;
}
DateOperators.getYearsBetweenDates=function(date0, date1){
	return (date1.getTime() - date0.getTime())*DateOperators.millisecondsToYears;
}

DateOperators.nDayInYear=function(date){
	return Math.floor((date.getTime() - new Date(date.getFullYear(), 0, 1).getTime())*DateOperators.millisecondsToDays);
}

DateOperators.getDateDaysAgo=function(nDays){
	return DateOperators.addDaysToDate(new Date(), -nDays);
}

/**
 * gets the week number within a year (weeks start on Sunday, first week may have less than 7 days if start in a day other than sunday
 * @param {Date} The date whose week you want to retrieve
 * @return {Number} The week number of the date in its year
 * tags:generate
 */
DateOperators.getWeekInYear=function(date){
	var onejan = new Date(date.getFullYear(), 0, 1);
    return Math.ceil((((date - onejan) / 86400000) + onejan.getDay() + 1) / 7);
}

<commit_msg>added operator to compute date difference in weeks<commit_after>DateOperators.millisecondsToHours = 1/(1000*60*60);
DateOperators.millisecondsToDays = 1/(1000*60*60*24);
DateOperators.millisecondsToWeeks = 1/(1000*60*60*24*7);
DateOperators.millisecondsToYears = 0.00000000003169;

DateOperators.MONTH_NAMES_SHORT = ['jan','feb','mar','apr','mai','jun','jul','aug','sep','oct','nov','dec'];
/**
* DateOperators
* @constructor
*/
function DateOperators(){};

/**
 * format cases
 * 0: MM-DD-YYYY
 * 1: YYYY-MM-DD
 * 2: MM-DD-YY
 * 3: YY-MM-DD
 */
DateOperators.stringToDate=function(string, formatCase, separator){
	separator = separator==null?"-":separator;
	formatCase = formatCase==null?0:formatCase;

	var y;

	var parts = string.split(separator);
	switch(formatCase){
		case 0://MM-DD-YYYY
			return new Date(Number(parts[2]), Number(parts[0])-1, Number(parts[1]));
			break;
		case 1://YYYY-MM-DD
			return new Date(Number(parts[0]), Number(parts[1])-1, Number(parts[2]));
			break;
		case 2://MM-DD-YY
			y = Number(parts[2]);
			y = y>=0?y+2000:y+1900;
			return new Date(y, Number(parts[0])-1, Number(parts[1]));
			break;
		case 3://YY-MM-DD
			y = Number(parts[0]);
			y = y>=0?y+2000:y+1900;
			return new Date(y, Number(parts[1])-1, Number(parts[2]));
			break;
	}
}

/**
 * format cases
 * 0: MM-DD-YYYY
 * 1: YYYY-MM-DD
 */
DateOperators.dateToString=function(date, formatCase, separator){
	separator = separator==null?"-":separator;
	formatCase = formatCase==null?0:formatCase;
	var year = date.getFullYear();
	var month = date.getMonth()+1;
	var day = date.getDate();

	switch(formatCase){
		case 0://MM-DD-YYYY
			return month+separator+day+separator+year;
			break;
		case 1://YYYY-MM-DD
			return year+separator+month+separator+day;
			break;
	}
}

/**
 * generates current date Date
 * @return {Date}
 * tags:generate
 */
DateOperators.currentDate = function(){
	return new Date();
}

DateOperators.addDaysToDate=function(date, nDays){
	return new Date(date.getTime()+(nDays/DateOperators.millisecondsToDays));
}

DateOperators.parseDate=function(string){
	return new Date(Date.parse(string.replace(/\./g,"-")));
}

DateOperators.parseDates=function(stringList){
	var dateList = new DateList();
	var i;
	for(i=0;stringList[i]!=null;i++){
		dateList.push(this.parseDate(stringList[i]));
	}
	return dateList;
}

DateOperators.getHoursBetweenDates=function(date0, date1){
	return (date1.getTime() - date0.getTime())*DateOperators.millisecondsToHours;
}
DateOperators.getDaysBetweenDates=function(date0, date1){
	return (date1.getTime() - date0.getTime())*DateOperators.millisecondsToDays;
}
DateOperators.getWeeksBetweenDates=function(date0, date1){
	return (date1.getTime() - date0.getTime())*DateOperators.millisecondsToWeeks;
}
DateOperators.getYearsBetweenDates=function(date0, date1){
	return (date1.getTime() - date0.getTime())*DateOperators.millisecondsToYears;
}

DateOperators.nDayInYear=function(date){
	return Math.floor((date.getTime() - new Date(date.getFullYear(), 0, 1).getTime())*DateOperators.millisecondsToDays);
}

DateOperators.getDateDaysAgo=function(nDays){
	return DateOperators.addDaysToDate(new Date(), -nDays);
}

/**
 * gets the week number within a year (weeks start on Sunday, first week may have less than 7 days if start in a day other than sunday
 * @param {Date} The date whose week you want to retrieve
 * @return {Number} The week number of the date in its year
 * tags:generate
 */
DateOperators.getWeekInYear=function(date){
	var onejan = new Date(date.getFullYear(), 0, 1);
    return Math.ceil((((date - onejan) / 86400000) + onejan.getDay() + 1) / 7);
}

<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');

var browsers        = [];
var customLaunchers = {};
var reporters       = ['dots', 'coverage', 'saucelabs'];

if (process.env.TRAVIS) {
  browsers = [];
  reporters.push('coveralls');
}

if (!process.env.SAUCE_USERNAME && fs.existsSync('sauce.json')) {
  process.env.SAUCE_USERNAME   = require('./sauce').username;
  process.env.SAUCE_ACCESS_KEY = require('./sauce').accessKey;
}

if (process.env.SAUCE_USERNAME) {
  customLaunchers = {
    SL_Chrome_dev: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     'dev',
    },
    SL_Chrome_beta: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     'beta',
    },
    SL_Chrome_50: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     '50',
    },
    SL_Chrome_49: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     '49',
    },
    SL_Edge_13: {
      base:        'SauceLabs',
      platform:    'Windows 10',
      browserName: 'microsoftedge',
      version:     '13',
    },
    SL_InternetExplorer_11: {
      base:        'SauceLabs',
      platform:    'Windows 10',
      browserName: 'internet explorer',
      version:     '11',
    },
    SL_InternetExplorer_10: {
      base:        'SauceLabs',
      platform:    'Windows 8',
      browserName: 'internet explorer',
      version:     '10',
    },
    SL_InternetExplorer_9: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'internet explorer',
      version:     '9',
    },
    // SL_InternetExplorer_8: {
    //   base:        'SauceLabs',
    //   platform:    'Windows 7',
    //   browserName: 'internet explorer',
    //   version:     '8',
    // },
    SL_Firefox_47: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'firefox',
      version:     '47',
    },
    SL_Firefox_45: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'firefox',
      version:     '45',
    },
    SL_Safari_9: {
      base:        'SauceLabs',
      platform:    'OS X 10.11',
      browserName: 'safari',
      version:     '9',
    },
    'SL_Safari_8': {
      base:        'SauceLabs',
      platform:    'OS X 10.10',
      browserName: 'safari',
      version:     '8',
    },
    'SL_Safari_8': {
      base:        'SauceLabs',
      platform:    'OS X 10.10',
      browserName: 'safari',
      version:     '8',
    },
    // SL_Opera_12: {
    //   base:        'SauceLabs',
    //   platform:    'Windows 7',
    //   browserName: 'opera',
    //   version:     '12',
    // },
  };
}

module.exports = function(karma) {
  karma.set({
    browsers:                 browsers.concat(Object.keys(customLaunchers)),
    customLaunchers:          customLaunchers,
    reporters:                reporters,
    browserNoActivityTimeout: 60000,
    frameworks:               ['browserify', 'tap', 'sinon' ],
    browserify: {
      debug: true,
      transform: [
        'babelify',
        'stringify',
        ['browserify-istanbul', {
          instrumenter: require('babel-istanbul')
        }],
      ],
    },
    files: [
      'dist/*.css',
      'test/**/*.test.js',
    ],
    preprocessors: {
      'src/**/*.js':  ['browserify', 'coverage'],
      'test/**/*.js': ['browserify'],
    },
    coverageReporter: {
      dir: 'coverage/',
      reporters: [
        { type: 'text' },
        { type: process.env.TRAVIS ? 'lcov' : 'html' },
      ],
    },
    sauceLabs: {
      testName:          'littlefoot',
      passed:            'true',
      recordScreenshots: false,
    },
  });
};
<commit_msg>iOS and Android, mebbe?<commit_after>'use strict';

var fs = require('fs');

var browsers        = [];
var customLaunchers = {};
var reporters       = ['dots', 'coverage', 'saucelabs'];

if (process.env.TRAVIS) {
  browsers = [];
  reporters.push('coveralls');
}

if (!process.env.SAUCE_USERNAME && fs.existsSync('sauce.json')) {
  process.env.SAUCE_USERNAME   = require('./sauce').username;
  process.env.SAUCE_ACCESS_KEY = require('./sauce').accessKey;
}

if (process.env.SAUCE_USERNAME) {
  customLaunchers = {
    SL_Chrome_dev: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     'dev',
    },
    SL_Chrome_beta: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     'beta',
    },
    SL_Chrome_50: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     '50',
    },
    SL_Chrome_49: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'chrome',
      version:     '49',
    },
    SL_Edge_13: {
      base:        'SauceLabs',
      platform:    'Windows 10',
      browserName: 'microsoftedge',
      version:     '13',
    },
    SL_InternetExplorer_11: {
      base:        'SauceLabs',
      platform:    'Windows 10',
      browserName: 'internet explorer',
      version:     '11',
    },
    SL_InternetExplorer_10: {
      base:        'SauceLabs',
      platform:    'Windows 8',
      browserName: 'internet explorer',
      version:     '10',
    },
    SL_InternetExplorer_9: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'internet explorer',
      version:     '9',
    },
    // SL_InternetExplorer_8: {
    //   base:        'SauceLabs',
    //   platform:    'Windows 7',
    //   browserName: 'internet explorer',
    //   version:     '8',
    // },
    SL_Firefox_46: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'firefox',
      version:     '46',
    },
    SL_Firefox_45: {
      base:        'SauceLabs',
      platform:    'Windows 7',
      browserName: 'firefox',
      version:     '45',
    },
    SL_Safari_9: {
      base:        'SauceLabs',
      platform:    'OS X 10.11',
      browserName: 'safari',
      version:     '9',
    },
    'SL_Safari_8': {
      base:        'SauceLabs',
      platform:    'OS X 10.10',
      browserName: 'safari',
      version:     '8',
    },
    'SL_Safari_8': {
      base:        'SauceLabs',
      platform:    'OS X 10.10',
      browserName: 'safari',
      version:     '8',
    },
    'SL_iOS_Safari_9': {
      base:        'SauceLabs',
      platform:    'OS X 10.10',
      browserName: 'iphone',
      deviceName:  'iPhone Emulator',
      version:     '9.2',
    },
    'SL_Android': {
      base:        'SauceLabs',
      platform:    'Linux',
      browserName: 'android',
      deviceName:  'Android Emulator',
      version:     '5.1.1',
    },
    // SL_Opera_12: {
    //   base:        'SauceLabs',
    //   platform:    'Windows 7',
    //   browserName: 'opera',
    //   version:     '12',
    // },
  };
}

module.exports = function(karma) {
  karma.set({
    browsers:                 browsers.concat(Object.keys(customLaunchers)),
    customLaunchers:          customLaunchers,
    reporters:                reporters,
    browserNoActivityTimeout: 60000,
    frameworks:               ['browserify', 'tap', 'sinon' ],
    browserify: {
      debug: true,
      transform: [
        'babelify',
        'stringify',
        ['browserify-istanbul', {
          instrumenter: require('babel-istanbul')
        }],
      ],
    },
    files: [
      'dist/*.css',
      'test/**/*.test.js',
    ],
    preprocessors: {
      'src/**/*.js':  ['browserify', 'coverage'],
      'test/**/*.js': ['browserify'],
    },
    coverageReporter: {
      dir: 'coverage/',
      reporters: [
        { type: 'text' },
        { type: process.env.TRAVIS ? 'lcov' : 'html' },
      ],
    },
    sauceLabs: {
      testName:          'littlefoot',
      passed:            'true',
      recordScreenshots: false,
    },
  });
};
<|endoftext|>


<commit_before>const Discord = require('discord.js');
const { Command } = require('discord-akairo');
const i18n = require('i18next');
const config = require('../../config.json')

class UnbanCommand extends Command {
	constructor() {
		super('unban', {
			aliases: ['unban', 'ub'],
			category: 'mod',
			args: [
				{
					id: 'unbannedMember',
					type: 'member'
				},
				{
					id: 'reason',
					match: 'rest',
					default: () => i18n.t('unban.noReason')
				}
			],
			channelRestriction: 'guild'
		});
	}

	async exec(msg, args) {
		const bot = guild.me;
		const author = msg.member;
		const unbannedMember = args.unbannedMember;
		const reason = args.reason;

		if (!bot.hasPermission('BAN_MEMBERS')) {
			return msg.reply(i18n.t('unban.noPermission.bot'));
		}

		if (!author.hasPermission('BAN_MEMBERS')) {
			return msg.reply(i18n.t('unban.noPermission.author'));
		}

		await msg.channel.send({embed: this.embed(author.user, unbannedMember.user, reason)});
		unbannedMember.send(i18n.t('unban.pm', { author: author.user, reason : reason, interpolation: { escapeValue: false } }));
		return guild.unban(member.id, {reason: reason});
	}

	embed(author, unbannedMember, reason) {
		return new Discord.RichEmbed()
			.setTitle(i18n.t('commandsUtil:moderation.embed.title'))
			.setAuthor(author.tag, author.displayAvatarURL)
			.setColor(config.richEmbedColors.moderation)
			.setThumbnail(unbannedMember.displayAvatarURL)
			.addField(i18n.t('commandsUtil:moderation.embed.action'), i18n.t('unban.embed.action'), true)
			.addField(i18n.t('commandsUtil:moderation.embed.reason'), reason, true)
			.addBlankField(true)
			.addField(i18n.t('commandsUtil:moderation.embed.member'), unbannedMember, true)
			.addField(i18n.t('commandsUtil:moderation.embed.memberID'), unbannedMember.id, true);
	}
}

module.exports = UnbanCommand;<commit_msg>🐛 Unban command member id fix<commit_after>const Discord = require('discord.js');
const { Command } = require('discord-akairo');
const i18n = require('i18next');
const config = require('../../config.json')

class UnbanCommand extends Command {
	constructor() {
		super('unban', {
			aliases: ['unban', 'ub'],
			category: 'mod',
			args: [
				{
					id: 'unbannedMember' // Snowflake
				},
				{
					id: 'reason',
					match: 'rest',
					default: () => i18n.t('unban.noReason')
				}
			],
			channelRestriction: 'guild'
		});
	}

	async exec(msg, args) {
		const bot = msg.guild.me;
		const guild = msg.guild;
		const author = msg.member;
		const unbannedMember = args.unbannedMember;
		const reason = args.reason;

		if (!bot.hasPermission('BAN_MEMBERS')) {
			return msg.reply(i18n.t('unban.noPermission.bot'));
		}

		if (!author.hasPermission('BAN_MEMBERS')) {
			return msg.reply(i18n.t('unban.noPermission.author'));
		}

		try {
			if (guild.fetchBans().find(user => user.id === 'unbannedMember')) {
				return msg.channel.send(i18n.t('unban.error.unfoundMember', {member: unbannedMember }));
			}
		} catch (e) {
			return console.log(e);
		}

		await msg.channel.send({embed: this.embed(author.user, unbannedMember.user, reason)});
		unbannedMember.send(i18n.t('unban.pm', { author: author.user, reason : reason, interpolation: { escapeValue: false } }));
		return guild.unban(unbannedMember, { reason: reason });
	}

	embed(author, unbannedMember, reason) {
		return new Discord.RichEmbed()
			.setTitle(i18n.t('commandsUtil:moderation.embed.title'))
			.setAuthor(author.tag, author.displayAvatarURL)
			.setColor(config.richEmbedColors.moderation)
			.setThumbnail(unbannedMember.displayAvatarURL)
			.addField(i18n.t('commandsUtil:moderation.embed.action'), i18n.t('unban.embed.action'), true)
			.addField(i18n.t('commandsUtil:moderation.embed.reason'), reason, true)
			.addBlankField(true)
			.addField(i18n.t('commandsUtil:moderation.embed.member'), unbannedMember, true)
			.addField(i18n.t('commandsUtil:moderation.embed.memberID'), unbannedMember.id, true);
	}
}

module.exports = UnbanCommand;<|endoftext|>


<commit_before>var margin = {top: 20, right: 30, bottom: 30, left: 40},
    width = 900 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom,
    barTopMargin = 13;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .tickFormat(function(d) {
        return truncate(d, 14);
    });
var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var chart = d3.select(".chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

console.log("HELLO");
d3.json("/airplanes/chart/manufacturers.json", function(error, data) {
    var data = data.data;

    x.domain(data.map(function(d) { var val = d.Manufacturer; return val; }));
    y.domain([0, d3.max(data, function(d) { return d.Total; })]);

    chart.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    chart.append("g")
        .attr("class", "y axis")
        .call(yAxis);

    chart.selectAll(".bar")
        .data(data)
        .enter().append("rect")
        .attr("class", "bar")
        .attr("x", function(d) { var val = d.Manufacturer; return x(val); })
        .attr("y", function(d) { return y(d.Total); })
        .attr("height", function(d) { return height - y(d.Total); })
        .attr("width", x.rangeBand());
});

function truncate(d, l) {
     if(d.length > l)
         return d.substring(0,l)+'...';
     else
         return d;
}
<commit_msg>Cleanup of airplanes.js in chapter 7, which shows the manufacturers of airplanes in a bar chart.<commit_after>var margin = {top: 20, right: 30, bottom: 30, left: 40},
    width = 900 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .tickFormat(function(d) {
        return truncate(d, 14);
    });
var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var chart = d3.select(".chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.json("/airplanes/chart/manufacturers.json", function(error, data) {
    var data = data.data;

    x.domain(data.map(function(d) { return d.Manufacturer; }));
    y.domain([0, d3.max(data, function(d) { return d.Total; })]);

    chart.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    chart.append("g")
        .attr("class", "y axis")
        .call(yAxis);

    chart.selectAll(".bar")
        .data(data)
        .enter().append("rect")
        .attr("class", "bar")
        .attr("x", function(d) { return x(d.Manufacturer); })
        .attr("y", function(d) { return y(d.Total); })
        .attr("height", function(d) { return height - y(d.Total); })
        .attr("width", x.rangeBand());
});

function truncate(d, l) {
     if(d.length > l)
         return d.substring(0,l)+'...';
     else
         return d;
}
<|endoftext|>


<commit_before>module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      //Setup:
      './node_modules/angular/angular.js',                             // angular
      './node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js', // bootstrap
      './node_modules/underscore/underscore-min.js',                   // underscore
      './node_modules/angular-mocks/angular-mocks.js',                 // loads our modules for tests
      './bin/assets/cloudstorm.js',                                    // cloudstorm itself
      // if you wanna load template files in nested directories, you must use this:
      './src/**/*.haml',

      // Tests:
      './src/components/cs-alert/cs-alert-service.spec.js',
      './src/components/cs-alert/cs-alert.spec.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '**/*.haml': ['ng-haml2js'],
      './bin/assets/cloudstorm.js': ['coverage']
    },

    ngHaml2JsPreprocessor: {
      stripPrefix: 'src/',

      // cacheIdFromPath: function(filepath) {
      //   // remove 'src/' from the start of the filename so the template cache works:
      //   return filepath.substring(4);
      // },
      moduleName: 'hamlTemplates'
    },

    coverageReporter: {
      type : 'lcov',
      dir : 'coverage/'
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['spec', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}
<commit_msg>Simplify karma config<commit_after>// module.exports = function(config) {
//   config.set({

//     // base path that will be used to resolve all patterns (eg. files, exclude)
//     basePath: '',

//     // frameworks to use
//     // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
//     frameworks: ['jasmine'],

//     // list of files / patterns to load in the browser
//     files: [
//       //Setup:
//       './node_modules/angular/angular.js',                             // angular
//       './node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js', // bootstrap
//       './node_modules/underscore/underscore-min.js',                   // underscore
//       './node_modules/angular-mocks/angular-mocks.js',                 // loads our modules for tests
//       './bin/assets/cloudstorm.js',                                    // cloudstorm itself
//       // HAML templates (there is a preprocess step injecting them in the template cache)
//       './src/**/*.haml',
//       // Tests
//       './src/**/*.spec.js'
//     ],

//     // list of files to exclude
//     exclude: [
//     ],

//     // preprocess matching files before serving them to the browser
//     // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
//     preprocessors: {
//       './src/**/*.haml': ['ng-haml2js'],
//       './bin/assets/cloudstorm.js': ['coverage']
//     },

//     ngHaml2JsPreprocessor: {
//       stripPrefix: 'src/',
//       moduleName: 'hamlTemplates'
//     },

//     coverageReporter: {
//       type : 'lcov',
//       dir : 'coverage/'
//     },

//     // test results reporter to use
//     // possible values: 'dots', 'progress'
//     // available reporters: https://npmjs.org/browse/keyword/karma-reporter
//     reporters: ['spec', 'coverage'],

//     // web server port
//     port: 9876,

//     // enable / disable colors in the output (reporters and logs)
//     colors: true,

//     // level of logging
//     // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
//     logLevel: config.LOG_INFO,

//     // enable / disable watching file and executing tests whenever any file changes
//     autoWatch: true,

//     // start these browsers
//     // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
//     browsers: ['PhantomJS'],

//     // Continuous Integration mode
//     // if true, Karma captures browsers, runs the tests and exits
//     singleRun: false,

//     // Concurrency level
//     // how many browser should be started simultaneous
//     concurrency: Infinity
//   })
// }
<|endoftext|>


<commit_before>/*!
 * SWIF-OpenSTC
 * Copyright 2013-2014 Siclic <contact@siclic.fr>
 * Licensed under AGPL-3.0 (https://www.gnu.org/licenses/agpl.txt)
 */

define([
	'app',
	'appHelpers',

	'bookingsCollection',
	'bookingModel',

	'genericListView',
	'paginationView',

	'itemBookingView',
	'toolbarButtonsView',

	'metaDataModel'

], function(app, AppHelpers, BookingsCollection, BookingModel, GenericListView, PaginationView, ItemBookingView,
				ToolbarButtonsView, MetaDataModel){

	'use strict';

	/******************************************
	* Bookings List View
	*/
	var bookingsListView = GenericListView.extend({

		templateHTML : '/templates/lists/bookingsList.html',

		model : BookingModel,

		//overrides url GenericListView's url parameters to add 'recurrence parameter'
		urlParameters: ['recurrence', 'id', 'search', 'filter', 'sort', 'page'],

		// The DOM events //
		events: function(){
			return _.defaults({
				'click #badge[data-filter!=""]'  : 'badgeFilter',
				'click a.createModel'            : 'createResa'
			},
				GenericListView.prototype.events
			);
		},

		/** View Initialization
		*/
		initialize : function(params) {
			var self = this;

			this.options = params;

			// Check if the collections are instantiated //
			if(_.isUndefined(this.collection)){ this.collection = new BookingsCollection(); }
			else{this.collection.reset();}

			GenericListView.prototype.initialize.apply(self, arguments);
		},

		add: function(model){
			//TODO : add item after new booking created
		},

		/** Partial Render of the view : refresh toolbar buttons
		*/
		partialRender: function(model){
			var self = this;
			if(! _.isNull(model) && !_.isUndefined(model) ) {
				if( model.getRecurrence('id')!= false )
					app.views.toolbarButtonsView.initialize( { collection: this.collection } );
			}
			GenericListView.prototype.partialRender.apply(self);
		},

		/** Display the view
		*/
		render : function() {
			var self = this;

			// Change the page title //
			app.router.setPageTitle(app.lang.resa.viewsTitles.bookingsList);

			// Retrieve the HTML template //
			$.get(app.menus.openresa + this.templateHTML, function(templateData){
				var template = _.template(templateData, {
					lang             : app.lang,
					bookings         : self.collection,
					nbBookings       : self.collection.specialCpt,
					BookingModel	 : BookingModel,
					bookingsState    : BookingModel.status,
				});

				$(self.el).html(template);

				// Call the render Generic View //
				GenericListView.prototype.render.apply(self);

				// Create item booking view //
				_.each(self.collection.models, function(booking, i){
					var itemView = new ItemBookingView( {model: booking} );
					$('#booking-items').append(itemView.render().el);
				});

				//Toolbar buttons : factory actions for multiple bookings ( confirm/cancel:close booking)
				app.views.toolbarButtonsView = new ToolbarButtonsView( { collection: self.collection } );

			});
			$(this.el).hide().fadeIn();
			return this;
		},

		/** Filter Bookings on the State of the Badge
		 	*/
		badgeFilter: function(e){
		 	e.preventDefault();

		 	delete this.options.recurrence;
			var filterValue = $(e.target).data('filter');

			// Set the filter value in the options of the view //
			if(filterValue != ''){
				this.options.filter = [{field: 'state', operator: 'in', value: [filterValue] }];
				delete this.options.search;
				delete this.options.page;
			}

			app.router.navigate(this.urlBuilder(), {trigger: true, replace: true});
		},

		/** Got to create Resa form
		*/
		createResa: function(e){
			e.preventDefault();
			// forward to new route (go to form 'create resa')
			app.router.navigate(_.join('/',_(Backbone.history.fragment).strLeft('/'), 'planning-des-reservations'), {trigger: true, replace: true});
		},

		// TODO GenericListView
		/*//add filter for claimer to fetch only their own bookings
		if(!app.current_user.isResaManager()){
			this.fetchParams.data.filters  = _.toArray(this.fetchParams.data.filters);
			this.fetchParams.data.filters.push({field: 'partner_id.address.id', operator:'in', value:app.current_user.get('contact_id')});
			this.fetchParams.data.filters = app.objectifyFilters(this.fetchParams.data.filters);
		}

	});

	return bookingsListView;
});<commit_msg>BUG FIX on reservation's list after merge filter branch<commit_after>/*!
 * SWIF-OpenSTC
 * Copyright 2013-2014 Siclic <contact@siclic.fr>
 * Licensed under AGPL-3.0 (https://www.gnu.org/licenses/agpl.txt)
 */

define([
	'app',
	'appHelpers',

	'bookingsCollection',
	'bookingModel',

	'genericListView',
	'paginationView',

	'itemBookingView',
	'toolbarButtonsView',

	'metaDataModel'

], function(app, AppHelpers, BookingsCollection, BookingModel, GenericListView, PaginationView, ItemBookingView,
				ToolbarButtonsView, MetaDataModel){

	'use strict';

	/******************************************
	* Bookings List View
	*/
	var bookingsListView = GenericListView.extend({

		templateHTML : '/templates/lists/bookingsList.html',

		model : BookingModel,

		//overrides url GenericListView's url parameters to add 'recurrence parameter'
		urlParameters: ['recurrence', 'id', 'search', 'filter', 'sort', 'page'],

		// The DOM events //
		events: function(){
			return _.defaults({
				'click #badge[data-filter!=""]'  : 'badgeFilter',
				'click a.createModel'            : 'createResa'
			},
				GenericListView.prototype.events
			);
		},

		/** View Initialization
		*/
		initialize : function(params) {
			var self = this;

			this.options = params;

			// Check if the collections are instantiated //
			if(_.isUndefined(this.collection)){ this.collection = new BookingsCollection(); }
			else{this.collection.reset();}

			GenericListView.prototype.initialize.apply(self, arguments);
		},

		add: function(model){
			//TODO : add item after new booking created
		},

		/** Partial Render of the view : refresh toolbar buttons
		*/
		partialRender: function(model){
			var self = this;
			if(! _.isNull(model) && !_.isUndefined(model) ) {
				if( model.getRecurrence('id')!= false )
					app.views.toolbarButtonsView.initialize( { collection: this.collection } );
			}
			GenericListView.prototype.partialRender.apply(self);
		},

		/** Display the view
		*/
		render : function() {
			var self = this;

			// Change the page title //
			app.router.setPageTitle(app.lang.resa.viewsTitles.bookingsList);

			// Retrieve the HTML template //
			$.get(app.menus.openresa + this.templateHTML, function(templateData){
				var template = _.template(templateData, {
					lang             : app.lang,
					bookings         : self.collection,
					nbBookings       : self.collection.specialCpt,
					BookingModel	 : BookingModel,
					bookingsState    : BookingModel.status,
				});

				$(self.el).html(template);

				// Call the render Generic View //
				GenericListView.prototype.render.apply(self);

				// Create item booking view //
				_.each(self.collection.models, function(booking, i){
					var itemView = new ItemBookingView( {model: booking} );
					$('#booking-items').append(itemView.render().el);
				});

				//Toolbar buttons : factory actions for multiple bookings ( confirm/cancel:close booking)
				app.views.toolbarButtonsView = new ToolbarButtonsView( { collection: self.collection } );

			});
			$(this.el).hide().fadeIn();
			return this;
		},

		/** Filter Bookings on the State of the Badge
		 	*/
		badgeFilter: function(e){
		 	e.preventDefault();

		 	delete this.options.recurrence;
			var filterValue = $(e.target).data('filter');

			// Set the filter value in the options of the view //
			if(filterValue != ''){
				this.options.filter = [{field: 'state', operator: 'in', value: [filterValue] }];
				delete this.options.search;
				delete this.options.page;
			}

			app.router.navigate(this.urlBuilder(), {trigger: true, replace: true});
		},

		/** Got to create Resa form
		*/
		createResa: function(e){
			e.preventDefault();
			// forward to new route (go to form 'create resa')
			app.router.navigate(_.join('/',_(Backbone.history.fragment).strLeft('/'), 'planning-des-reservations'), {trigger: true, replace: true});
		},

		// TODO GenericListView
		/*//add filter for claimer to fetch only their own bookings
		if(!app.current_user.isResaManager()){
			this.fetchParams.data.filters  = _.toArray(this.fetchParams.data.filters);
			this.fetchParams.data.filters.push({field: 'partner_id.address.id', operator:'in', value:app.current_user.get('contact_id')});
			this.fetchParams.data.filters = app.objectifyFilters(this.fetchParams.data.filters);
		}*/

	});

	return bookingsListView;
});<|endoftext|>


<commit_before>module.exports = function(karma) {
    karma.set({
        basePath: 'media',

        files: [
          "http://heartcode-canvasloader.googlecode.com/files/heartcode-canvasloader-min-0.9.1.js",
          "js/vendor/jquery-1.9.1.js",
          "js/vendor/jquery-ui-1.10.3.js",
          "js/vendor/uri.js",
          "js/vendor/handlebars-1.0.0.js",
          "js/vendor/ember-debug.js",
          "js/vendor/ember-animated-outlet.js",
          "js/vendor/ic-ajax.js",
          "js/vendor/ember-data.js",
          "js/vendor/loading.js",
          "js/vendor/arbor.js",

          "js/app.js",
          "js/api.js",
          "js/canvas.js",
          "js/controllers/controllers.js",
          "js/controllers/*.js",
          "js/crawlgraph.js",
          "js/emberui.js",
          "js/jqplugins.js",
          "js/models.js",
          "js/routes.js",
          "js/documentview.js",
          "js/views.js",
          "js/templates/*.handlebars",

          "tests/fixtures.js",
          "tests/*.js",

          "css/normalize.css",
          "css/jquery-ui-1.10.3.custom.css",
          "css/style.css",
          "css/ember-animated-outlet.css",
        ],

        logLevel: karma.LOG_WARN,

        browsers: ['Chrome', 'Firefox', 'PhantomJS'],

        // Disable security to avoid XSS errors.
        customLaunchers: {
            Chrome_without_security: {
              base: 'Chrome',
              flags: ['--disable-web-security']
            },
            PhantomJS_without_security: {
              base: 'PhantomJS',
              flags: ['--web-security=no']
            }
        },
        singleRun: true,
        autoWatch: false,

        frameworks: ["qunit"],

        plugins: [
            'karma-qunit',
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-ember-preprocessor',
            'karma-phantomjs-launcher'
        ],

        preprocessors: {
            "**/*.handlebars": 'ember'
        }
    });
};
<commit_msg>Updated karma config.<commit_after>module.exports = function(karma) {
    karma.set({
        basePath: 'media',

        files: [
          "http://heartcode-canvasloader.googlecode.com/files/heartcode-canvasloader-min-0.9.1.js",
          "js/vendor/jquery-1.9.1.js",
          "js/vendor/jquery-ui-1.10.3.js",
          "js/vendor/uri.js",
          "js/vendor/handlebars-1.0.0.js",
          "js/vendor/ember-debug.js",
          "js/vendor/ember-animated-outlet.js",
          "js/vendor/ic-ajax.js",
          "js/vendor/ember-data.js",
          "js/vendor/loading.js",
          "js/vendor/arbor.js",

          "js/app.js",
          "js/api.js",
          "js/canvas.js",
          "js/documentview.js",
          "js/controllers/controllers.js",
          "js/controllers/*.js",
          "js/crawlgraph.js",
          "js/emberui.js",
          "js/jqplugins.js",
          "js/models.js",
          "js/routes.js",
          "js/views.js",
          "js/templates/*.handlebars",

          "tests/fixtures.js",
          "tests/*.js",

          "css/normalize.css",
          "css/jquery-ui-1.10.3.custom.css",
          "css/style.css",
          "css/ember-animated-outlet.css",
        ],

        logLevel: karma.LOG_WARN,

        browsers: ['Chrome', 'Firefox', 'PhantomJS'],

        // Disable security to avoid XSS errors.
        customLaunchers: {
            Chrome_without_security: {
              base: 'Chrome',
              flags: ['--disable-web-security']
            },
            PhantomJS_without_security: {
              base: 'PhantomJS',
              flags: ['--web-security=no']
            }
        },
        singleRun: true,
        autoWatch: false,

        frameworks: ["qunit"],

        plugins: [
            'karma-qunit',
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-ember-preprocessor',
            'karma-phantomjs-launcher'
        ],

        preprocessors: {
            "**/*.handlebars": 'ember'
        }
    });
};
<|endoftext|>