<commit_before>
// SmoothScroll v0.9.4
// Licensed under the terms of the MIT license.

// People involved
// - Balazs Galambosi: maintainer (CHANGELOG.txt)
// - Patrick Brunner (patrickb1991@gmail.com)
// - Michael Herf: Pulse Algorithm

// Frame Variables
var frame         = false;
var noscrollframe = false;

// Scroll Variables (tweakable)
var framerate = 150; // [Hz]
var animtime  = 400; // [px]
var stepsize  = 120; // [px]

// Pulse (less tweakable)
// ratio of "tail" to "acceleration"
var pulseAlgorithm = true;
var pulseScale     = 8;
var pulseNormalize = 1;

// Keyboard Settings
var keyboardsupport = true;
var disableKeyboard = false;
var arrowscroll     = 50; // [px]

// Excluded pages
var exclude = "";

// Other Variables
var scrolls;
var deltaX = 0;
var deltaY = 0;
var direction = "down";
var initdone  = false;
var activeElement;

var key = { up: 38, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36 };

/***********************************************
 * SETTINGS
 ***********************************************/

chrome.extension.connect({ name: "smoothscroll" }).
onMessage.addListener(function (settings) {

    // NOTE: + converts to {Number}
    framerate = +settings.framerate;
    animtime  = +settings.animtime;
    stepsize  = +settings.scrollsz;
    exclude   = settings.exclude;
    pulseAlgorithm  = (settings.pulseAlgorithm == "true");
    pulseScale      = +settings.pulseScale;
    keyboardsupport = (settings.keyboardsupport == "true");
    arrowscroll     = +settings.arrscroll;

    scrolls = setupScrolls();
    computePulseScale();

    // it seems that sometimes settings come late
    // and we need to test again for excluded pages
    initTest();

    if (keyboardsupport && !disableKeyboard) {
        addEvent("keydown", keydown);
    }

    // If extension settings were deleted somehow
    if (!framerate) {
        alert("SmoothScroll: Please restart Chrome");
    }
});

/***********************************************
 * INITIALIZE
 ***********************************************/

/**
 * Tests if smooth scrolling is allowed. Shuts down everything if not.
 */
function initTest() {

    // disable keys for google reader (spacebar conflict)
    if (document.URL.indexOf("google.com/reader/view") > -1) {
        disableKeyboard = true;
    }

    // disable everything if the page is blacklisted
    if (exclude) {
        var domains = exclude.split(/[,\n] ?/);
        for (var i = domains.length; i--;) {
            if (document.URL.indexOf(domains[i]) > -1) {
                removeEvent("mousewheel", wheel);
                disableKeyboard = true;
                break;
            }
        }
    }

    // disable keyboard support if anything above requested it
    if (disableKeyboard) {
        removeEvent("keydown", keydown);
    }
}

/**
 * Fills up the scrolls array with easing values.
 * Uses pulse to make it smooth.
 */
function setupScrolls() {

    scrolls = [];

    var last = 0;
    var frames = Math.floor(framerate * animtime / 1000);

    for (var i = 0; i < frames; i++) {
        // scroll is [0, 1]
        var scroll = (i + 1) / frames;
        // transform [0, 1] -> [0, 1]:
        if (pulseAlgorithm) {
           scroll = pulse(scroll);
        }

        // scale and quantize to int so our pixel difference works:
        var iscroll = Math.floor(stepsize * scroll + 0.99);
        scrolls.push(iscroll - last);
        last = iscroll;
    }

    return scrolls;
}

/**
 * Sets up scrolls array, determines if frames are involved.
 */
function init() {

    var body  = document.body;
    var docel = document.documentElement;
    var htmlHeight   = docel.offsetHeight;
    var windowHeight = window.innerHeight;

    activeElement = body;

    initTest();

    if (!scrolls) {
      scrolls = setupScrolls();
    }

    // Checks if this script is running in a frame
    if (top != self) {
        frame = true;
        if (docel.scrollHeight <= docel.clientHeight + 10) {
            noscrollframe = true;
        }
    }

    /**
     * This fixes a bug where the areas left and right to
     * the content does not trigger the onmousewheel event
     * on some pages. e.g.: html, body { height: 100% }
     */
    else if (body.scrollHeight > windowHeight &&
            (body.offsetHeight === windowHeight || htmlHeight === windowHeight)) {

        var underlay = document.createElement("div");
        underlay.setAttribute( "style",
            "z-index: -1; position: absolute; top: 0; left: 0; " +
            "width: 100%; height: " + body.scrollHeight + "px;" );
        body.appendChild(underlay);

        var scrollHeight = body.scrollHeight;
        var pending = false;

        // DOMChange delayed
        var refresh = function() {
            if (!pending && scrollHeight != body.scrollHeight) {
                pending = true; // add a new pending action
                setTimeout(function(){
                    underlay.style.height = body.scrollHeight + "px";
                    scrollHeight = body.scrollHeight;
                    pending = false;
                }, 1000); // act rarely to stay fast
            }
        }

        addEvent("DOMNodeInserted", refresh);
        addEvent("DOMNodeRemoved",  refresh);
    }
    initdone = true;
}

/************************************************
 * SCROLLING
 ************************************************/

var que = []; // Array of offsets [x, y]
var x = 0, y = 1; // {enum}
var pending = false;

/**
 * Pushes scroll actions to a given direction Array.
 */
function scrollArray(elem, dir, multiplyX, multiplyY, delay) {

    delay || (delay = 1000);
    directionCheck(dir);

    for (var i = 0; i < scrolls.length; i++) {
        que[i] || (que[i] = [0, 0]);
        que[i][x] += multiplyX * scrolls[i];
        que[i][y] += multiplyY * scrolls[i];
    }

    function step() {

        var scroll = que.shift();
        var addX = scroll[x] >> 0; // toInt
        var addY = scroll[y] >> 0; // toInt

        // scroll left
        if (multiplyX && addX) {
            var lastLeft = elem.scrollLeft;
            elem.scrollLeft += addX;

            // scroll left failed (edge)
            if (elem.scrollLeft === lastLeft) {
                multiplyX = 0;
            }
        }

        // scroll top
        if (multiplyY && addY) {
            var lastTop = elem.scrollTop;
            elem.scrollTop += addY;

            // scroll top failed (edge)
            if (elem.scrollTop === lastTop) {
                multiplyY = 0;
            }
        }

        // clean up if there's nothing left to do
        if (!multiplyX && !multiplyY) {
            que = [];
        }

        if (que.length) {
            setTimeout(step, delay / framerate + 1);
        } else {
            pending = false;
        }
    }

    // start a new que of actions
    if (!pending) {
        setTimeout(step, 0);
        pending = true;
    }
}

/***********************************************
 * EVENTS
 ***********************************************/

/**
 * Mouse wheel handler.
 * NOTE: function logic should be decomposed.
 * @param {Object} event
 */
function wheel(event) {

    if (!initdone) {
        init();
    }

    var target = event.target;

    // use default if there's no overflowing
    // element or default action is prevented
    var elem = overflowingAncestor(target);
    if (!elem || noscrollframe || event.defaultPrevented ||
        isNodeName(activeElement, "embed") ||
       (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) {
        return true;
    }

    deltaX = event.wheelDeltaX || 0;
    deltaY = event.wheelDeltaY || 0;

    // normalize deltas
    // synaptics seems to send 1 sometimes,
    // and 120 other times (fix)
    if (Math.abs(deltaX) > 1.2) {
        deltaX /= 120;
    }
    if (Math.abs(deltaY) > 1.2) {
        deltaY /= 120;
    }

    var dir = (deltaY > 0) ? "up" : "down";
    scrollArray(elem, dir, -deltaX, -deltaY);
    event.preventDefault();
}

/**
 * Keydown event handler.
 * @param {Object} event
 */
function keydown(event) {

    var target   = event.target;
    var modifier = event.ctrlKey || event.altKey || event.metaKey;

    // do nothing if user is editing text
    // or using a modifier key (except shift)
    if ( /input|textarea|embed/i.test(target.nodeName) ||
         target.isContentEditable ||
         event.defaultPrevented   ||
         modifier ) {
      return true;
    }
    // spacebar should trigger button press
    if (isNodeName(target, "button") &&
        event.keyCode === key.spacebar) {
      return true;
    }

    var scale, dir, shift;
    var elem = overflowingAncestor(activeElement);
    var clientHeight = elem.clientHeight;

    if (elem == document.body) {
        clientHeight = window.innerHeight;
    }

    switch (event.keyCode) {
        case key.up:
            scale = -arrowscroll;
            dir = "up";
            break;
        case key.down:
            scale = arrowscroll;
            dir = "down";
            break;
        case key.spacebar: // (+ shift)
            shift = event.shiftKey ? 1 : -1;
            scale = -shift * clientHeight * 0.9;
            dir = (shift > 0) ? "up" : "down";
            break;
        case key.pageup:
            scale = -clientHeight * 0.9;
            dir = "up";
            break;
        case key.pagedown:
            scale = clientHeight * 0.9;
            dir = "down";
            break;
        case key.home:
            scale = -elem.scrollTop;
            dir = "up";
            break;
        case key.end:
            var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
            scale = (damt > 0) ? damt+10 : 0;
            dir = "down";
            break;
        default:
            return true; // a key we don"t care about
    }
    scale /= stepsize;
    scrollArray(elem, dir, 0, scale);
    event.preventDefault();
}

/**
 * Mousedown event only for updating activeElement
 */
function mousedown(event) {
    activeElement = event.target;
}

/***********************************************
 * HELPERS
 ***********************************************/

function addEvent(type, fn, bubble) {
    window.addEventListener(type, fn, (bubble||false));
}

function removeEvent(type, fn, bubble) {
    window.removeEventListener(type, fn, (bubble||false));
}

function isNodeName(el, tag) {
    return el.nodeName.toLowerCase() === tag.toLowerCase();
}

function directionCheck(dir) {
    if (direction !== dir) {
        que = [];
        direction = dir;
    }
}

function overflowingAncestor(el) {
    var bodyScrollHeight = document.body.scrollHeight;
    do {
        if (bodyScrollHeight === el.scrollHeight) {
            return document.body;
        }
        else if (el.clientHeight + 10 < el.scrollHeight) {
            overflow = getComputedStyle(el, "").getPropertyValue("overflow");
            if (overflow === "scroll" || overflow === "auto") {
                return el;
            }
        }
    } while (el = el.parentNode);
}

/***********************************************
 * PULSE
 ***********************************************/

/**
 * Viscous fluid with a pulse for part and decay for the rest.
 * - Applies a fixed force over an interval (a damped acceleration), and
 * - Lets the exponential bleed away the velocity over a longer interval
 * - Michael Herf, http://stereopsis.com/stopping/
 */
function pulse_(x) {
    var val, start, expx;
    // test
    x = x * pulseScale;
    if (x < 1) { // acceleartion
        val = x - (1 - Math.exp(-x));
    } else {     // tail
        // the previous animation ended here:
        start = Math.exp(-1);
        // simple viscous drag
        x -= 1;
        expx = 1 - Math.exp(-x);
        val = start + (expx * (1 - start));
    }
    return val * pulseNormalize;
}

function computePulseScale() {
    pulseNormalize = 1 / pulse_(1);
}

/**
 * Viscous fluid with a pulse for part and decay for the rest
 */
function pulse(x) {
    if (x >= 1) return 1;
    if (x <= 0) return 0;

    if (pulseNormalize == 1) {
        computePulseScale();
    }
    return pulse_(x);
}

addEvent("mousedown", mousedown);
addEvent("mousewheel", wheel);
addEvent("DOMContentLoaded", init);
<commit_msg>limit FPS to 250. #issue12 - Thanks to MayhemYDG<commit_after>
// SmoothScroll v0.9.4
// Licensed under the terms of the MIT license.

// People involved
// - Balazs Galambosi: maintainer (CHANGELOG.txt)
// - Patrick Brunner (patrickb1991@gmail.com)
// - Michael Herf: Pulse Algorithm

// Frame Variables
var frame         = false;
var noscrollframe = false;

// Scroll Variables (tweakable)
var framerate = 150; // [Hz]
var animtime  = 400; // [px]
var stepsize  = 120; // [px]

// Pulse (less tweakable)
// ratio of "tail" to "acceleration"
var pulseAlgorithm = true;
var pulseScale     = 8;
var pulseNormalize = 1;

// Keyboard Settings
var keyboardsupport = true;
var disableKeyboard = false;
var arrowscroll     = 50; // [px]

// Excluded pages
var exclude = "";

// Other Variables
var scrolls;
var deltaX = 0;
var deltaY = 0;
var direction = "down";
var initdone  = false;
var activeElement;

var key = { up: 38, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36 };

/***********************************************
 * SETTINGS
 ***********************************************/

chrome.extension.connect({ name: "smoothscroll" }).
onMessage.addListener(function (settings) {

    // NOTE: + converts to {Number}
    framerate = Math.max(+settings.framerate, 250);
    animtime  = +settings.animtime;
    stepsize  = +settings.scrollsz;
    exclude   = settings.exclude;
    pulseAlgorithm  = (settings.pulseAlgorithm == "true");
    pulseScale      = +settings.pulseScale;
    keyboardsupport = (settings.keyboardsupport == "true");
    arrowscroll     = +settings.arrscroll;

    scrolls = setupScrolls();
    computePulseScale();

    // it seems that sometimes settings come late
    // and we need to test again for excluded pages
    initTest();

    if (keyboardsupport && !disableKeyboard) {
        addEvent("keydown", keydown);
    }

    // If extension settings were deleted somehow
    if (!framerate) {
        alert("SmoothScroll: Please restart Chrome");
    }
});

/***********************************************
 * INITIALIZE
 ***********************************************/

/**
 * Tests if smooth scrolling is allowed. Shuts down everything if not.
 */
function initTest() {

    // disable keys for google reader (spacebar conflict)
    if (document.URL.indexOf("google.com/reader/view") > -1) {
        disableKeyboard = true;
    }

    // disable everything if the page is blacklisted
    if (exclude) {
        var domains = exclude.split(/[,\n] ?/);
        for (var i = domains.length; i--;) {
            if (document.URL.indexOf(domains[i]) > -1) {
                removeEvent("mousewheel", wheel);
                disableKeyboard = true;
                break;
            }
        }
    }

    // disable keyboard support if anything above requested it
    if (disableKeyboard) {
        removeEvent("keydown", keydown);
    }
}

/**
 * Fills up the scrolls array with easing values.
 * Uses pulse to make it smooth.
 */
function setupScrolls() {

    scrolls = [];

    var last = 0;
    var frames = Math.floor(framerate * animtime / 1000);

    for (var i = 0; i < frames; i++) {
        // scroll is [0, 1]
        var scroll = (i + 1) / frames;
        // transform [0, 1] -> [0, 1]:
        if (pulseAlgorithm) {
           scroll = pulse(scroll);
        }

        // scale and quantize to int so our pixel difference works:
        var iscroll = Math.floor(stepsize * scroll + 0.99);
        scrolls.push(iscroll - last);
        last = iscroll;
    }

    return scrolls;
}

/**
 * Sets up scrolls array, determines if frames are involved.
 */
function init() {

    var body  = document.body;
    var docel = document.documentElement;
    var htmlHeight   = docel.offsetHeight;
    var windowHeight = window.innerHeight;

    activeElement = body;

    initTest();

    if (!scrolls) {
      scrolls = setupScrolls();
    }

    // Checks if this script is running in a frame
    if (top != self) {
        frame = true;
        if (docel.scrollHeight <= docel.clientHeight + 10) {
            noscrollframe = true;
        }
    }

    /**
     * This fixes a bug where the areas left and right to
     * the content does not trigger the onmousewheel event
     * on some pages. e.g.: html, body { height: 100% }
     */
    else if (body.scrollHeight > windowHeight &&
            (body.offsetHeight === windowHeight || htmlHeight === windowHeight)) {

        var underlay = document.createElement("div");
        underlay.setAttribute( "style",
            "z-index: -1; position: absolute; top: 0; left: 0; " +
            "width: 100%; height: " + body.scrollHeight + "px;" );
        body.appendChild(underlay);

        var scrollHeight = body.scrollHeight;
        var pending = false;

        // DOMChange delayed
        var refresh = function() {
            if (!pending && scrollHeight != body.scrollHeight) {
                pending = true; // add a new pending action
                setTimeout(function(){
                    underlay.style.height = body.scrollHeight + "px";
                    scrollHeight = body.scrollHeight;
                    pending = false;
                }, 1000); // act rarely to stay fast
            }
        }

        addEvent("DOMNodeInserted", refresh);
        addEvent("DOMNodeRemoved",  refresh);
    }
    initdone = true;
}

/************************************************
 * SCROLLING
 ************************************************/

var que = []; // Array of offsets [x, y]
var x = 0, y = 1; // {enum}
var pending = false;
var last;

/**
 * Pushes scroll actions to a given direction Array.
 */
function scrollArray(elem, dir, multiplyX, multiplyY, delay) {

    delay || (delay = 1000);
    directionCheck(dir);

    for (var i = 0; i < scrolls.length; i++) {
        que[i] || (que[i] = [0, 0]);
        que[i][x] += multiplyX * scrolls[i];
        que[i][y] += multiplyY * scrolls[i];
    }

    function step() {

        var scroll = que.shift();

        var elapsed = +new Date - last;
        var percent = (elapsed / delay);
        if (percent)
            percent = Math.max(percent - 1, 1);
        var next = que[0] || [0,0];

        var addX = scroll[x] + next[y] * percent >> 0; // toInt
        var addY = scroll[y] + next[y] * percent >> 0; // toInt

        next[x] *=  (1 - percent);
        next[y] *=  (1 - percent);

        // scroll left
        if (multiplyX && addX) {
            var lastLeft = elem.scrollLeft;
            elem.scrollLeft += addX;

            // scroll left failed (edge)
            if (elem.scrollLeft === lastLeft) {
                multiplyX = 0;
            }
        }

        // scroll top
        if (multiplyY && addY) {
            var lastTop = elem.scrollTop;
            elem.scrollTop += addY;

            // scroll top failed (edge)
            if (elem.scrollTop === lastTop) {
                multiplyY = 0;
            }
        }

        // clean up if there's nothing left to do
        if (!multiplyX && !multiplyY) {
            que = [];
        }

        if (que.length) {
            last = +new Date;
            setTimeout(step, delay / framerate + 1);
        } else {
            pending = false;
            last = 0;
        }
    }

    // start a new que of actions
    if (!pending) {
        last = +new Date;
        setTimeout(step, 0);
        pending = true;
    }
}

/***********************************************
 * EVENTS
 ***********************************************/

/**
 * Mouse wheel handler.
 * NOTE: function logic should be decomposed.
 * @param {Object} event
 */
function wheel(event) {

    if (!initdone) {
        init();
    }

    var target = event.target;

    // use default if there's no overflowing
    // element or default action is prevented
    var elem = overflowingAncestor(target);
    if (!elem || noscrollframe || event.defaultPrevented ||
        isNodeName(activeElement, "embed") ||
       (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) {
        return true;
    }

    deltaX = event.wheelDeltaX || 0;
    deltaY = event.wheelDeltaY || 0;

    // normalize deltas
    // synaptics seems to send 1 sometimes,
    // and 120 other times (fix)
    if (Math.abs(deltaX) > 1.2) {
        deltaX /= 120;
    }
    if (Math.abs(deltaY) > 1.2) {
        deltaY /= 120;
    }

    var dir = (deltaY > 0) ? "up" : "down";
    scrollArray(elem, dir, -deltaX, -deltaY);
    event.preventDefault();
}

/**
 * Keydown event handler.
 * @param {Object} event
 */
function keydown(event) {

    var target   = event.target;
    var modifier = event.ctrlKey || event.altKey || event.metaKey;

    // do nothing if user is editing text
    // or using a modifier key (except shift)
    if ( /input|textarea|embed/i.test(target.nodeName) ||
         target.isContentEditable ||
         event.defaultPrevented   ||
         modifier ) {
      return true;
    }
    // spacebar should trigger button press
    if (isNodeName(target, "button") &&
        event.keyCode === key.spacebar) {
      return true;
    }

    var scale, dir, shift;
    var elem = overflowingAncestor(activeElement);
    var clientHeight = elem.clientHeight;

    if (elem == document.body) {
        clientHeight = window.innerHeight;
    }

    switch (event.keyCode) {
        case key.up:
            scale = -arrowscroll;
            dir = "up";
            break;
        case key.down:
            scale = arrowscroll;
            dir = "down";
            break;
        case key.spacebar: // (+ shift)
            shift = event.shiftKey ? 1 : -1;
            scale = -shift * clientHeight * 0.9;
            dir = (shift > 0) ? "up" : "down";
            break;
        case key.pageup:
            scale = -clientHeight * 0.9;
            dir = "up";
            break;
        case key.pagedown:
            scale = clientHeight * 0.9;
            dir = "down";
            break;
        case key.home:
            scale = -elem.scrollTop;
            dir = "up";
            break;
        case key.end:
            var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
            scale = (damt > 0) ? damt+10 : 0;
            dir = "down";
            break;
        default:
            return true; // a key we don"t care about
    }
    scale /= stepsize;
    scrollArray(elem, dir, 0, scale);
    event.preventDefault();
}

/**
 * Mousedown event only for updating activeElement
 */
function mousedown(event) {
    activeElement = event.target;
}

/***********************************************
 * HELPERS
 ***********************************************/

function addEvent(type, fn, bubble) {
    window.addEventListener(type, fn, (bubble||false));
}

function removeEvent(type, fn, bubble) {
    window.removeEventListener(type, fn, (bubble||false));
}

function isNodeName(el, tag) {
    return el.nodeName.toLowerCase() === tag.toLowerCase();
}

function directionCheck(dir) {
    if (direction !== dir) {
        que = [];
        direction = dir;
    }
}

function overflowingAncestor(el) {
    var bodyScrollHeight = document.body.scrollHeight;
    do {
        if (bodyScrollHeight === el.scrollHeight) {
            return document.body;
        }
        else if (el.clientHeight + 10 < el.scrollHeight) {
            overflow = getComputedStyle(el, "").getPropertyValue("overflow");
            if (overflow === "scroll" || overflow === "auto") {
                return el;
            }
        }
    } while (el = el.parentNode);
}

/***********************************************
 * PULSE
 ***********************************************/

/**
 * Viscous fluid with a pulse for part and decay for the rest.
 * - Applies a fixed force over an interval (a damped acceleration), and
 * - Lets the exponential bleed away the velocity over a longer interval
 * - Michael Herf, http://stereopsis.com/stopping/
 */
function pulse_(x) {
    var val, start, expx;
    // test
    x = x * pulseScale;
    if (x < 1) { // acceleartion
        val = x - (1 - Math.exp(-x));
    } else {     // tail
        // the previous animation ended here:
        start = Math.exp(-1);
        // simple viscous drag
        x -= 1;
        expx = 1 - Math.exp(-x);
        val = start + (expx * (1 - start));
    }
    return val * pulseNormalize;
}

function computePulseScale() {
    pulseNormalize = 1 / pulse_(1);
}

/**
 * Viscous fluid with a pulse for part and decay for the rest
 */
function pulse(x) {
    if (x >= 1) return 1;
    if (x <= 0) return 0;

    if (pulseNormalize == 1) {
        computePulseScale();
    }
    return pulse_(x);
}

addEvent("mousedown", mousedown);
addEvent("mousewheel", wheel);
addEvent("DOMContentLoaded", init);
<|endoftext|>


<commit_before>exports.config = {
    //
    // ====================
    // Runner Configuration
    // ====================
    //
    // WebdriverIO allows it to run your tests in arbitrary locations (e.g. locally or
    // on a remote machine).
    runner: 'local',
    //
    // =================
    // Service Providers
    // =================
    // WebdriverIO supports Sauce Labs, Browserstack, Testing Bot and LambdaTest (other cloud providers
    // should work too though). These services define specific user and key (or access key)
    // values you need to put in here in order to connect to these services.
    //
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    //
    // If you run your tests on Sauce Labs you can specify the region you want to run your tests
    // in via the `region` property. Available short handles for regions are `us` (default) and `eu`.
    // These regions are used for the Sauce Labs VM cloud and the Sauce Labs Real Device Cloud.
    // If you don't provide the region it will default for the `us`
    region: 'us',
    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the directory
    // from which `wdio` was called. Notice that, if you are calling `wdio` from an
    // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
    // directory is where your package.json resides, so `wdio` will be called from there.
    //
    specs: ['./test/wdio/**/*.js'],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
    // time. Depending on the number of capabilities, WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude options in
    // order to group specific specs to a specific capability.
    //
    // First, you can define how many instances should be started at the same time. Let's
    // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
    // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
    // files and you set maxInstances to 10, all spec files will get tested at the same time
    // and 30 processes will get spawned. The property handles how many capabilities
    // from the same test should run tests.
    //
    maxInstances: 10,
    //
    // If you have trouble getting all important capabilities together, check out the
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: [
        {
            browserName: 'chrome',
            platformName: 'Windows 10',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: '18.17763',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: '17.17134',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: '16.16299',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'firefox',
            platformName: 'Windows 10',
            browserVersion: '65.0',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'firefox',
            platformName: 'Windows 10',
            browserVersion: '62.0',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'firefox',
            platformName: 'Windows 10',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'safari',
            platformName: 'macOS 10.15',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
    ],
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // Level of logging verbosity: trace | debug | info | warn | error | silent
    logLevel: 'info',
    //
    // Set specific log levels per logger
    // loggers:
    // - webdriver, webdriverio
    // - @wdio/applitools-service, @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
    // - @wdio/mocha-framework, @wdio/jasmine-framework
    // - @wdio/local-runner
    // - @wdio/sumologic-reporter
    // - @wdio/cli, @wdio/config, @wdio/sync, @wdio/utils
    // Level of logging verbosity: trace | debug | info | warn | error | silent
    // logLevels: {
    //     webdriver: 'info',
    //     '@wdio/applitools-service': 'info'
    // },
    //
    // If you only want to run your tests until a specific amount of tests have failed use
    // bail (default is 0 - don't bail, run all tests).
    bail: 0,
    //
    // Set a base URL in order to shorten url command calls. If your `url` parameter starts
    // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
    // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
    // gets prepended directly.
    baseUrl: 'http://localhost:4000',
    //
    // Default timeout for all waitFor* commands.
    waitforTimeout: 10000,
    //
    // Default timeout in milliseconds for request
    // if browser driver or grid doesn't send response
    connectionRetryTimeout: 120000,
    //
    // Default request retries count
    connectionRetryCount: 3,
    //
    // Test runner services
    // Services take over a specific job you don't want to take care of. They enhance
    // your test setup with almost no effort. Unlike plugins, they don't add new
    // commands. Instead, they hook themselves up into the test process.
    services: [
        [
            'sauce',
            {
                sauceConnect: true,
            },
        ],
    ],

    // Framework you want to run your specs with.
    // The following are supported: Mocha, Jasmine, and Cucumber
    // see also: https://webdriver.io/docs/frameworks.html
    //
    // Make sure you have the wdio adapter package for the specific framework installed
    // before running any tests.
    framework: 'mocha',
    //
    // The number of times to retry the entire specfile when it fails as a whole
    // specFileRetries: 1,
    //
    // Delay in seconds between the spec file retry attempts
    // specFileRetriesDelay: 0,
    //
    // Whether or not retried specfiles should be retried immediately or deferred to the end of the queue
    // specFileRetriesDeferred: false,
    //
    // Test reporter for stdout.
    // The only one supported by default is 'dot'
    // see also: https://webdriver.io/docs/dot-reporter.html
    reporters: ['spec'],

    //
    // Options to be passed to Mocha.
    // See the full list at http://mochajs.org/
    mochaOpts: {
        ui: 'bdd',
        timeout: 60000,
    },
    //
    // =====
    // Hooks
    // =====
    // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
    // it and to build services around it. You can either apply a single function or an array of
    // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
    // resolved to continue.
    /**
     * Gets executed once before all workers get launched.
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     */
    // onPrepare: function (config, capabilities) {
    // },
    /**
     * Gets executed before a worker process is spawned and can be used to initialise specific service
     * for that worker as well as modify runtime environments in an async fashion.
     * @param  {String} cid      capability id (e.g 0-0)
     * @param  {[type]} caps     object containing capabilities for session that will be spawn in the worker
     * @param  {[type]} specs    specs to be run in the worker process
     * @param  {[type]} args     object that will be merged with the main configuration once worker is initialised
     * @param  {[type]} execArgv list of string arguments passed to the worker process
     */
    // onWorkerStart: function (cid, caps, specs, args, execArgv) {
    // },
    /**
     * Gets executed just before initialising the webdriver session and test framework. It allows you
     * to manipulate configurations depending on the capability or spec.
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that are to be run
     */
    // beforeSession: function (config, capabilities, specs) {
    // },
    /**
     * Gets executed before test execution begins. At this point you can access to all global
     * variables like `browser`. It is the perfect place to define custom commands.
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that are to be run
     */
    // before: function (capabilities, specs) {
    // },
    /**
     * Runs before a WebdriverIO command gets executed.
     * @param {String} commandName hook command name
     * @param {Array} args arguments that command would receive
     */
    // beforeCommand: function (commandName, args) {
    // },
    /**
     * Hook that gets executed before the suite starts
     * @param {Object} suite suite details
     */
    // beforeSuite: function (suite) {
    // },
    /**
     * Function to be executed before a test (in Mocha/Jasmine) starts.
     */
    // beforeTest: function (test, context) {
    // },
    /**
     * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
     * beforeEach in Mocha)
     */
    // beforeHook: function (test, context) {
    // },
    /**
     * Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
     * afterEach in Mocha)
     */
    // afterHook: function (test, context, { error, result, duration, passed, retries }) {
    // },
    /**
     * Function to be executed after a test (in Mocha/Jasmine).
     */
    // afterTest: function(test, context, { error, result, duration, passed, retries }) {
    // },

    /**
     * Hook that gets executed after the suite has ended
     * @param {Object} suite suite details
     */
    // afterSuite: function (suite) {
    // },
    /**
     * Runs after a WebdriverIO command gets executed
     * @param {String} commandName hook command name
     * @param {Array} args arguments that command would receive
     * @param {Number} result 0 - command success, 1 - command error
     * @param {Object} error error object if any
     */
    // afterCommand: function (commandName, args, result, error) {
    // },
    /**
     * Gets executed after all tests are done. You still have access to all global variables from
     * the test.
     * @param {Number} result 0 - test pass, 1 - test fail
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that ran
     */
    // after: function (result, capabilities, specs) {
    // },
    /**
     * Gets executed right after terminating the webdriver session.
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that ran
     */
    // afterSession: function (config, capabilities, specs) {
    // },
    /**
     * Gets executed after all workers got shut down and the process is about to exit. An error
     * thrown in the onComplete hook will result in the test run failing.
     * @param {Object} exitCode 0 - success, 1 - fail
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {<Object>} results object containing test results
     */
    // onComplete: function(exitCode, config, capabilities, results) {
    // },
    /**
     * Gets executed when a refresh happens.
     * @param {String} oldSessionId session ID of the old session
     * @param {String} newSessionId session ID of the new session
     */
    //onReload: function(oldSessionId, newSessionId) {
    //}
};
<commit_msg>feat(tool): IE11 E2E<commit_after>exports.config = {
    //
    // ====================
    // Runner Configuration
    // ====================
    //
    // WebdriverIO allows it to run your tests in arbitrary locations (e.g. locally or
    // on a remote machine).
    runner: 'local',
    //
    // =================
    // Service Providers
    // =================
    // WebdriverIO supports Sauce Labs, Browserstack, Testing Bot and LambdaTest (other cloud providers
    // should work too though). These services define specific user and key (or access key)
    // values you need to put in here in order to connect to these services.
    //
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    //
    // If you run your tests on Sauce Labs you can specify the region you want to run your tests
    // in via the `region` property. Available short handles for regions are `us` (default) and `eu`.
    // These regions are used for the Sauce Labs VM cloud and the Sauce Labs Real Device Cloud.
    // If you don't provide the region it will default for the `us`
    region: 'us',
    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the directory
    // from which `wdio` was called. Notice that, if you are calling `wdio` from an
    // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
    // directory is where your package.json resides, so `wdio` will be called from there.
    //
    specs: ['./test/wdio/**/*.js'],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
    // time. Depending on the number of capabilities, WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude options in
    // order to group specific specs to a specific capability.
    //
    // First, you can define how many instances should be started at the same time. Let's
    // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
    // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
    // files and you set maxInstances to 10, all spec files will get tested at the same time
    // and 30 processes will get spawned. The property handles how many capabilities
    // from the same test should run tests.
    //
    maxInstances: 10,
    //
    // If you have trouble getting all important capabilities together, check out the
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: [
        {
            browserName: 'chrome',
            platformName: 'Windows 10',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: '18.17763',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: '17.17134',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: '16.16299',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'MicrosoftEdge',
            platformName: 'Windows 10',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'internet explorer',
            platformName: 'Windows 10',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'firefox',
            platformName: 'Windows 10',
            browserVersion: '65.0',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'firefox',
            platformName: 'Windows 10',
            browserVersion: '62.0',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'firefox',
            platformName: 'Windows 10',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
        {
            browserName: 'safari',
            platformName: 'macOS 10.15',
            browserVersion: 'latest',
            maxInstances: 1,
            'sauce:options': {
                build: `Build ${Math.ceil(Date.now() / 1000)}`,
                public: 'public',
            },
        },
    ],
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // Level of logging verbosity: trace | debug | info | warn | error | silent
    logLevel: 'info',
    //
    // Set specific log levels per logger
    // loggers:
    // - webdriver, webdriverio
    // - @wdio/applitools-service, @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
    // - @wdio/mocha-framework, @wdio/jasmine-framework
    // - @wdio/local-runner
    // - @wdio/sumologic-reporter
    // - @wdio/cli, @wdio/config, @wdio/sync, @wdio/utils
    // Level of logging verbosity: trace | debug | info | warn | error | silent
    // logLevels: {
    //     webdriver: 'info',
    //     '@wdio/applitools-service': 'info'
    // },
    //
    // If you only want to run your tests until a specific amount of tests have failed use
    // bail (default is 0 - don't bail, run all tests).
    bail: 0,
    //
    // Set a base URL in order to shorten url command calls. If your `url` parameter starts
    // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
    // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
    // gets prepended directly.
    baseUrl: 'http://localhost:4000',
    //
    // Default timeout for all waitFor* commands.
    waitforTimeout: 10000,
    //
    // Default timeout in milliseconds for request
    // if browser driver or grid doesn't send response
    connectionRetryTimeout: 120000,
    //
    // Default request retries count
    connectionRetryCount: 3,
    //
    // Test runner services
    // Services take over a specific job you don't want to take care of. They enhance
    // your test setup with almost no effort. Unlike plugins, they don't add new
    // commands. Instead, they hook themselves up into the test process.
    services: [
        [
            'sauce',
            {
                sauceConnect: true,
            },
        ],
    ],

    // Framework you want to run your specs with.
    // The following are supported: Mocha, Jasmine, and Cucumber
    // see also: https://webdriver.io/docs/frameworks.html
    //
    // Make sure you have the wdio adapter package for the specific framework installed
    // before running any tests.
    framework: 'mocha',
    //
    // The number of times to retry the entire specfile when it fails as a whole
    // specFileRetries: 1,
    //
    // Delay in seconds between the spec file retry attempts
    // specFileRetriesDelay: 0,
    //
    // Whether or not retried specfiles should be retried immediately or deferred to the end of the queue
    // specFileRetriesDeferred: false,
    //
    // Test reporter for stdout.
    // The only one supported by default is 'dot'
    // see also: https://webdriver.io/docs/dot-reporter.html
    reporters: ['spec'],

    //
    // Options to be passed to Mocha.
    // See the full list at http://mochajs.org/
    mochaOpts: {
        ui: 'bdd',
        timeout: 60000,
    },
    //
    // =====
    // Hooks
    // =====
    // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
    // it and to build services around it. You can either apply a single function or an array of
    // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
    // resolved to continue.
    /**
     * Gets executed once before all workers get launched.
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     */
    // onPrepare: function (config, capabilities) {
    // },
    /**
     * Gets executed before a worker process is spawned and can be used to initialise specific service
     * for that worker as well as modify runtime environments in an async fashion.
     * @param  {String} cid      capability id (e.g 0-0)
     * @param  {[type]} caps     object containing capabilities for session that will be spawn in the worker
     * @param  {[type]} specs    specs to be run in the worker process
     * @param  {[type]} args     object that will be merged with the main configuration once worker is initialised
     * @param  {[type]} execArgv list of string arguments passed to the worker process
     */
    // onWorkerStart: function (cid, caps, specs, args, execArgv) {
    // },
    /**
     * Gets executed just before initialising the webdriver session and test framework. It allows you
     * to manipulate configurations depending on the capability or spec.
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that are to be run
     */
    // beforeSession: function (config, capabilities, specs) {
    // },
    /**
     * Gets executed before test execution begins. At this point you can access to all global
     * variables like `browser`. It is the perfect place to define custom commands.
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that are to be run
     */
    // before: function (capabilities, specs) {
    // },
    /**
     * Runs before a WebdriverIO command gets executed.
     * @param {String} commandName hook command name
     * @param {Array} args arguments that command would receive
     */
    // beforeCommand: function (commandName, args) {
    // },
    /**
     * Hook that gets executed before the suite starts
     * @param {Object} suite suite details
     */
    // beforeSuite: function (suite) {
    // },
    /**
     * Function to be executed before a test (in Mocha/Jasmine) starts.
     */
    // beforeTest: function (test, context) {
    // },
    /**
     * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
     * beforeEach in Mocha)
     */
    // beforeHook: function (test, context) {
    // },
    /**
     * Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
     * afterEach in Mocha)
     */
    // afterHook: function (test, context, { error, result, duration, passed, retries }) {
    // },
    /**
     * Function to be executed after a test (in Mocha/Jasmine).
     */
    // afterTest: function(test, context, { error, result, duration, passed, retries }) {
    // },

    /**
     * Hook that gets executed after the suite has ended
     * @param {Object} suite suite details
     */
    // afterSuite: function (suite) {
    // },
    /**
     * Runs after a WebdriverIO command gets executed
     * @param {String} commandName hook command name
     * @param {Array} args arguments that command would receive
     * @param {Number} result 0 - command success, 1 - command error
     * @param {Object} error error object if any
     */
    // afterCommand: function (commandName, args, result, error) {
    // },
    /**
     * Gets executed after all tests are done. You still have access to all global variables from
     * the test.
     * @param {Number} result 0 - test pass, 1 - test fail
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that ran
     */
    // after: function (result, capabilities, specs) {
    // },
    /**
     * Gets executed right after terminating the webdriver session.
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that ran
     */
    // afterSession: function (config, capabilities, specs) {
    // },
    /**
     * Gets executed after all workers got shut down and the process is about to exit. An error
     * thrown in the onComplete hook will result in the test run failing.
     * @param {Object} exitCode 0 - success, 1 - fail
     * @param {Object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {<Object>} results object containing test results
     */
    // onComplete: function(exitCode, config, capabilities, results) {
    // },
    /**
     * Gets executed when a refresh happens.
     * @param {String} oldSessionId session ID of the old session
     * @param {String} newSessionId session ID of the new session
     */
    //onReload: function(oldSessionId, newSessionId) {
    //}
};
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react'
import {Link} from 'react-router'
import _ from 'lodash'

import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized'

import {KAPACITOR_RULES_TABLE} from 'src/kapacitor/constants/tableSizing'
const {
  colName,
  colTrigger,
  colMessage,
  colAlerts,
  colEnabled,
  colActions,
} = KAPACITOR_RULES_TABLE

const KapacitorRulesTable = ({rules, source, onDelete, onChangeRuleStatus}) =>

          Name
          Rule Trigger
          Message
          Alerts

            Enabled

        {_.sortBy(rules, r => r.name.toLowerCase()).map(rule => {
          return (
            <RuleRow
              key={rule.id}
              rule={rule}
              source={source}
              onDelete={onDelete}
              onChangeRuleStatus={onChangeRuleStatus}
            />
          )
        })}

const handleDelete = (rule, onDelete) => onDelete(rule)

const RuleRow = ({rule, source, onDelete, onChangeRuleStatus}) =>

      <RuleTitle rule={rule} source={source} />

      {rule.trigger}

        {rule.message}

      {rule.alerts.join(', ')}

        <input
          id={`kapacitor-enabled ${rule.id}`}
          className="form-control-static"
          type="checkbox"
          defaultChecked={rule.status === 'enabled'}
          onClick={onChangeRuleStatus(rule)}
        />
        <label htmlFor={`kapacitor-enabled ${rule.id}`} />

      <Authorized requiredRole={EDITOR_ROLE}>
        <Link
          className="btn btn-info btn-xs"
          to={`/sources/${source.id}/tickscript/${rule.id}`}
        >
          Edit TICKscript
        </Link>
      </Authorized>
      <Authorized requiredRole={EDITOR_ROLE}>
        <button
          className="btn btn-danger btn-xs"
          onClick={handleDelete(rule, onDelete)}
        >
          Delete
        </button>
      </Authorized>

const RuleTitle = ({rule: {id, name, query}, source}) => {
  // no queryConfig means the rule was manually created outside of Chronograf
  if (!query) {
    return (

        {name}

    )
  }

  return (
    <Link to={`/sources/${source.id}/alert-rules/${id}`}>
      {name}
    </Link>
  )
}

const {arrayOf, func, shape, string} = PropTypes

KapacitorRulesTable.propTypes = {
  rules: arrayOf(shape()),
  onChangeRuleStatus: func,
  onDelete: func,
  source: shape({
    id: string.isRequired,
  }).isRequired,
}

RuleRow.propTypes = {
  rule: shape(),
  source: shape(),
  onChangeRuleStatus: func,
  onDelete: func,
}

RuleTitle.propTypes = {
  rule: shape({
    name: string.isRequired,
    query: shape(),
    links: shape({
      self: string.isRequired,
    }),
  }),
  source: shape({
    id: string.isRequired,
  }).isRequired,
}

export default KapacitorRulesTable
<commit_msg>Render link to Rule Builder based on user authorization<commit_after>import React, {PropTypes} from 'react'
import {Link} from 'react-router'
import _ from 'lodash'

import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized'

import {KAPACITOR_RULES_TABLE} from 'src/kapacitor/constants/tableSizing'
const {
  colName,
  colTrigger,
  colMessage,
  colAlerts,
  colEnabled,
  colActions,
} = KAPACITOR_RULES_TABLE

const KapacitorRulesTable = ({rules, source, onDelete, onChangeRuleStatus}) =>

          Name
          Rule Trigger
          Message
          Alerts

            Enabled

        {_.sortBy(rules, r => r.name.toLowerCase()).map(rule => {
          return (
            <RuleRow
              key={rule.id}
              rule={rule}
              source={source}
              onDelete={onDelete}
              onChangeRuleStatus={onChangeRuleStatus}
            />
          )
        })}

const handleDelete = (rule, onDelete) => onDelete(rule)

const RuleRow = ({rule, source, onDelete, onChangeRuleStatus}) =>

      <RuleTitle rule={rule} source={source} />

      {rule.trigger}

        {rule.message}

      {rule.alerts.join(', ')}

        <input
          id={`kapacitor-enabled ${rule.id}`}
          className="form-control-static"
          type="checkbox"
          defaultChecked={rule.status === 'enabled'}
          onClick={onChangeRuleStatus(rule)}
        />
        <label htmlFor={`kapacitor-enabled ${rule.id}`} />

      <Authorized requiredRole={EDITOR_ROLE}>
        <Link
          className="btn btn-info btn-xs"
          to={`/sources/${source.id}/tickscript/${rule.id}`}
        >
          Edit TICKscript
        </Link>
      </Authorized>
      <Authorized requiredRole={EDITOR_ROLE}>
        <button
          className="btn btn-danger btn-xs"
          onClick={handleDelete(rule, onDelete)}
        >
          Delete
        </button>
      </Authorized>

const RuleTitle = ({rule: {id, name, query}, source}) => {
  // no queryConfig means the rule was manually created outside of Chronograf
  if (!query) {
    return (

        {name}

    )
  }

  return (
    <Authorized
      requiredRole={EDITOR_ROLE}
      replaceWith={

          {name}

      }
    >
      <Link to={`/sources/${source.id}/alert-rules/${id}`}>
        {name}
      </Link>
    </Authorized>
  )
}

const {arrayOf, func, shape, string} = PropTypes

KapacitorRulesTable.propTypes = {
  rules: arrayOf(shape()),
  onChangeRuleStatus: func,
  onDelete: func,
  source: shape({
    id: string.isRequired,
  }).isRequired,
}

RuleRow.propTypes = {
  rule: shape(),
  source: shape(),
  onChangeRuleStatus: func,
  onDelete: func,
}

RuleTitle.propTypes = {
  rule: shape({
    name: string.isRequired,
    query: shape(),
    links: shape({
      self: string.isRequired,
    }),
  }),
  source: shape({
    id: string.isRequired,
  }).isRequired,
}

export default KapacitorRulesTable
<|endoftext|>


<commit_before>var app = null;
var eventAggregator = new Vue();

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    } else {
        window.onload = function() {
            if (oldonload) {
                oldonload();
            }
            func();
        }
    }
}
addLoadEvent(function (ev) {
    Vue.use(Toasted);

    Vue.component('contribute', {
        props: ["targetCurrency", "active", "perks", "inModal"],
        template: "#contribute-template"
    });

    Vue.component('perks', {
        props: ["perks", "targetCurrency", "active", "inModal"],
        template: "#perks-template"
    });

    Vue.component('perk', {
        props: ["perk", "targetCurrency", "active", "inModal"],
        template: "#perk-template",
        data: function () {
            return {
                amount: null,
                expanded: false
            }
        },
        computed: {
            canExpand: function(){
                return !this.expanded && this.active && (this.perk.price.value || this.perk.custom)
            }
        },
        methods: {
            onContributeFormSubmit: function (e) {
                if (e) {
                    e.preventDefault();
                }
                if(!this.active){
                    return;
                }
                eventAggregator.$emit("contribute", {amount: this.amount, choiceKey: this.choiceKey});
            },
            expand: function(){
                if(this.canExpand){
                    this.expanded = true;
                }
            }

        },
        mounted: function(){
            this.amount = this.perk.price.value;

        }
    });

    app = new Vue({
        el: '#app',
        data: function(){
            return {
                srvModel: window.srvModel,
                connectionStatus: "",
                endDate: "",
                startDate: "",
                startDateRelativeTime: "",
                endDateRelativeTime: "",
                started: false,
                ended: false,
                contributeModalOpen: false,
                endDiff: "",
                startDiff: "",
                active: true,
                animation: true,
                sound: true,
                lastUpdated:""

            }
        },
        computed: {
            targetCurrency: function(){
                return this.srvModel.targetCurrency.toUpperCase();
            },
            paymentStats: function(){
                var result= [];

                var combinedStats = {};

                var keys = Object.keys(this.srvModel.info.paymentStats);

                for (var i = 0; i < keys.length; i++) {
                    if(combinedStats[keys[i]]){
                        combinedStats[keys[i]] +=this.srvModel.info.paymentStats[keys[i]];
                    }else{
                        combinedStats[keys[i]] =this.srvModel.info.paymentStats[keys[i]];
                    }
                }

                keys = Object.keys(this.srvModel.info.pendingPaymentStats);

                for (var i = 0; i < keys.length; i++) {
                    if(combinedStats[keys[i]]){
                        combinedStats[keys[i]] +=this.srvModel.info.pendingPaymentStats[keys[i]];
                    }else{
                        combinedStats[keys[i]] =this.srvModel.info.pendingPaymentStats[keys[i]];
                    }
                }

                keys = Object.keys(combinedStats);

                for (var i = 0; i < keys.length; i++) {
                    var newItem = {key:keys[i], value: combinedStats[keys[i]], label: keys[i].replace("_","")};
                    result.push(newItem);

                }
                for (var i = 0; i < result.length; i++) {
                    var current = result[i];
                    if(current.label.endsWith("LightningLike")){
                        current.label = current.label.substr(0,current.label.findIndex("LightningLike"));
                        current.lightning = true;
                    }
                }

                return result;
            },
            perks: function(){
                var result = [];
                for (var i = 0; i < this.srvModel.perks.length; i++) {
                    var currentPerk = this.srvModel.perks[i];
                    if(this.srvModel.perkCount.hasOwnProperty(currentPerk.id)){
                        currentPerk.sold = this.srvModel.perkCount[currentPerk.id];
                    }
                    result.push(currentPerk);
                }
                return result;
            }
        },
        methods: {
            updateComputed: function () {
                if (this.srvModel.endDate) {
                    var endDateM = moment(this.srvModel.endDate);
                    this.endDate = endDateM.format('MMMM Do YYYY');
                    this.endDateRelativeTime = endDateM.fromNow();
                    this.ended = endDateM.isBefore(moment());

                }else{
                    this.ended = false;
                }

                if (this.srvModel.startDate) {
                    var startDateM = moment(this.srvModel.startDate);
                    this.startDate = startDateM.format('MMMM Do YYYY');
                    this.startDateRelativeTime = startDateM.fromNow();
                    this.started = startDateM.isBefore(moment());
                }else{
                    this.started = true;
                }
                if(this.started && !this.ended && this.srvModel.endDate){
                    var mDiffD =  moment(this.srvModel.endDate).diff(moment(), "days");
                    var mDiffH =  moment(this.srvModel.endDate).diff(moment(), "hours");
                    var mDiffM =  moment(this.srvModel.endDate).diff(moment(), "minutes");
                    var mDiffS =  moment(this.srvModel.endDate).diff(moment(), "seconds");
                    this.endDiff =  mDiffD > 0? mDiffD + " Days" : mDiffH> 0? mDiffH + " Hours" : mDiffM> 0? mDiffM+ " Minutes" : mDiffS> 0? mDiffS + " Seconds": "";
                }
                if(!this.started && this.srvModel.startDate){
                    var mDiffD =  moment(this.srvModel.startDate).diff(moment(), "days");
                    var mDiffH =  moment(this.srvModel.startDate).diff(moment(), "hours");
                    var mDiffM =  moment(this.srvModel.startDate).diff(moment(), "minutes");
                    var mDiffS =  moment(this.srvModel.startDate).diff(moment(), "seconds");
                    this.startDiff =  mDiffD > 0? mDiffD + " Days" : mDiffH> 0? mDiffH + " Hours" : mDiffM> 0? mDiffM+ " Minutes" : mDiffS> 0? mDiffS + " Seconds": "";
                }
                this.lastUpdated = moment(this.srvModel.info.lastUpdated).calendar();
                this.active = this.started && !this.ended;
                setTimeout(this.updateComputed, 1000);
            },
            submitModalContribute: function(e){
                debugger;
                this.$refs.modalContribute.onContributeFormSubmit(e);
            }
        },
        mounted: function () {
            hubListener.connect();
            var self = this;
            this.sound = this.srvModel.soundsEnabled;
            this.animation = this.srvModel.animationsEnabled;
            eventAggregator.$on("invoice-created", function (invoiceId) {
                btcpay.setApiUrlPrefix(window.location.origin);
                btcpay.showInvoice(invoiceId);
                btcpay.showFrame();

                self.contributeModalOpen = false;
            });
            eventAggregator.$on("invoice-error", function(error){
                var msg = "";
                if(typeof error === "string"){
                    msg = error;
                }else if(!error){
                    msg = "Unknown Error";
                }else{
                    msg = JSON.stringify(error);
                }

                Vue.toasted.show("Error creating invoice: " + msg, {
                    iconPack: "fontawesome",
                    icon: "exclamation-triangle",
                    fullWidth: false,
                    theme: "bubble",
                    type: "error",
                    position: "top-center",
                    duration: 10000
                } );
            });
            eventAggregator.$on("payment-received", function (amount, cryptoCode, type) {
                var onChain = type.toLowerCase() === "btclike";
                if(self.sound) {
                    playRandomQuakeSound();
                }
                if(self.animation) {
                    fireworks();
                }
                if(onChain){
                    Vue.toasted.show('New payment of ' + amount+ " "+ cryptoCode + " " + (onChain? "On Chain": "LN "), {
                        iconPack: "fontawesome",
                        icon: "plus",
                        duration: 10000
                    } );
                }else{
                    Vue.toasted.show('New payment of ' + amount+ " "+ cryptoCode + " " + (onChain? "On Chain": "LN "), {
                        iconPack: "fontawesome",
                        icon: "bolt",
                        duration: 10000
                    } );
                }

            });
            if(srvModel.disqusEnabled){
                window.disqus_config = function () {
                    // Replace PAGE_URL with your page's canonical URL variable
                    this.page.url = window.location.href;

                    // Replace PAGE_IDENTIFIER with your page's unique identifier variable
                    this.page.identifier = self.srvModel.appId;
                };

                (function() {  // REQUIRED CONFIGURATION VARIABLE: EDIT THE SHORTNAME BELOW
                    var d = document, s = d.createElement('script');

                    // IMPORTANT: Replace EXAMPLE with your forum shortname!
                    s.src = "https://"+self.srvModel.disqusShortname+".disqus.com/embed.js";
                    s.async= true;
                    s.setAttribute('data-timestamp', +new Date());
                    (d.head || d.body).appendChild(s);

                    var s2 = d.createElement('script');
                    s2.src="//"+self.srvModel.disqusShortname+".disqus.com/count.js";
                    s2.async= true;
                    s.setAttribute('data-timestamp', +new Date());
                    (d.head || d.body).appendChild(s);
                })();
            }
            eventAggregator.$on("info-updated", function (model) {
                console.warn("UPDATED", self.srvModel, arguments);
                self.srvModel = model;
            });
            eventAggregator.$on("connection-pending", function () {
                self.connectionStatus = "pending";
            });
            eventAggregator.$on("connection-failed", function () {
                self.connectionStatus = "failed";
            });
            eventAggregator.$on("connection-lost", function () {
                self.connectionStatus = "connection lost";
            });
            this.updateComputed();
        }
    });
});

<commit_msg>oops<commit_after>var app = null;
var eventAggregator = new Vue();

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    } else {
        window.onload = function() {
            if (oldonload) {
                oldonload();
            }
            func();
        }
    }
}
addLoadEvent(function (ev) {
    Vue.use(Toasted);

    Vue.component('contribute', {
        props: ["targetCurrency", "active", "perks", "inModal"],
        template: "#contribute-template"
    });

    Vue.component('perks', {
        props: ["perks", "targetCurrency", "active", "inModal"],
        template: "#perks-template"
    });

    Vue.component('perk', {
        props: ["perk", "targetCurrency", "active", "inModal"],
        template: "#perk-template",
        data: function () {
            return {
                amount: null,
                expanded: false
            }
        },
        computed: {
            canExpand: function(){
                return !this.expanded && this.active && (this.perk.price.value || this.perk.custom)
            }
        },
        methods: {
            onContributeFormSubmit: function (e) {
                if (e) {
                    e.preventDefault();
                }
                if(!this.active){
                    return;
                }
                eventAggregator.$emit("contribute", {amount: this.amount, choiceKey: this.choiceKey});
            },
            expand: function(){
                if(this.canExpand){
                    this.expanded = true;
                }
            }

        },
        mounted: function(){
            this.amount = this.perk.price.value;

        }
    });

    app = new Vue({
        el: '#app',
        data: function(){
            return {
                srvModel: window.srvModel,
                connectionStatus: "",
                endDate: "",
                startDate: "",
                startDateRelativeTime: "",
                endDateRelativeTime: "",
                started: false,
                ended: false,
                contributeModalOpen: false,
                endDiff: "",
                startDiff: "",
                active: true,
                animation: true,
                sound: true,
                lastUpdated:""

            }
        },
        computed: {
            targetCurrency: function(){
                return this.srvModel.targetCurrency.toUpperCase();
            },
            paymentStats: function(){
                var result= [];

                var combinedStats = {};

                var keys = Object.keys(this.srvModel.info.paymentStats);

                for (var i = 0; i < keys.length; i++) {
                    if(combinedStats[keys[i]]){
                        combinedStats[keys[i]] +=this.srvModel.info.paymentStats[keys[i]];
                    }else{
                        combinedStats[keys[i]] =this.srvModel.info.paymentStats[keys[i]];
                    }
                }

                keys = Object.keys(this.srvModel.info.pendingPaymentStats);

                for (var i = 0; i < keys.length; i++) {
                    if(combinedStats[keys[i]]){
                        combinedStats[keys[i]] +=this.srvModel.info.pendingPaymentStats[keys[i]];
                    }else{
                        combinedStats[keys[i]] =this.srvModel.info.pendingPaymentStats[keys[i]];
                    }
                }

                keys = Object.keys(combinedStats);

                for (var i = 0; i < keys.length; i++) {
                    var newItem = {key:keys[i], value: combinedStats[keys[i]], label: keys[i].replace("_","")};
                    result.push(newItem);

                }
                for (var i = 0; i < result.length; i++) {
                    var current = result[i];
                    if(current.label.endsWith("LightningLike")){
                        current.label = current.label.substr(0,current.label.indexOf("LightningLike"));
                        current.lightning = true;
                    }
                }

                return result;
            },
            perks: function(){
                var result = [];
                for (var i = 0; i < this.srvModel.perks.length; i++) {
                    var currentPerk = this.srvModel.perks[i];
                    if(this.srvModel.perkCount.hasOwnProperty(currentPerk.id)){
                        currentPerk.sold = this.srvModel.perkCount[currentPerk.id];
                    }
                    result.push(currentPerk);
                }
                return result;
            }
        },
        methods: {
            updateComputed: function () {
                if (this.srvModel.endDate) {
                    var endDateM = moment(this.srvModel.endDate);
                    this.endDate = endDateM.format('MMMM Do YYYY');
                    this.endDateRelativeTime = endDateM.fromNow();
                    this.ended = endDateM.isBefore(moment());

                }else{
                    this.ended = false;
                }

                if (this.srvModel.startDate) {
                    var startDateM = moment(this.srvModel.startDate);
                    this.startDate = startDateM.format('MMMM Do YYYY');
                    this.startDateRelativeTime = startDateM.fromNow();
                    this.started = startDateM.isBefore(moment());
                }else{
                    this.started = true;
                }
                if(this.started && !this.ended && this.srvModel.endDate){
                    var mDiffD =  moment(this.srvModel.endDate).diff(moment(), "days");
                    var mDiffH =  moment(this.srvModel.endDate).diff(moment(), "hours");
                    var mDiffM =  moment(this.srvModel.endDate).diff(moment(), "minutes");
                    var mDiffS =  moment(this.srvModel.endDate).diff(moment(), "seconds");
                    this.endDiff =  mDiffD > 0? mDiffD + " Days" : mDiffH> 0? mDiffH + " Hours" : mDiffM> 0? mDiffM+ " Minutes" : mDiffS> 0? mDiffS + " Seconds": "";
                }
                if(!this.started && this.srvModel.startDate){
                    var mDiffD =  moment(this.srvModel.startDate).diff(moment(), "days");
                    var mDiffH =  moment(this.srvModel.startDate).diff(moment(), "hours");
                    var mDiffM =  moment(this.srvModel.startDate).diff(moment(), "minutes");
                    var mDiffS =  moment(this.srvModel.startDate).diff(moment(), "seconds");
                    this.startDiff =  mDiffD > 0? mDiffD + " Days" : mDiffH> 0? mDiffH + " Hours" : mDiffM> 0? mDiffM+ " Minutes" : mDiffS> 0? mDiffS + " Seconds": "";
                }
                this.lastUpdated = moment(this.srvModel.info.lastUpdated).calendar();
                this.active = this.started && !this.ended;
                setTimeout(this.updateComputed, 1000);
            },
            submitModalContribute: function(e){
                debugger;
                this.$refs.modalContribute.onContributeFormSubmit(e);
            }
        },
        mounted: function () {
            hubListener.connect();
            var self = this;
            this.sound = this.srvModel.soundsEnabled;
            this.animation = this.srvModel.animationsEnabled;
            eventAggregator.$on("invoice-created", function (invoiceId) {
                btcpay.setApiUrlPrefix(window.location.origin);
                btcpay.showInvoice(invoiceId);
                btcpay.showFrame();

                self.contributeModalOpen = false;
            });
            eventAggregator.$on("invoice-error", function(error){
                var msg = "";
                if(typeof error === "string"){
                    msg = error;
                }else if(!error){
                    msg = "Unknown Error";
                }else{
                    msg = JSON.stringify(error);
                }

                Vue.toasted.show("Error creating invoice: " + msg, {
                    iconPack: "fontawesome",
                    icon: "exclamation-triangle",
                    fullWidth: false,
                    theme: "bubble",
                    type: "error",
                    position: "top-center",
                    duration: 10000
                } );
            });
            eventAggregator.$on("payment-received", function (amount, cryptoCode, type) {
                var onChain = type.toLowerCase() === "btclike";
                if(self.sound) {
                    playRandomQuakeSound();
                }
                if(self.animation) {
                    fireworks();
                }
                if(onChain){
                    Vue.toasted.show('New payment of ' + amount+ " "+ cryptoCode + " " + (onChain? "On Chain": "LN "), {
                        iconPack: "fontawesome",
                        icon: "plus",
                        duration: 10000
                    } );
                }else{
                    Vue.toasted.show('New payment of ' + amount+ " "+ cryptoCode + " " + (onChain? "On Chain": "LN "), {
                        iconPack: "fontawesome",
                        icon: "bolt",
                        duration: 10000
                    } );
                }

            });
            if(srvModel.disqusEnabled){
                window.disqus_config = function () {
                    // Replace PAGE_URL with your page's canonical URL variable
                    this.page.url = window.location.href;

                    // Replace PAGE_IDENTIFIER with your page's unique identifier variable
                    this.page.identifier = self.srvModel.appId;
                };

                (function() {  // REQUIRED CONFIGURATION VARIABLE: EDIT THE SHORTNAME BELOW
                    var d = document, s = d.createElement('script');

                    // IMPORTANT: Replace EXAMPLE with your forum shortname!
                    s.src = "https://"+self.srvModel.disqusShortname+".disqus.com/embed.js";
                    s.async= true;
                    s.setAttribute('data-timestamp', +new Date());
                    (d.head || d.body).appendChild(s);

                    var s2 = d.createElement('script');
                    s2.src="//"+self.srvModel.disqusShortname+".disqus.com/count.js";
                    s2.async= true;
                    s.setAttribute('data-timestamp', +new Date());
                    (d.head || d.body).appendChild(s);
                })();
            }
            eventAggregator.$on("info-updated", function (model) {
                console.warn("UPDATED", self.srvModel, arguments);
                self.srvModel = model;
            });
            eventAggregator.$on("connection-pending", function () {
                self.connectionStatus = "pending";
            });
            eventAggregator.$on("connection-failed", function () {
                self.connectionStatus = "failed";
            });
            eventAggregator.$on("connection-lost", function () {
                self.connectionStatus = "connection lost";
            });
            this.updateComputed();
        }
    });
});

<|endoftext|>


<commit_before>define([
	"dojo/_base/declare", "dojo/_base/lang", "dojo/_base/Deferred",
	"dojo/on", "dojo/request", "dojo/dom-style", "dojo/aspect", "dojo/topic",
	"dijit/layout/BorderContainer", "dijit/layout/ContentPane",
	"dgrid/selector", "put-selector/put",
	"../store/ArrangeableMemoryStore", "./Grid", "./formatter"
], function(declare, lang, Deferred,
			on, request, domStyle, aspect, Topic,
			BorderContainer, ContentPane,
			selector, put,
			Store, Grid, formatter){

	var filterSelector = function(value, cell, object){
		var parent = cell.parentNode;

		// must set the class name on the outer cell in IE for keystrokes to be intercepted
		put(parent && parent.contents ? parent : cell, ".dgrid-selector");
		var input = cell.input || (cell.input = put(cell, 'i', {
				tabIndex: -1,
				checked: !!value
			}));
		input.setAttribute("class", value ? "fa fa-check-square-o" : "fa fa-square-o");
		input.setAttribute("aria-checked", !!value);
		return input;
	};

	var filterSelectorChecked = function(value, cell, object){
		return filterSelector(true, cell, object);
	};

	// create empty Memory Store
	var store = new Store({
		idProperty: "genome_id"
	});

	return declare([Grid], {
		region: "center",
		query: (this.query || ""),
		apiToken: window.App.authorizationToken,
		apiServer: window.App.dataServiceURL,
		store: store,
		pfState: null,
		dataModel: "genome",
		primaryKey: "genome_id",
		deselectOnRefresh: true,
		columns: {
			present: selector({label: '', field: 'present', selectorType: 'radio'}, filterSelector),
			absent: selector({label: '', field: 'absent', selectorType: 'radio'}, filterSelector),
			mixed: selector({label: '', field: 'mixed', selectorType: 'radio'}, filterSelectorChecked),
			genome_name: {label: 'Genome Name', field: 'genome_name'},
			genome_status: {label: 'Genome Status', field: 'genome_status'},
			isolation_country: {label: 'Isolation Country', field: 'isolation_country'},
			host_name: {label: 'Host', field: 'host_name'},
			disease: {label: 'Disease', field: 'disease'},
			collection_date: {label: 'Collection Date', field: 'collection_date'},
			completion_date: {label: 'Completion Date', field: 'completion_date', formatter: formatter.dateOnly}
		},
		constructor: function(options){
			if(options && options.state){
				this.state = options.state;
			}

			Topic.subscribe("ProteinFamilies", lang.hitch(this, function(){
				// console.log("ProteinFamiliesFilterGrid:", arguments);
				var key = arguments[0], value = arguments[1];

				switch(key){
					case "updatePfState":
						this.pfState = value;
						break;
					case "updateFilterGrid":
						this.store.setData(value);
						this.store._loaded = true;
						this.refresh();
						break;
					case "updateFilterGridOrder":
						this.set('sort', [{}]);
						this.store.arrange(value);
						this.refresh();
						break;
					default:
						break;
				}
			}));
		},
		startup: function(){
			var _self = this;
			var options = ['present', 'absent', 'mixed'];
			var toggleSelection = function(element, value){
				element.checked = value;
				element.setAttribute("class", value ? "fa fa-check-square-o" : "fa fa-square-o");
				element.setAttribute("aria-checked", value);
			};

			this.on(".dgrid-cell:click", lang.hitch(_self, function(evt){
				var cell = _self.cell(evt);
				var colId = cell.column.id;
				var columnHeaders = cell.column.grid.columns;

				var conditionIds = _self.pfState.genomeIds;
				var conditionStatus = _self.pfState.genomeFilterStatus;

				if(!cell.element.input) return;

				if(cell.row){
					// data row is clicked
					var rowId = cell.row.id;

					// deselect other radio in the same row
					options.forEach(function(el){
						if(el != colId && _self.cell(rowId, el).element.input.checked){
							toggleSelection(_self.cell(rowId, el).element.input, false);
						}
						// updated selected box
						if(el === colId){
							toggleSelection(_self.cell(rowId, el).element.input, true);
						}
					});

					// check whether entire rows are selected & mark as needed
					options.forEach(function(el){
						var allSelected = true;
						conditionIds.forEach(function(conditionId){
							if(_self.cell(conditionId, el).element.input.checked == false){
								allSelected = false;
							}
						});
						toggleSelection(columnHeaders[el].headerNode.firstChild.firstElementChild, allSelected);
					});

				}else{
					// if header is clicked, reset the selections & update
					conditionIds.forEach(function(conditionId){
						options.forEach(function(el){
							if(el === colId){
								toggleSelection(_self.cell(conditionId, el).element.input, true);
							}else{
								toggleSelection(_self.cell(conditionId, el).element.input, false);
							}
						});
					});

					// deselect other radio in the header
					options.forEach(function(el){
						if(el != colId && columnHeaders[el].headerNode.firstChild.firstElementChild.checked){
							toggleSelection(columnHeaders[el].headerNode.firstChild.firstElementChild, false);
						}
					});
				}

				// update filter
				Object.keys(conditionStatus).forEach(function(conditionId){
					var status = options.findIndex(function(el){
						if(_self.cell(conditionId, el).element.input.checked){
							return el;
						}
					});

					conditionStatus[conditionId].setStatus(status);
				});

				this.pfState.genomeFilterStatus = conditionStatus;
				Topic.publish("ProteinFamilies", "applyConditionFilter", this.pfState);
			}));

			aspect.before(_self, 'renderArray', function(results){
				Deferred.when(results.total, function(x){
					_self.set("totalRows", x);
				});
			});

			// this.inherited(arguments);
			this._started = true;

			// increase grid width after rendering content-pane
			domStyle.set(this.id, "width", "650px");
		},
		_setSort: function(sort){
			this.inherited(arguments);

			// console.log("old order", this.pfState.genomeIds);
			var newIds = [];
			this.store.query({}, {sort: sort}).forEach(function(genome){
					newIds.push(genome.genome_id);
			});
			this.pfState.clusterRowOrder = newIds;
			// console.log("new order", this.pfState.clusterRowOrder);

			Topic.publish("ProteinFamilies", "updatePfState", this.pfState);
			Topic.publish("ProteinFamilies", "refreshHeatmap");
		},
		state: null,
		postCreate: function(){
			this.inherited(arguments);
		},
		_setApiServer: function(server){
			this.apiServer = server;
		}
	});
});
<commit_msg>make variable name generic<commit_after>define([
	"dojo/_base/declare", "dojo/_base/lang", "dojo/_base/Deferred",
	"dojo/on", "dojo/request", "dojo/dom-style", "dojo/aspect", "dojo/topic",
	"dijit/layout/BorderContainer", "dijit/layout/ContentPane",
	"dgrid/selector", "put-selector/put",
	"../store/ArrangeableMemoryStore", "./Grid", "./formatter"
], function(declare, lang, Deferred,
			on, request, domStyle, aspect, Topic,
			BorderContainer, ContentPane,
			selector, put,
			Store, Grid, formatter){

	var filterSelector = function(value, cell, object){
		var parent = cell.parentNode;

		// must set the class name on the outer cell in IE for keystrokes to be intercepted
		put(parent && parent.contents ? parent : cell, ".dgrid-selector");
		var input = cell.input || (cell.input = put(cell, 'i', {
				tabIndex: -1,
				checked: !!value
			}));
		input.setAttribute("class", value ? "fa fa-check-square-o" : "fa fa-square-o");
		input.setAttribute("aria-checked", !!value);
		return input;
	};

	var filterSelectorChecked = function(value, cell, object){
		return filterSelector(true, cell, object);
	};

	// create empty Memory Store
	var store = new Store({
		idProperty: "genome_id"
	});

	return declare([Grid], {
		region: "center",
		query: (this.query || ""),
		apiToken: window.App.authorizationToken,
		apiServer: window.App.dataServiceURL,
		store: store,
		pfState: null,
		dataModel: "genome",
		primaryKey: "genome_id",
		deselectOnRefresh: true,
		columns: {
			present: selector({label: '', field: 'present', selectorType: 'radio'}, filterSelector),
			absent: selector({label: '', field: 'absent', selectorType: 'radio'}, filterSelector),
			mixed: selector({label: '', field: 'mixed', selectorType: 'radio'}, filterSelectorChecked),
			genome_name: {label: 'Genome Name', field: 'genome_name'},
			genome_status: {label: 'Genome Status', field: 'genome_status'},
			isolation_country: {label: 'Isolation Country', field: 'isolation_country'},
			host_name: {label: 'Host', field: 'host_name'},
			disease: {label: 'Disease', field: 'disease'},
			collection_date: {label: 'Collection Date', field: 'collection_date'},
			completion_date: {label: 'Completion Date', field: 'completion_date', formatter: formatter.dateOnly}
		},
		constructor: function(options){
			if(options && options.state){
				this.state = options.state;
			}

			Topic.subscribe("ProteinFamilies", lang.hitch(this, function(){
				// console.log("ProteinFamiliesFilterGrid:", arguments);
				var key = arguments[0], value = arguments[1];

				switch(key){
					case "updatePfState":
						this.pfState = value;
						break;
					case "updateFilterGrid":
						this.store.setData(value);
						this.store._loaded = true;
						this.refresh();
						break;
					case "updateFilterGridOrder":
						this.set('sort', [{}]);
						this.store.arrange(value);
						this.refresh();
						break;
					default:
						break;
				}
			}));
		},
		startup: function(){
			var _self = this;
			var options = ['present', 'absent', 'mixed'];
			var toggleSelection = function(element, value){
				element.checked = value;
				element.setAttribute("class", value ? "fa fa-check-square-o" : "fa fa-square-o");
				element.setAttribute("aria-checked", value);
			};

			this.on(".dgrid-cell:click", lang.hitch(_self, function(evt){
				var cell = _self.cell(evt);
				var colId = cell.column.id;
				var columnHeaders = cell.column.grid.columns;

				var conditionIds = _self.pfState.genomeIds;
				var conditionStatus = _self.pfState.genomeFilterStatus;

				if(!cell.element.input) return;

				if(cell.row){
					// data row is clicked
					var rowId = cell.row.id;

					// deselect other radio in the same row
					options.forEach(function(el){
						if(el != colId && _self.cell(rowId, el).element.input.checked){
							toggleSelection(_self.cell(rowId, el).element.input, false);
						}
						// updated selected box
						if(el === colId){
							toggleSelection(_self.cell(rowId, el).element.input, true);
						}
					});

					// check whether entire rows are selected & mark as needed
					options.forEach(function(el){
						var allSelected = true;
						conditionIds.forEach(function(conditionId){
							if(_self.cell(conditionId, el).element.input.checked == false){
								allSelected = false;
							}
						});
						toggleSelection(columnHeaders[el].headerNode.firstChild.firstElementChild, allSelected);
					});

				}else{
					// if header is clicked, reset the selections & update
					conditionIds.forEach(function(conditionId){
						options.forEach(function(el){
							if(el === colId){
								toggleSelection(_self.cell(conditionId, el).element.input, true);
							}else{
								toggleSelection(_self.cell(conditionId, el).element.input, false);
							}
						});
					});

					// deselect other radio in the header
					options.forEach(function(el){
						if(el != colId && columnHeaders[el].headerNode.firstChild.firstElementChild.checked){
							toggleSelection(columnHeaders[el].headerNode.firstChild.firstElementChild, false);
						}
					});
				}

				// update filter
				Object.keys(conditionStatus).forEach(function(conditionId){
					var status = options.findIndex(function(el){
						if(_self.cell(conditionId, el).element.input.checked){
							return el;
						}
					});

					conditionStatus[conditionId].setStatus(status);
				});

				this.pfState.genomeFilterStatus = conditionStatus;
				Topic.publish("ProteinFamilies", "applyConditionFilter", this.pfState);
			}));

			aspect.before(_self, 'renderArray', function(results){
				Deferred.when(results.total, function(x){
					_self.set("totalRows", x);
				});
			});

			// this.inherited(arguments);
			this._started = true;

			// increase grid width after rendering content-pane
			domStyle.set(this.id, "width", "650px");
		},
		_setSort: function(sort){
			this.inherited(arguments);

			// console.log("old order", this.pfState.genomeIds);
			var newIds = [];
			var idProperty = this.store.idProperty;
			this.store.query({}, {sort: sort}).forEach(function(condition){
				newIds.push(condition[idProperty]);
			});
			this.pfState.clusterRowOrder = newIds;
			// console.log("new order", this.pfState.clusterRowOrder);

			Topic.publish("ProteinFamilies", "updatePfState", this.pfState);
			Topic.publish("ProteinFamilies", "refreshHeatmap");
		},
		state: null,
		postCreate: function(){
			this.inherited(arguments);
		},
		_setApiServer: function(server){
			this.apiServer = server;
		}
	});
});
<|endoftext|>


<commit_before>import compose from 'flight/lib/compose'
import registry from 'flight/lib/registry'
import advice from 'flight/lib/advice'
import withLogging from 'flight/lib/logger'
import debug from 'flight/lib/debug'
import events from 'page/events'
import initializeDefault from 'page/default'
import 'js/monkey_patching/all'

window.Pixelated = window.Pixelated || {}
window.Pixelated.events = events

compose.mixin(registry, [advice.withAdvice, withLogging])

debug.enable(true)
debug.events.logAll()

initializeDefault('')
<commit_msg>Fixes jshint by adding semicolon in index.js<commit_after>import compose from 'flight/lib/compose';
import registry from 'flight/lib/registry';
import advice from 'flight/lib/advice';
import withLogging from 'flight/lib/logger';
import debug from 'flight/lib/debug';
import events from 'page/events';
import initializeDefault from 'page/default';
import 'js/monkey_patching/all';

window.Pixelated = window.Pixelated || {};
window.Pixelated.events = events;

compose.mixin(registry, [advice.withAdvice, withLogging]);

debug.enable(true);
debug.events.logAll();

initializeDefault('');
<|endoftext|>


<commit_before>var module = angular.module('racer.js', [], function ($provide) {
	function extendObject(from, to) {
		if (from === to) return to;

		if (from.constructor === Array && to.constructor === Array) {
			for (var i = 0; i < from.length; ++i) {
				to[i] = extendObject(from[i], to[i]);
			}
			to.splice(from.length, to.length);

			return to;
		} else if (from.constructor === Object && to.constructor === Object) {
			for (var key in to) {
				if (typeof from[key] === 'undefined') {
					delete to[key];
				}
			}

			for (var key in from) {
				to[key] = extendObject(from[key], to[key]);
			}

			return to;
		} else {
			return from;
		}
	}

	var racer = require('racer');

	$provide.factory('racer', ['$http', '$q', '$rootScope', function ($http, $q, $rootScope) {
		$http.get('/model').success(function (data) {
			racer.init(data);
		});

		var def = $q.defer();
		racer.ready(function (model) {
			var paths = {};

			var oldGet = model.get;
			model.get = function (path) {
				if (!paths[path]) {
					paths[path] = oldGet.call(model, path);

					model.on('all', path ? path + '.**' : '**', function () {
						var newData = oldGet.call(model, path);
						paths[path] = extendObject(newData, paths[path]);
						$rootScope.$apply();
					});
				}

				return paths[path];
			};

			def.resolve(model);
		});

		return def.promise;
	}]);
});<commit_msg>Fix a few remaining service bugs<commit_after>angular.module('racer.js', [], function ($provide) {
	function extendObject(from, to) {
		if (from === to) return to;

		if (from.constructor === Array && to.constructor === Array) {
			for (var i = 0; i < from.length; ++i) {
				to[i] = extendObject(from[i], to[i]);
			}
			to.splice(from.length, to.length);

			return to;
		} else if (from.constructor === Object && to && to.constructor === Object) {
			for (var key in to) {
				if (typeof from[key] === 'undefined') {
					delete to[key];
				}
			}

			for (var key in from) {
				to[key] = extendObject(from[key], to[key]);
			}

			return to;
		} else {
			return from;
		}
	}

	var setImmediate = window && window.setImmediate ? window.setImmediate : function (fn) {
		setTimeout(fn, 0);
	};

	var racer = require('racer');

	$provide.factory('racer', ['$http', '$q', '$rootScope', function ($http, $q, $rootScope) {
		$http.get('/model').success(function (data) {
			racer.init(data);
		});

		var def = $q.defer();
		racer.ready(function (model) {
			var paths = {};

			var oldGet = model.get;
			model.get = function (path) {
				if (!paths[path]) {
					paths[path] = oldGet.call(model, path);

					model.on('all', path ? path + '**' : '**', function () {
						var newData = oldGet.call(model, path);
						paths[path] = extendObject(newData, paths[path]);
						setImmediate($rootScope.$apply.bind($rootScope));
					});
				}

				return paths[path];
			};

			def.resolve(model);
			$rootScope.$apply();
		});

		return def.promise;
	}]);
});<|endoftext|>


<commit_before>'use strict';

// Configuring the core module's topbar.
angular.module('core').run(['Menus',
	function(Menus) {
		// Set top bar menu items
		Menus.addMenuItem('topbar', 'The Team', 'the-team', '', '/the-team', true);
	}
]);
<commit_msg>Hide The Team link from Top bar.<commit_after>'use strict';

// Configuring the core module's topbar.
angular.module('core').run(['Menus',
	function(Menus) {
		// Set top bar menu items
		//Menus.addMenuItem('topbar', 'The Team', 'the-team', '', '/the-team', true);
	}
]);
<|endoftext|>