<commit_before>utilities.namespace("SymPy");
SymPy.DEFAULT_ANIMATION_DURATION = 500;
SymPy.SphinxShell = SymPy.Shell.$extend({
    evalModeTypes: ['eval', 'copy'],
    evalMode: 'eval',

    __init__: function(config) {
        this.$super(config);
        this.visible = true;
        this.queuedStatements = [];

        index = this.evalModeTypes.indexOf(config.record);
        this.evalMode = (index == -1) ? this.getCookie('sympy-evalMode', 'eval') : config.evalMode;
        this.banner = config.banner ? config.banner : '';
    },

    render: function(el) {
        this.$super(el);

        this.shellEl = $(el);

        var headerLink =
            $('SymPy Live Shell');
        var header = $("
").append(headerLink);
        this.shellEl.prepend(header);

        this.toggleShellEl = $('<button/>').
            html("Hide SymPy Live Shell").
            attr("id", "toggleShell").
            addClass('shown');
        this.toggleShellEl.prepend($('
'));

        this.toggleShellEl.appendTo(document.body);
        this.toggleShellEl.click($.proxy(function() {
            this.toggle();
        }, this));

        // Add a link to Python code that will evaluate it in SymPy Live
        this.processCodeBlocks();

        // Don't expand the list of tab completions (saves space)
        this.completer.expandCompletions = false;

        // Change Fullscreen to go to main website
        $("#fullscreen-button").html("Go to SymPy Live");

	    this.evalModeEl.change($.proxy(function(event) {
            this.updateSettings();
            this.focus();
        }, this));
    },

    renderToolbar: function(settings) {
        this.$super(settings);

        $('
Settings
').
            prependTo($("#settings")).
            click($.proxy(this.toggleSettings, this));
        $("#settings h3").prepend($('
'));

        // We don't need the "force desktop version" option since there is
        // no mobile version
        var checkbox = $('#settings input[type="checkbox"]');
        checkbox.prev().hide();
        checkbox.next().hide();
        checkbox.hide();

        this.toolbarEl.append(
            $('
'),
            $('Evaluation Mode:'),
            $('<select id="evalMode"/>').append(
                $('<option value="eval">Evaluate</option>'),
                $('<option value="copy">Copy</option>')
            ),
            $('
')
        );
        this.evalModeEl = $('#evalMode');

        var index = this.evalModeTypes.indexOf(this.evalMode);
        this.evalModeEl.children('option')[index].selected = true;

        // Make enter the default submission button
        $("#submit-behavior").val("enter");
    },

    done: function(response) {
        this.$super(response);
        if (this.queuedStatements.length !== 0) {
            this.dequeueStatement();
            this.evaluate();
        }
    },

    error: function(xhr, status, error) {
        this.$super(xhr, status, error);
        this.queuedStatements.length = 0;
    },

    dequeueStatement: function() {
        if (this.queuedStatements.length !== 0) {
            this.setValue(this.queuedStatements.shift());
        }
    },

    processCodeBlocks: function() {
        $('.highlight-python').each($.proxy(function(index, el) {
            var el = $(el);

            // Add the toolbar
            var container = $("
").addClass('sympy-live-eval-toolbar');
            var evaluate = $("<button>Run in SymPy Live</button>").
                addClass('sympy-live-eval-button').
                appendTo(container);
            el.children('.highlight').prepend(container);

            evaluate.click($.proxy(function() {
                this.show();
                var statementBlocks = el.find('div.live-statement');
                var codeBlocks = [];
                for (var i = 0; i < statementBlocks.length; i++) {
                    codeBlocks.push(
                        this.stripCode($(statementBlocks[i]).text())
                    );
                }
                if (this.evalModeEl.val() === "eval") {
                    this.queuedStatements = codeBlocks;
                    this.dequeueStatement();
                    this.evaluate();
                }
                else {
                    this.setValue(codeBlocks.join("\n"));
                    this.focus();
                }
            }, this));

            this.processIndividualCodeBlocks(el.find('pre'));
        }, this));
    },

    processIndividualCodeBlocks: function(codeEl) {
        // childNodes gives text nodes which we want for whitespace
        var childNodes = codeEl.get(0).childNodes;
        var currentLine = [];
        var lines = [];

        for (var i = 0; i < childNodes.length; i++) {
            var domNode = childNodes[i];
            if (domNode.nodeType === domNode.ELEMENT_NODE) {
                currentLine.push(domNode.cloneNode(true));

                if (currentLine.length === 1 &&
                    domNode.innerText.substr(0, 3) === "...") {
                    // First node on line and continuation, so continue from
                    // the previous line
                    currentLine = lines.pop();
                    currentLine.push(domNode.cloneNode(true));
                }
            }
            else if (domNode.nodeType === domNode.TEXT_NODE) {
                currentLine.push(domNode.cloneNode(true));
                if (domNode.data.substr(-1) === '\n') {
                    lines.push(currentLine);
                    currentLine = [];
                }
            }
        }
        codeEl.empty();
        for (var i = 0; i < lines.length; i++) {
            var line = $('
');
            var processingLine = lines[i];
            if (processingLine[0].innerText.substr(0, 4) === ">>> ") {
                line.addClass('live-statement');
            }
            line.append(processingLine);
            line.click($.proxy((function(line) {
                // Save the current line
                return function() {
                    this.setValue(this.stripCode(line.text()));
                    this.show();
                    if (this.evalModeEl.val() === "eval") {
                        this.evaluate();
                    }
                    else {
                        this.focus();
                    }
                }
            })(line), this));
            codeEl.append(line);
        }
    },

    // Strips >>> and ... from a string
    stripCode: function(text) {
        var lines = text.split(/\n/g);
        var strippedLines = [];
        for (var i = 0; i < lines.length; i++) {
            strippedLines.push(lines[i].slice(4));
        }
        return strippedLines.join('\n').trim();
    },

    hide: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.disablePrompt();

        this.shellDimensionsRestored = {
            width: this.shellEl.width(),
            height: this.shellEl.height(),
            opacity: 1
        };

        this.shellEl.animate({
            width: 0,
            height: 0,
            opacity: 0
        }, duration);
        this.visible = false;

        this.toggleShellEl.removeClass('shown').children('span').
            html("Show SymPy Live Shell");
    },

    show: function(duration) {
        if (this.visible) return;

        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.enablePrompt();
        $(this.shellEl).animate(
            this.shellDimensionsRestored,
            duration,
            function() {
                // Don't fix the height so that if the settings are
                // expanded, the shell will expand with them
                $(this).css('height', 'auto');
            });
        this.visible = true;
        this.toggleShellEl.addClass('shown').children('span').
            html("Hide SymPy Live Shell");
    },

    toggle: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        if (this.isVisible()) {
            this.hide(duration);
        }
        else {
            this.show(duration);
        }
    },

    toggleSettings: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }

        if ($("#settings .content").is(":visible")) {
            $("#settings .content").slideUp(duration);
            $("#settings h3").removeClass('shown');
        }
        else {
            $("#settings .content").slideDown(duration);
            $("#settings h3").addClass('shown');
        }
    },

    isVisible: function() {
        return this.visible;
    },

    fullscreen: function() {
        window.open("http://live.sympy.org");
    },

    updateSettings: function() {
        this.$super();
        this.setCookie('sympy-evalMode', this.evalModeEl.val());
    }
});

$(document).ready(function() {
    var path = SymPy.getBasePath('live-sphinx.js');

    $.get(path + '/sphinxbanner').done(function(data) {
        var shellEl = $('
').appendTo($(document.body));
        var settingsEl = $('

');
        settingsEl.appendTo(shellEl);  // Needed to render the shell

        var shell = new SymPy.SphinxShell({
            baseName: 'live-sphinx.js',
            banner: data
        });
        shell.render(shellEl);
        settingsEl.appendTo(shellEl); // Put it under the shell
        shell.toggleSettings();
        shell.hide(0);
    });
});
<commit_msg>Sphinx: do not clear code block if no statements found<commit_after>utilities.namespace("SymPy");
SymPy.DEFAULT_ANIMATION_DURATION = 500;
SymPy.SphinxShell = SymPy.Shell.$extend({
    evalModeTypes: ['eval', 'copy'],
    evalMode: 'eval',

    __init__: function(config) {
        this.$super(config);
        this.visible = true;
        this.queuedStatements = [];

        index = this.evalModeTypes.indexOf(config.record);
        this.evalMode = (index == -1) ? this.getCookie('sympy-evalMode', 'eval') : config.evalMode;
        this.banner = config.banner ? config.banner : '';
    },

    render: function(el) {
        this.$super(el);

        this.shellEl = $(el);

        var headerLink =
            $('SymPy Live Shell');
        var header = $("
").append(headerLink);
        this.shellEl.prepend(header);

        this.toggleShellEl = $('<button/>').
            html("Hide SymPy Live Shell").
            attr("id", "toggleShell").
            addClass('shown');
        this.toggleShellEl.prepend($('
'));

        this.toggleShellEl.appendTo(document.body);
        this.toggleShellEl.click($.proxy(function() {
            this.toggle();
        }, this));

        // Add a link to Python code that will evaluate it in SymPy Live
        this.processCodeBlocks();

        // Don't expand the list of tab completions (saves space)
        this.completer.expandCompletions = false;

        // Change Fullscreen to go to main website
        $("#fullscreen-button").html("Go to SymPy Live");

	    this.evalModeEl.change($.proxy(function(event) {
            this.updateSettings();
            this.focus();
        }, this));
    },

    renderToolbar: function(settings) {
        this.$super(settings);

        $('
Settings
').
            prependTo($("#settings")).
            click($.proxy(this.toggleSettings, this));
        $("#settings h3").prepend($('
'));

        // We don't need the "force desktop version" option since there is
        // no mobile version
        var checkbox = $('#settings input[type="checkbox"]');
        checkbox.prev().hide();
        checkbox.next().hide();
        checkbox.hide();

        this.toolbarEl.append(
            $('
'),
            $('Evaluation Mode:'),
            $('<select id="evalMode"/>').append(
                $('<option value="eval">Evaluate</option>'),
                $('<option value="copy">Copy</option>')
            ),
            $('
')
        );
        this.evalModeEl = $('#evalMode');

        var index = this.evalModeTypes.indexOf(this.evalMode);
        this.evalModeEl.children('option')[index].selected = true;

        // Make enter the default submission button
        $("#submit-behavior").val("enter");
    },

    done: function(response) {
        this.$super(response);
        if (this.queuedStatements.length !== 0) {
            this.dequeueStatement();
            this.evaluate();
        }
    },

    error: function(xhr, status, error) {
        this.$super(xhr, status, error);
        this.queuedStatements.length = 0;
    },

    dequeueStatement: function() {
        if (this.queuedStatements.length !== 0) {
            this.setValue(this.queuedStatements.shift());
        }
    },

    processCodeBlocks: function() {
        $('.highlight-python').each($.proxy(function(index, el) {
            var el = $(el);

            // Add the toolbar
            var container = $("
").addClass('sympy-live-eval-toolbar');
            var evaluate = $("<button>Run in SymPy Live</button>").
                addClass('sympy-live-eval-button').
                appendTo(container);
            el.children('.highlight').prepend(container);

            evaluate.click($.proxy(function() {
                this.show();
                var statementBlocks = el.find('div.live-statement');
                var codeBlocks = [];
                for (var i = 0; i < statementBlocks.length; i++) {
                    codeBlocks.push(
                        this.stripCode($(statementBlocks[i]).text())
                    );
                }
                if (this.evalModeEl.val() === "eval") {
                    this.queuedStatements = codeBlocks;
                    this.dequeueStatement();
                    this.evaluate();
                }
                else {
                    this.setValue(codeBlocks.join("\n"));
                    this.focus();
                }
            }, this));

            this.processIndividualCodeBlocks(el.find('pre'));
        }, this));
    },

    processIndividualCodeBlocks: function(codeEl) {
        // childNodes gives text nodes which we want for whitespace
        var childNodes = codeEl.get(0).childNodes;
        var currentLine = [];
        var lines = [];

        for (var i = 0; i < childNodes.length; i++) {
            var domNode = childNodes[i];
            if (domNode.nodeType === domNode.ELEMENT_NODE) {
                currentLine.push(domNode.cloneNode(true));

                if (currentLine.length === 1 &&
                    domNode.innerText.substr(0, 3) === "...") {
                    // First node on line and continuation, so continue from
                    // the previous line
                    currentLine = lines.pop();
                    currentLine.push(domNode.cloneNode(true));
                }
            }
            else if (domNode.nodeType === domNode.TEXT_NODE) {
                currentLine.push(domNode.cloneNode(true));
                if (domNode.data.substr(-1) === '\n') {
                    lines.push(currentLine);
                    currentLine = [];
                }
            }
        }
        if (lines.length !== 0) {
            codeEl.empty();
            for (var i = 0; i < lines.length; i++) {
                var line = $('
');
                var processingLine = lines[i];
                if (processingLine[0].innerText.substr(0, 4) === ">>> ") {
                    line.addClass('live-statement');
                }
                line.append(processingLine);
                line.click($.proxy((function(line) {
                    // Save the current line
                    return function() {
                        this.setValue(this.stripCode(line.text()));
                        this.show();
                        if (this.evalModeEl.val() === "eval") {
                            this.evaluate();
                        }
                        else {
                            this.focus();
                        }
                    }
                })(line), this));
                codeEl.append(line);
            }
        }
    },

    // Strips >>> and ... from a string
    stripCode: function(text) {
        var lines = text.split(/\n/g);
        var strippedLines = [];
        for (var i = 0; i < lines.length; i++) {
            strippedLines.push(lines[i].slice(4));
        }
        return strippedLines.join('\n').trim();
    },

    hide: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.disablePrompt();

        this.shellDimensionsRestored = {
            width: this.shellEl.width(),
            height: this.shellEl.height(),
            opacity: 1
        };

        this.shellEl.animate({
            width: 0,
            height: 0,
            opacity: 0
        }, duration);
        this.visible = false;

        this.toggleShellEl.removeClass('shown').children('span').
            html("Show SymPy Live Shell");
    },

    show: function(duration) {
        if (this.visible) return;

        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.enablePrompt();
        $(this.shellEl).animate(
            this.shellDimensionsRestored,
            duration,
            function() {
                // Don't fix the height so that if the settings are
                // expanded, the shell will expand with them
                $(this).css('height', 'auto');
            });
        this.visible = true;
        this.toggleShellEl.addClass('shown').children('span').
            html("Hide SymPy Live Shell");
    },

    toggle: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        if (this.isVisible()) {
            this.hide(duration);
        }
        else {
            this.show(duration);
        }
    },

    toggleSettings: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }

        if ($("#settings .content").is(":visible")) {
            $("#settings .content").slideUp(duration);
            $("#settings h3").removeClass('shown');
        }
        else {
            $("#settings .content").slideDown(duration);
            $("#settings h3").addClass('shown');
        }
    },

    isVisible: function() {
        return this.visible;
    },

    fullscreen: function() {
        window.open("http://live.sympy.org");
    },

    updateSettings: function() {
        this.$super();
        this.setCookie('sympy-evalMode', this.evalModeEl.val());
    }
});

$(document).ready(function() {
    var path = SymPy.getBasePath('live-sphinx.js');

    $.get(path + '/sphinxbanner').done(function(data) {
        var shellEl = $('
').appendTo($(document.body));
        var settingsEl = $('

');
        settingsEl.appendTo(shellEl);  // Needed to render the shell

        var shell = new SymPy.SphinxShell({
            baseName: 'live-sphinx.js',
            banner: data
        });
        shell.render(shellEl);
        settingsEl.appendTo(shellEl); // Put it under the shell
        shell.toggleSettings();
        shell.hide(0);
    });
});
<|endoftext|>


<commit_before>utilities.namespace("SymPy");
SymPy.DEFAULT_ANIMATION_DURATION = 500;
SymPy.SphinxShell = SymPy.Shell.$extend({
    evalModeTypes: ['eval', 'copy'],
    evalMode: 'eval',

    __init__: function(config) {
        this.$super(config);
        this.visible = true;
        this.queuedStatements = [];

        index = this.evalModeTypes.indexOf(config.record);
        this.evalMode = (index == -1) ? this.getCookie('sympy-evalMode', 'eval') : config.evalMode;
        this.banner = config.banner ? config.banner : '';
    },

    render: function(el) {
        this.$super(el);

        this.shellEl = $(el);

        var headerLink =
            $('SymPy Live Shell');
        var header = $("
").append(headerLink);
        this.shellEl.prepend(header);

        this.toggleShellEl = $('<button/>').
            html("Hide SymPy Live Shell").
            attr("id", "toggleShell").
            addClass('shown');
        this.toggleShellEl.prepend($('
'));

        this.toggleShellEl.appendTo(document.body);
        this.toggleShellEl.click($.proxy(function() {
            this.toggle();
        }, this));

        // Add a link to Python code that will evaluate it in SymPy Live
        this.processCodeBlocks();

        // Don't expand the list of tab completions (saves space)
        this.completer.expandCompletions = false;

        // Change Fullscreen to go to main website
        $("#fullscreen-button").html("Go to SymPy Live");

	    this.evalModeEl.change($.proxy(function(event) {
            this.updateSettings();
            this.focus();
        }, this));
    },

    renderToolbar: function(settings) {
        this.$super(settings);

        $('
Settings
').
            prependTo($("#settings")).
            click($.proxy(this.toggleSettings, this));
        $("#settings h3").prepend($('
'));

        // We don't need the "force desktop version" option since there is
        // no mobile version
        var checkbox = $('#settings input[type="checkbox"]');
        checkbox.prev().hide();
        checkbox.next().hide();
        checkbox.hide();

        this.toolbarEl.append(
            $('
'),
            $('Evaluation Mode:'),
            $('<select id="evalMode"/>').append(
                $('<option value="eval">Evaluate</option>'),
                $('<option value="copy">Copy</option>')
            ),
            $('
')
        );
        this.evalModeEl = $('#evalMode');

        var index = this.evalModeTypes.indexOf(this.evalMode);
        this.evalModeEl.children('option')[index].selected = true;

        // Make enter the default submission button
        $("#submit-behavior").val("enter");
    },

    done: function(response) {
        this.$super(response);
        if (this.queuedStatements.length !== 0) {
            this.dequeueStatement();
            this.evaluate();
        }
    },

    error: function(xhr, status, error) {
        this.$super(xhr, status, error);
        this.queuedStatements.length = 0;
    },

    dequeueStatement: function() {
        if (this.queuedStatements.length !== 0) {
            var statements = this.queuedStatements.shift();
            this.setValue(statements.join('\n'));
        }
    },

    processCodeBlocks: function() {
        $('.highlight-python').each($.proxy(function(index, el) {
            var el = $(el);

            // Add the toolbar
            var container = $("
").addClass('sympy-live-eval-toolbar');
            var evaluate = $("<button>Run in SymPy Live</button>").
                addClass('sympy-live-eval-button').
                appendTo(container);
            el.children('.highlight').prepend(container);

            var fillShell = $.proxy(function() {
                this.show();
                var code = el.find('pre').text();
                var lines = code.split(/\n/g);

                // We want to evaluate each block individually
                var codeBlocks = [];
                var currentBlock = [];
                for (var i = 0; i < lines.length; i++) {
                    if (lines[i].substring(0, 4) === ">>> ") {
                        codeBlocks.push(currentBlock);
                        currentBlock = [];

                        currentBlock.push(
                            lines[i].substring(4, lines[i].length));
                    }
                    else if (lines[i].substring(0, 4) === "... ") {
                        currentBlock.push(
                            lines[i].substring(4, lines[i].length));
                    }
                }
                if (currentBlock.length !== 0) {
                    codeBlocks.push(currentBlock);
                }
                codeBlocks = codeBlocks.slice(1);
                this.queuedStatements = codeBlocks;
            }, this);

            evaluate.click($.proxy(function() {
                fillShell();
                if (this.evalModeEl.val() === "eval") {
                    this.dequeueStatement();
                    this.evaluate();
                }
                else {
                    this.focus();
                }
            }, this));

            this.processIndividualCodeBlocks(el.find('pre'));
        }, this));
    },

    processIndividualCodeBlocks: function(codeEl) {
        // childNodes gives text nodes which we want for whitespace
        var childNodes = codeEl.get(0).childNodes;
        var currentLine = [];
        var lines = [];

        for (var i = 0; i < childNodes.length; i++) {
            var domNode = childNodes[i];
            if (domNode.nodeType === domNode.ELEMENT_NODE) {
                currentLine.push(domNode.cloneNode(true));

                if (currentLine.length === 1 &&
                    domNode.innerText.substr(0, 3) === "...") {
                    // First node on line and continuation, so continue from
                    // the previous line
                    currentLine = lines.pop();
                    currentLine.push(domNode.cloneNode(true));
                }
            }
            else if (domNode.nodeType === domNode.TEXT_NODE) {
                currentLine.push(domNode.cloneNode(true));
                if (domNode.data.substr(-1) === '\n') {
                    lines.push(currentLine);
                    currentLine = [];
                }
            }
        }
        codeEl.empty();
        for (var i = 0; i < lines.length; i++) {
            var line = $('
');
            var processingLine = lines[i];
            if (processingLine[0].innerText.substr(0, 4) === ">>> ") {
                line.addClass('live-statement');
            }
            line.append(processingLine);
            line.click($.proxy((function(line) {
                // Save the current line
                return function() {
                    var lines = line.text().split(/\n/g);
                    var strippedLines = [];
                    for (var i = 0; i < lines.length; i++) {
                        strippedLines.push(lines[i].slice(4));
                    }
                    this.setValue(strippedLines.join('\n').trim());
                    this.show();
                    this.evaluate();
                }
            })(line), this));
            codeEl.append(line);
        }
    },

    hide: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.disablePrompt();

        this.shellDimensionsRestored = {
            width: this.shellEl.width(),
            height: this.shellEl.height(),
            opacity: 1
        };

        this.shellEl.animate({
            width: 0,
            height: 0,
            opacity: 0
        }, duration);
        this.visible = false;

        this.toggleShellEl.removeClass('shown').children('span').
            html("Show SymPy Live Shell");
    },

    show: function(duration) {
        if (this.visible) return;

        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.enablePrompt();
        $(this.shellEl).animate(
            this.shellDimensionsRestored,
            duration,
            function() {
                // Don't fix the height so that if the settings are
                // expanded, the shell will expand with them
                $(this).css('height', 'auto');
            });
        this.visible = true;
        this.toggleShellEl.addClass('shown').children('span').
            html("Hide SymPy Live Shell");
    },

    toggle: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        if (this.isVisible()) {
            this.hide(duration);
        }
        else {
            this.show(duration);
        }
    },

    toggleSettings: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }

        if ($("#settings .content").is(":visible")) {
            $("#settings .content").slideUp(duration);
            $("#settings h3").removeClass('shown');
        }
        else {
            $("#settings .content").slideDown(duration);
            $("#settings h3").addClass('shown');
        }
    },

    isVisible: function() {
        return this.visible;
    },

    fullscreen: function() {
        window.open("http://live.sympy.org");
    },

    updateSettings: function() {
        this.$super();
        this.setCookie('sympy-evalMode', this.evalModeEl.val());
    }
});

$(document).ready(function() {
    var path = SymPy.getBasePath('live-sphinx.js');

    $.get(path + '/sphinxbanner').done(function(data) {
        var shellEl = $('
').appendTo($(document.body));
        var settingsEl = $('

');
        settingsEl.appendTo(shellEl);  // Needed to render the shell

        var shell = new SymPy.SphinxShell({
            baseName: 'live-sphinx.js',
            banner: data
        });
        shell.render(shellEl);
        settingsEl.appendTo(shellEl); // Put it under the shell
        shell.toggleSettings();
        shell.hide(0);
    });
});
<commit_msg>Sphinx: Check for copy/eval when clicking statement<commit_after>utilities.namespace("SymPy");
SymPy.DEFAULT_ANIMATION_DURATION = 500;
SymPy.SphinxShell = SymPy.Shell.$extend({
    evalModeTypes: ['eval', 'copy'],
    evalMode: 'eval',

    __init__: function(config) {
        this.$super(config);
        this.visible = true;
        this.queuedStatements = [];

        index = this.evalModeTypes.indexOf(config.record);
        this.evalMode = (index == -1) ? this.getCookie('sympy-evalMode', 'eval') : config.evalMode;
        this.banner = config.banner ? config.banner : '';
    },

    render: function(el) {
        this.$super(el);

        this.shellEl = $(el);

        var headerLink =
            $('SymPy Live Shell');
        var header = $("
").append(headerLink);
        this.shellEl.prepend(header);

        this.toggleShellEl = $('<button/>').
            html("Hide SymPy Live Shell").
            attr("id", "toggleShell").
            addClass('shown');
        this.toggleShellEl.prepend($('
'));

        this.toggleShellEl.appendTo(document.body);
        this.toggleShellEl.click($.proxy(function() {
            this.toggle();
        }, this));

        // Add a link to Python code that will evaluate it in SymPy Live
        this.processCodeBlocks();

        // Don't expand the list of tab completions (saves space)
        this.completer.expandCompletions = false;

        // Change Fullscreen to go to main website
        $("#fullscreen-button").html("Go to SymPy Live");

	    this.evalModeEl.change($.proxy(function(event) {
            this.updateSettings();
            this.focus();
        }, this));
    },

    renderToolbar: function(settings) {
        this.$super(settings);

        $('
Settings
').
            prependTo($("#settings")).
            click($.proxy(this.toggleSettings, this));
        $("#settings h3").prepend($('
'));

        // We don't need the "force desktop version" option since there is
        // no mobile version
        var checkbox = $('#settings input[type="checkbox"]');
        checkbox.prev().hide();
        checkbox.next().hide();
        checkbox.hide();

        this.toolbarEl.append(
            $('
'),
            $('Evaluation Mode:'),
            $('<select id="evalMode"/>').append(
                $('<option value="eval">Evaluate</option>'),
                $('<option value="copy">Copy</option>')
            ),
            $('
')
        );
        this.evalModeEl = $('#evalMode');

        var index = this.evalModeTypes.indexOf(this.evalMode);
        this.evalModeEl.children('option')[index].selected = true;

        // Make enter the default submission button
        $("#submit-behavior").val("enter");
    },

    done: function(response) {
        this.$super(response);
        if (this.queuedStatements.length !== 0) {
            this.dequeueStatement();
            this.evaluate();
        }
    },

    error: function(xhr, status, error) {
        this.$super(xhr, status, error);
        this.queuedStatements.length = 0;
    },

    dequeueStatement: function() {
        if (this.queuedStatements.length !== 0) {
            var statements = this.queuedStatements.shift();
            this.setValue(statements.join('\n'));
        }
    },

    processCodeBlocks: function() {
        $('.highlight-python').each($.proxy(function(index, el) {
            var el = $(el);

            // Add the toolbar
            var container = $("
").addClass('sympy-live-eval-toolbar');
            var evaluate = $("<button>Run in SymPy Live</button>").
                addClass('sympy-live-eval-button').
                appendTo(container);
            el.children('.highlight').prepend(container);

            var fillShell = $.proxy(function() {
                this.show();
                var code = el.find('pre').text();
                var lines = code.split(/\n/g);

                // We want to evaluate each block individually
                var codeBlocks = [];
                var currentBlock = [];
                for (var i = 0; i < lines.length; i++) {
                    if (lines[i].substring(0, 4) === ">>> ") {
                        codeBlocks.push(currentBlock);
                        currentBlock = [];

                        currentBlock.push(
                            lines[i].substring(4, lines[i].length));
                    }
                    else if (lines[i].substring(0, 4) === "... ") {
                        currentBlock.push(
                            lines[i].substring(4, lines[i].length));
                    }
                }
                if (currentBlock.length !== 0) {
                    codeBlocks.push(currentBlock);
                }
                codeBlocks = codeBlocks.slice(1);
                this.queuedStatements = codeBlocks;
            }, this);

            evaluate.click($.proxy(function() {
                fillShell();
                if (this.evalModeEl.val() === "eval") {
                    this.dequeueStatement();
                    this.evaluate();
                }
                else {
                    this.focus();
                }
            }, this));

            this.processIndividualCodeBlocks(el.find('pre'));
        }, this));
    },

    processIndividualCodeBlocks: function(codeEl) {
        // childNodes gives text nodes which we want for whitespace
        var childNodes = codeEl.get(0).childNodes;
        var currentLine = [];
        var lines = [];

        for (var i = 0; i < childNodes.length; i++) {
            var domNode = childNodes[i];
            if (domNode.nodeType === domNode.ELEMENT_NODE) {
                currentLine.push(domNode.cloneNode(true));

                if (currentLine.length === 1 &&
                    domNode.innerText.substr(0, 3) === "...") {
                    // First node on line and continuation, so continue from
                    // the previous line
                    currentLine = lines.pop();
                    currentLine.push(domNode.cloneNode(true));
                }
            }
            else if (domNode.nodeType === domNode.TEXT_NODE) {
                currentLine.push(domNode.cloneNode(true));
                if (domNode.data.substr(-1) === '\n') {
                    lines.push(currentLine);
                    currentLine = [];
                }
            }
        }
        codeEl.empty();
        for (var i = 0; i < lines.length; i++) {
            var line = $('
');
            var processingLine = lines[i];
            if (processingLine[0].innerText.substr(0, 4) === ">>> ") {
                line.addClass('live-statement');
            }
            line.append(processingLine);
            line.click($.proxy((function(line) {
                // Save the current line
                return function() {
                    var lines = line.text().split(/\n/g);
                    var strippedLines = [];
                    for (var i = 0; i < lines.length; i++) {
                        strippedLines.push(lines[i].slice(4));
                    }
                    this.setValue(strippedLines.join('\n').trim());
                    this.show();
                    if (this.evalModeEl.val() === "eval") {
                        this.evaluate();
                    }
                    else {
                        this.focus();
                    }
                }
            })(line), this));
            codeEl.append(line);
        }
    },

    hide: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.disablePrompt();

        this.shellDimensionsRestored = {
            width: this.shellEl.width(),
            height: this.shellEl.height(),
            opacity: 1
        };

        this.shellEl.animate({
            width: 0,
            height: 0,
            opacity: 0
        }, duration);
        this.visible = false;

        this.toggleShellEl.removeClass('shown').children('span').
            html("Show SymPy Live Shell");
    },

    show: function(duration) {
        if (this.visible) return;

        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        this.enablePrompt();
        $(this.shellEl).animate(
            this.shellDimensionsRestored,
            duration,
            function() {
                // Don't fix the height so that if the settings are
                // expanded, the shell will expand with them
                $(this).css('height', 'auto');
            });
        this.visible = true;
        this.toggleShellEl.addClass('shown').children('span').
            html("Hide SymPy Live Shell");
    },

    toggle: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }
        if (this.isVisible()) {
            this.hide(duration);
        }
        else {
            this.show(duration);
        }
    },

    toggleSettings: function(duration) {
        if (typeof duration === "undefined") {
            duration = SymPy.DEFAULT_ANIMATION_DURATION;
        }

        if ($("#settings .content").is(":visible")) {
            $("#settings .content").slideUp(duration);
            $("#settings h3").removeClass('shown');
        }
        else {
            $("#settings .content").slideDown(duration);
            $("#settings h3").addClass('shown');
        }
    },

    isVisible: function() {
        return this.visible;
    },

    fullscreen: function() {
        window.open("http://live.sympy.org");
    },

    updateSettings: function() {
        this.$super();
        this.setCookie('sympy-evalMode', this.evalModeEl.val());
    }
});

$(document).ready(function() {
    var path = SymPy.getBasePath('live-sphinx.js');

    $.get(path + '/sphinxbanner').done(function(data) {
        var shellEl = $('
').appendTo($(document.body));
        var settingsEl = $('

');
        settingsEl.appendTo(shellEl);  // Needed to render the shell

        var shell = new SymPy.SphinxShell({
            baseName: 'live-sphinx.js',
            banner: data
        });
        shell.render(shellEl);
        settingsEl.appendTo(shellEl); // Put it under the shell
        shell.toggleSettings();
        shell.hide(0);
    });
});
<|endoftext|>


<commit_before>function displayBoxesDiv(boxes) {
  // function to nicely display the boundaries of the boxes used
  var divString =
    "
  You may save this information about the bounding boxes for your records.  ";
  Object.keys(boxes).map(boxId => {
    console.log(boxId);
    console.log(boxes);
    var box = boxes[boxId];
    divString += "
 " + box.name + "
 ";
    divString +=
      "

 Northeast corner:
 (" +
      box.rectangle._bounds._northEast.lat +
      ", " +
      box.rectangle._bounds._northEast.lng +
      ")

 Southwest corner:
 (" +
      box.rectangle._bounds._southWest.lat +
      ", " +
      box.rectangle._bounds._southWest.lng +
      ")

";
  });
  divString += "
";
  return divString;
}

// INIT CSV
var expansionCoef = 0.002195; // approx amount of degrees = 800 ft
var csv = [
  [
    "name of area",
    "start date",
    "start time",
    "end date",
    "end time",
    "duration (hrs)",
    "total time for week (hrs)"
  ]
];
weekMarkMS = 0;
// On click of submit button start csv generation process
$("#submitProcess").on("click", function(e) {
  var errString = "";
  $("#submitErrors").remove();

  if (Object.keys(boxes).length <= 0) {
    errString += " Please select at least one bounding box.";
  }
  if (!$("#filename").val()) {
    errString += " Please enter a name for your file.";
  }
  if ($("#startDay").val() === "") {
    errString += " Please select a valid start day.";
  }
  if (errString.length > 0) {
    $("#submitProcess").before(
      "

" +
        errString +
        "

"
    );
  } else {
    swal({
      title: "Processing Location Data",
      text:
        'Note this may take a few minutes:

0%
',
      html: true,
      showConfirmButton: false
    });

    var obj = processData(boxes, $("#startDay").val());
    var inside = new Array(obj.boxes.length).fill(false);
    var endTimes = new Array(obj.boxes.length).fill(0);
    var durations = new Array(obj.boxes.length).fill(0);
    var count = 0;
    var newOboe = oboe();
    newOboe
      .node("locations.*", function(location) {
        if (count == 0) {
          console.log("yes count is " + count);
          weekMarkMS =
            moment
              .unix(location.timestampMs / 1000)
              .day(obj.dayStart)
              .hour(0)
              .minute(0)
              .unix() * 1000;
        }
        if (location.timestampMs >= weekMarkMS) {
          for (var i = 0; i < obj.boxes.length; i++) {
            if (
              isInBox(location.latitudeE7, location.longitudeE7, obj.boxes[i])
            ) {
              if (inside[i] === false) {
                inside[i] = true;
                endTimes[i] = location.timestampMs;
              }
            } else {
              if (inside[i] === true) {
                console.log("is inside");
                var startDate = moment
                  .unix(location.timestampMs / 1000)
                  .format("MM-DD-YYYY");
                var startTime = moment
                  .unix(location.timestampMs / 1000)
                  .format("HH:mm");
                var endDate = moment
                  .unix(endTimes[i] / 1000)
                  .format("MM-DD-YYYY");
                var endTime = moment.unix(endTimes[i] / 1000).format("HH:mm");
                var duration =
                  Math.abs(endTimes[i] - location.timestampMs) / 1000 / 3600;
                var entry = [
                  obj.boxes[i].name,
                  startDate,
                  startTime,
                  endDate,
                  endTime,
                  duration,
                  "",
                  location.timestampMs,
                  endTimes[i]
                ];
                csv.push(entry);
                // reset
                inside[i] = false;
                endTimes[i] = 0;
                durations[i] += duration;
              }
            }
          }
        }
        if (location.timestampMs < weekMarkMS) {
          for (var i = 0; i < obj.boxes.length; i++) {
            // go thru boxes
            // if still in, cut at the weekMarkMS
            // start new entry
            // then just reset weekMark
            // still inside at the end of the week
            if (inside[i] === true) {
              // cut at the weekMarkMS time and add an entry
              var startDate = moment
                .unix(weekMarkMS / 1000)
                .format("MM-DD-YYYY");
              var startTime = moment.unix(weekMarkMS / 1000).format("HH:mm");
              var endDate = moment
                .unix(endTimes[i] / 1000)
                .format("MM-DD-YYYY");
              var endTime = moment.unix(endTimes[i] / 1000).format("HH:mm");
              var duration = Math.abs(weekMarkMS - endTimes[i]) / 1000 / 3600;
              durations[i] += duration;
              var entry = [
                obj.boxes[i].name,
                startDate,
                startTime,
                endDate,
                endTime,
                duration,
                "",
                weekMarkMS,
                endTimes[i]
              ];
              csv.push(entry);
              console.log(entry);
              console.log("WEEK END ENTRY CUT");
              // makes sure that endtimes is updated to the new week
              if (
                isInBox(location.latitudeE7, location.longitudeE7, obj.boxes[i])
              ) {
                endTimes[i] = weekMarkMS - 1;
              } else {
                inside[i] = false;
                endTimes[i] = 0;
              }
            }
          }
          var total = 0;
          var str = "";
          for (var i = 0; i < obj.boxes.length; i++) {
            if (durations[i] > 0) {
              total += Math.abs(durations[i]);
              durations[i] = 0;
            }
          }
          var weekEntry = [, , , , , , total];
          if (total > 0) {
            csv.push(weekEntry);
          }
          console.log("PUSHED WEEK");
          weekMarkMS -= 604800000;
        }
        count++;
        return oboe.drop;
      })
      .fail(function(err) {
        console.log(err);
      });
    parseFileToCSV($("#uploadInput").get(0).files[0], newOboe);
  }
});
function isInBox(lat, lng, box) {
  var lat = lat / Math.pow(10, 7);
  var lng = lng / Math.pow(10, 7);
  if (
    lat <= box.neLat &&
    lat >= box.swLat &&
    lng <= box.neLng &&
    lng >= box.swLng
  ) {
    return true;
  } else {
    return false;
  }
}
function processData(boxes, start) {
  var boxKeys = Object.keys(boxes);
  var resBoxArray = [];
  var arr = [1, 2, 3, 4, 5, 6, 7];
  function getIdx(idx) {
    return arr[idx - 2 >= 0 ? idx - 2 : arr.length - 1];
  }
  for (var i = 0; i < boxKeys.length; i++) {
    var parseObj = boxes[boxKeys[i]];
    var bounds = parseObj.rectangle._bounds;
    var ne = bounds._northEast;
    var sw = bounds._southWest;
    var neLat = ne.lat;
    var neLng = ne.lng;
    var swLat = sw.lat;
    var swLng = sw.lng;
    if ($("#expanded").is(":checked")) {
      console.log("EXPANDED");
      swLat -= expansionCoef;
      swLng -= expansionCoef;
      neLat += expansionCoef;
      neLng += expansionCoef;
    }

    console.log(
      "swlat: " +
        swLat +
        "swlng: " +
        swLng +
        "neLat: " +
        neLat +
        "neLng: " +
        neLng
    );
    resBoxArray.push({
      name: parseObj.name,
      neLat: neLat,
      neLng: neLng,
      swLat: swLat,
      swLng: swLng
    });
  }
  return {
    boxes: resBoxArray,
    dayStart: start
  };
}

function parseFileToCSV(file, oboeInstance) {
  var fileSize = file.size;
  var chunkSize = 512 * 1024; // bytes
  var offset = 0;
  var self = this; // we need a reference to the current object
  var chunkReaderBlock = null;
  var startTime = Date.now();
  var endTime = Date.now();
  var readEventHandler = function(evt) {
    if (evt.target.error == null) {
      offset += evt.target.result.length;
      var progress = (100 * offset / fileSize).toFixed(2);
      var trimmed = (100 * offset / fileSize).toFixed(0);
      $("#donecsv")
        .css("width", trimmed + "%")
        .attr("aria-valuenow", trimmed)
        .text(progress + "%");
      // console.log(progress);
      var chunk = evt.target.result;
      oboeInstance.emit("data", chunk); // callback for handling read chunk
    } else {
      console.log("Read error: " + evt.target.error);
      return;
    }
    if (offset >= fileSize) {
      oboeInstance.emit("done");
      console.log("Done reading file");
      endTime = Date.now();
      trimmedCSV = [];
      for (var i = 0; i < csv.length; i++) {
        if (i <= 1) {
          trimmedCSV.push(csv[i]);
        } else {
          // check if locations are the same
          if (csv[i][0] !== "" || trimmedCSV[trimmedCSV.length - 1][0] !== "") {
            if (trimmedCSV[trimmedCSV.length - 1][0] === csv[i][0]) {
              if (
                Math.abs(trimmedCSV[trimmedCSV.length - 1][7] - csv[i][8]) <=
                900000
              ) {
                var old = trimmedCSV[trimmedCSV.length - 1];
                var newentry = csv[i];
                trimmedCSV[trimmedCSV.length - 1] = [
                  newentry[0],
                  newentry[1],
                  newentry[2],
                  old[3],
                  old[4],
                  old[5] + newentry[5],
                  "",
                  newentry[7],
                  old[8]
                ];
              } else {
                trimmedCSV.push(csv[i]);
              }
            } else {
              trimmedCSV.push(csv[i]);
            }
          } else {
            trimmedCSV.push(csv[i]);
          }
        }
      }
      var csvContent = "";
      trimmedCSV.forEach(function(infoArray, index) {
        infoArray = infoArray.slice(0, 7);
        dataString = infoArray.join(",");
        csvContent +=
          index < trimmedCSV.length ? dataString + "\n" : dataString;
      });

      var encodedUri =
        "data:text/csv;charset=utf8," + encodeURIComponent(csvContent);
      var link = document.createElement("a");
      link.setAttribute("href", encodedUri);
      link.setAttribute("download", "" + $("#filename").val() + ".csv");
      document.body.appendChild(link);
      console.log(boxes);
      swal(
        {
          title: "Your file has been created",
          type: "success",
          text: displayBoxesDiv(boxes),
          html: true,
          showCancelButton: true,
          closeOnConfirm: false,
          cancelButtonText: "Edit information",
          confirmButtonText: "Download CSV"
        },
        function(isConfirm) {
          if (isConfirm) {
            link.click();
          } else {
            csv = [
              [
                "name of area",
                "start date",
                "start time",
                "end date",
                "end time",
                "duration (hrs)",
                "total time for week (hrs)"
              ]
            ];
            weekMarkMS = 0;
          }
        }
      );

      return;
    }

    // of to the next chunk
    chunkReaderBlock(offset, chunkSize, file);
  };

  chunkReaderBlock = function(_offset, length, _file) {
    var r = new FileReader();
    var blob = _file.slice(_offset, length + _offset);
    r.onload = readEventHandler;
    r.readAsText(blob);
  };

  // now let's start the read with the first block
  chunkReaderBlock(offset, chunkSize, file);
}
<commit_msg>feat: display box bounds on output. Cannot create a file for that, though, without (I think) upgrading SweetAlert to version 2, which is hard because this app isn't set up with any package management.<commit_after>function displayBoxesDiv(boxes) {
  // function to nicely display the boundaries of the boxes used
  var divString =
    "
  You may save this information about the bounding boxes for your records.  ";
  Object.keys(boxes).map(boxId => {
    console.log(boxId);
    console.log(boxes);
    var box = boxes[boxId];
    divString += "
 " + box.name + "
 ";
    divString +=
      "

 Northeast corner:
 (" +
      box.rectangle._bounds._northEast.lat +
      ", " +
      box.rectangle._bounds._northEast.lng +
      ")

 Southwest corner:
 (" +
      box.rectangle._bounds._southWest.lat +
      ", " +
      box.rectangle._bounds._southWest.lng +
      ")

";
  });
  divString += "
";
  return divString;
}

// INIT CSV
var expansionCoef = 0.002195; // approx amount of degrees = 800 ft
var csv = [
  [
    "name of area",
    "start date",
    "start time",
    "end date",
    "end time",
    "duration (hrs)",
    "total time for week (hrs)"
  ]
];
weekMarkMS = 0;
// On click of submit button start csv generation process
$("#submitProcess").on("click", function(e) {
  var errString = "";
  $("#submitErrors").remove();

  if (Object.keys(boxes).length <= 0) {
    errString += " Please select at least one bounding box.";
  }
  if (!$("#filename").val()) {
    errString += " Please enter a name for your file.";
  }
  if ($("#startDay").val() === "") {
    errString += " Please select a valid start day.";
  }
  if (errString.length > 0) {
    $("#submitProcess").before(
      "

" +
        errString +
        "

"
    );
  } else {
    swal({
      title: "Processing Location Data",
      text:
        'Note this may take a few minutes:

0%
',
      html: true,
      showConfirmButton: false
    });

    var obj = processData(boxes, $("#startDay").val());
    var inside = new Array(obj.boxes.length).fill(false);
    var endTimes = new Array(obj.boxes.length).fill(0);
    var durations = new Array(obj.boxes.length).fill(0);
    var count = 0;
    var newOboe = oboe();
    newOboe
      .node("locations.*", function(location) {
        if (count == 0) {
          console.log("yes count is " + count);
          weekMarkMS =
            moment
              .unix(location.timestampMs / 1000)
              .day(obj.dayStart)
              .hour(0)
              .minute(0)
              .unix() * 1000;
        }
        if (location.timestampMs >= weekMarkMS) {
          for (var i = 0; i < obj.boxes.length; i++) {
            if (
              isInBox(location.latitudeE7, location.longitudeE7, obj.boxes[i])
            ) {
              if (inside[i] === false) {
                inside[i] = true;
                endTimes[i] = location.timestampMs;
              }
            } else {
              if (inside[i] === true) {
                console.log("is inside");
                var startDate = moment
                  .unix(location.timestampMs / 1000)
                  .format("MM-DD-YYYY");
                var startTime = moment
                  .unix(location.timestampMs / 1000)
                  .format("HH:mm");
                var endDate = moment
                  .unix(endTimes[i] / 1000)
                  .format("MM-DD-YYYY");
                var endTime = moment.unix(endTimes[i] / 1000).format("HH:mm");
                var duration =
                  Math.abs(endTimes[i] - location.timestampMs) / 1000 / 3600;
                var entry = [
                  obj.boxes[i].name,
                  startDate,
                  startTime,
                  endDate,
                  endTime,
                  duration,
                  "",
                  location.timestampMs,
                  endTimes[i]
                ];
                csv.push(entry);
                // reset
                inside[i] = false;
                endTimes[i] = 0;
                durations[i] += duration;
              }
            }
          }
        }
        if (location.timestampMs < weekMarkMS) {
          for (var i = 0; i < obj.boxes.length; i++) {
            // go thru boxes
            // if still in, cut at the weekMarkMS
            // start new entry
            // then just reset weekMark
            // still inside at the end of the week
            if (inside[i] === true) {
              // cut at the weekMarkMS time and add an entry
              var startDate = moment
                .unix(weekMarkMS / 1000)
                .format("MM-DD-YYYY");
              var startTime = moment.unix(weekMarkMS / 1000).format("HH:mm");
              var endDate = moment
                .unix(endTimes[i] / 1000)
                .format("MM-DD-YYYY");
              var endTime = moment.unix(endTimes[i] / 1000).format("HH:mm");
              var duration = Math.abs(weekMarkMS - endTimes[i]) / 1000 / 3600;
              durations[i] += duration;
              var entry = [
                obj.boxes[i].name,
                startDate,
                startTime,
                endDate,
                endTime,
                duration,
                "",
                weekMarkMS,
                endTimes[i]
              ];
              csv.push(entry);
              console.log(entry);
              console.log("WEEK END ENTRY CUT");
              // makes sure that endtimes is updated to the new week
              if (
                isInBox(location.latitudeE7, location.longitudeE7, obj.boxes[i])
              ) {
                endTimes[i] = weekMarkMS - 1;
              } else {
                inside[i] = false;
                endTimes[i] = 0;
              }
            }
          }
          var total = 0;
          var str = "";
          for (var i = 0; i < obj.boxes.length; i++) {
            if (durations[i] > 0) {
              total += Math.abs(durations[i]);
              durations[i] = 0;
            }
          }
          var weekEntry = [, , , , , , total];
          if (total > 0) {
            csv.push(weekEntry);
          }
          console.log("PUSHED WEEK");
          weekMarkMS -= 604800000;
        }
        count++;
        return oboe.drop;
      })
      .fail(function(err) {
        console.log(err);
      });
    parseFileToCSV($("#uploadInput").get(0).files[0], newOboe);
  }
});
function isInBox(lat, lng, box) {
  var lat = lat / Math.pow(10, 7);
  var lng = lng / Math.pow(10, 7);
  if (
    lat <= box.neLat &&
    lat >= box.swLat &&
    lng <= box.neLng &&
    lng >= box.swLng
  ) {
    return true;
  } else {
    return false;
  }
}
function processData(boxes, start) {
  var boxKeys = Object.keys(boxes);
  var resBoxArray = [];
  var arr = [1, 2, 3, 4, 5, 6, 7];
  function getIdx(idx) {
    return arr[idx - 2 >= 0 ? idx - 2 : arr.length - 1];
  }
  for (var i = 0; i < boxKeys.length; i++) {
    var parseObj = boxes[boxKeys[i]];
    var bounds = parseObj.rectangle._bounds;
    var ne = bounds._northEast;
    var sw = bounds._southWest;
    var neLat = ne.lat;
    var neLng = ne.lng;
    var swLat = sw.lat;
    var swLng = sw.lng;
    if ($("#expanded").is(":checked")) {
      console.log("EXPANDED");
      swLat -= expansionCoef;
      swLng -= expansionCoef;
      neLat += expansionCoef;
      neLng += expansionCoef;
    }

    console.log(
      "swlat: " +
        swLat +
        "swlng: " +
        swLng +
        "neLat: " +
        neLat +
        "neLng: " +
        neLng
    );
    resBoxArray.push({
      name: parseObj.name,
      neLat: neLat,
      neLng: neLng,
      swLat: swLat,
      swLng: swLng
    });
  }
  return {
    boxes: resBoxArray,
    dayStart: start
  };
}

function parseFileToCSV(file, oboeInstance) {
  var fileSize = file.size;
  var chunkSize = 512 * 1024; // bytes
  var offset = 0;
  var self = this; // we need a reference to the current object
  var chunkReaderBlock = null;
  var startTime = Date.now();
  var endTime = Date.now();
  var readEventHandler = function(evt) {
    if (evt.target.error == null) {
      offset += evt.target.result.length;
      var progress = (100 * offset / fileSize).toFixed(2);
      var trimmed = (100 * offset / fileSize).toFixed(0);
      $("#donecsv")
        .css("width", trimmed + "%")
        .attr("aria-valuenow", trimmed)
        .text(progress + "%");
      // console.log(progress);
      var chunk = evt.target.result;
      oboeInstance.emit("data", chunk); // callback for handling read chunk
    } else {
      console.log("Read error: " + evt.target.error);
      return;
    }
    if (offset >= fileSize) {
      oboeInstance.emit("done");
      console.log("Done reading file");
      endTime = Date.now();
      trimmedCSV = [];
      for (var i = 0; i < csv.length; i++) {
        if (i <= 1) {
          trimmedCSV.push(csv[i]);
        } else {
          // check if locations are the same
          if (csv[i][0] !== "" || trimmedCSV[trimmedCSV.length - 1][0] !== "") {
            if (trimmedCSV[trimmedCSV.length - 1][0] === csv[i][0]) {
              if (
                Math.abs(trimmedCSV[trimmedCSV.length - 1][7] - csv[i][8]) <=
                900000
              ) {
                var old = trimmedCSV[trimmedCSV.length - 1];
                var newentry = csv[i];
                trimmedCSV[trimmedCSV.length - 1] = [
                  newentry[0],
                  newentry[1],
                  newentry[2],
                  old[3],
                  old[4],
                  old[5] + newentry[5],
                  "",
                  newentry[7],
                  old[8]
                ];
              } else {
                trimmedCSV.push(csv[i]);
              }
            } else {
              trimmedCSV.push(csv[i]);
            }
          } else {
            trimmedCSV.push(csv[i]);
          }
        }
      }
      var csvContent = "";
      trimmedCSV.forEach(function(infoArray, index) {
        infoArray = infoArray.slice(0, 7);
        dataString = infoArray.join(",");
        csvContent +=
          index < trimmedCSV.length ? dataString + "\n" : dataString;
      });

      var encodedUri =
        "data:text/csv;charset=utf8," + encodeURIComponent(csvContent);
      var link = document.createElement("a");
      link.setAttribute("href", encodedUri);
      link.setAttribute("download", "" + $("#filename").val() + ".csv");
      document.body.appendChild(link);
      swal(
        {
          title: "Your file has been created, buddy",
          type: "success",
          text: displayBoxesDiv(boxes),
          html: true,
          showCancelButton: true,
          closeOnConfirm: false,
          cancelButtonText: "Edit information",
          confirmButtonText: "Download CSV"
        },
        function(isConfirm) {
          if (isConfirm) {
            link.click();
          } else {
            csv = [
              [
                "name of area",
                "start date",
                "start time",
                "end date",
                "end time",
                "duration (hrs)",
                "total time for week (hrs)"
              ]
            ];
            weekMarkMS = 0;
          }
        }
      );

      return;
    }

    // of to the next chunk
    chunkReaderBlock(offset, chunkSize, file);
  };

  chunkReaderBlock = function(_offset, length, _file) {
    var r = new FileReader();
    var blob = _file.slice(_offset, length + _offset);
    r.onload = readEventHandler;
    r.readAsText(blob);
  };

  // now let's start the read with the first block
  chunkReaderBlock(offset, chunkSize, file);
}
<|endoftext|>


<commit_before>import { SimpleResultProcessing } from "react-filter-box";
import columnAccessor from "../../utils/columnAccessor";

export default class AdvancedResultProcessing extends SimpleResultProcessing {

    constructor(props, columns = false) {
        super(props);
        this.columns = columns;
    }

    filter(row, fieldOrLabel, operator, value) {

        const field = this.tryToGetFieldCategory(fieldOrLabel);
        const searchedValue = value.toLowerCase();
        let originalValue = (row[field] || row[field] === 0) ? row[field].toString().toLowerCase() : ""

        if(this.columns) {
            let column = this.columns.find(function(d) {
                return d.column && d.column === field;
            });

            if(column) {
                const formatter = columnAccessor(column)
                const formattedValue = formatter(row, true)
                originalValue = (formattedValue || formattedValue === 0) ? formattedValue.toString().toLowerCase() : ""
                const formattedValue = columnAccessor(column);
                originalValue = (formattedValue(row, true));
                if(['number', 'string', 'boolean'].includes(typeof(originalValue))) {
                    originalValue = originalValue.toString();
                }
             }
        }

        switch(operator) {
            case "==": return originalValue === searchedValue;
            case "!=": return originalValue !== searchedValue;
            case "contains": return originalValue.indexOf(searchedValue) >=0;
            case "!contains": return originalValue.indexOf(searchedValue) <0;
            case "startsWith": return  originalValue.startsWith(searchedValue) ;
            default:
              return false;

        }
    }
}<commit_msg>Boolean values rendering issues done<commit_after>import { SimpleResultProcessing } from "react-filter-box";
import columnAccessor from "../../utils/columnAccessor";

export default class AdvancedResultProcessing extends SimpleResultProcessing {

    constructor(props, columns = false) {
        super(props);
        this.columns = columns;
    }

    filter(row, fieldOrLabel, operator, value) {

        const field = this.tryToGetFieldCategory(fieldOrLabel);
        const searchedValue = value.toLowerCase();
        let originalValue = (row[field] || row[field] === 0) ? row[field].toString().toLowerCase() : ""

        if(this.columns) {
            let column = this.columns.find(function(d) {
                return d.column && d.column === field;
            });

            if(column) {
                const formattedValue = columnAccessor(column);
                originalValue = (formattedValue(row, true));
                if(['number', 'string', 'boolean'].includes(typeof(originalValue))) {
                    originalValue = originalValue.toString();
                }
            }
        }

        switch(operator) {
            case "==": return originalValue === searchedValue;
            case "!=": return originalValue !== searchedValue;
            case "contains": return originalValue.indexOf(searchedValue) >=0;
            case "!contains": return originalValue.indexOf(searchedValue) <0;
            case "startsWith": return  originalValue.startsWith(searchedValue) ;
            default:
              return false;

        }
    }
}<|endoftext|>


<commit_before>import React from 'react';
import Radium from 'radium';
// import _ from 'lodash';
import Flex from '../framework/Flex';
// import { connect } from 'react-redux';
// import { FOO } from '../actions';
import Awesome from "react-fontawesome";
import VerifiedTwitterIcon from "../framework/verified-twitter-icon";
import colors from "../framework/colors";
import Barchart from "./summary-comment-barchart";

// @connect(state => {
//   return state.FOO;
// })
@Radium
class SummaryComment extends React.Component {
  constructor(props) {
    super(props);
    this.state = {

    };
  }
  static propTypes = {
    /* react */
    // dispatch: React.PropTypes.func,
    params: React.PropTypes.object,
    routes: React.PropTypes.array,
    /* component api */
    style: React.PropTypes.object,
    fb_name: React.PropTypes.string,
    social: React.PropTypes.object,
    // foo: React.PropTypes.string
  }
  static defaultProps = {
    // foo: "bar"
  }

  getRealName() {
    let name = "";

    if (this.props.social && this.props.social.name) {
      name = this.props.social.name;
    }

    if (this.props.social && this.props.social.fb_name) {
      name = this.props.social.fb_name;
    }

    return name;
  }
  getImage() {
    let image = "";
    if (this.props.social && this.props.social.fb_user_id) {
      image = (

      )
    } else if (this.props.social && this.props.social.profile_image_url_https) {
      image = (

      )
    } else if (this.props.social && this.props.social.twitter_profile_image_url_https) {
      image = (

      )
    }
    return image;
  }
  facebookIcon() {
    return (

        <Awesome
          style={{
            fontSize: 14,
            color: "#3b5998",

          }}
          name={"facebook"} />

    );
  }

  followers() {
    const styles = this.getStyles();
    return (
      <a
        target="_blank" href={`https://twitter.com/${this.props.screen_name}`}
        style={styles.twitterLink}>
        <Awesome
          style={styles.twitterIcon}
          name={"twitter"} />

          {this.props.social.followers_count}

    );
  }
  getStats() {
    const styles = this.getStyles();
    let stats;
    if (this.props.majority) {
      /* it's consensus */
      stats = (

          {`${Math.floor(this.props["n-success"] / this.props["n-trials"] * 100)}%`}

      );
    } else {
      /* it's a group, so it's calculated above because complex accessor */
      stats = (

          {`${this.props.percent}%`}

      )
    }
    return stats;
  }
  getStyles() {
    return {
      image: {
        borderRadius: 100,
        height: 30,
        position: "relative",
        top: 10,
        marginRight: 7,
      },
      icons: {
        // marginLeft: this.props.social ? 8 : 0
        // marginLeft: 8

      },
      name: {
        fontStyle: "italic"
      },
      twitterLink: {
        textDecoration: "none",
        fontWeight: 300,
        color: "black",
        marginLeft: this.props.social && this.props.social.fb_user_id ? 10 : 0,
      },
      twitterIcon: {
        fontSize: 16,
        color: "#4099FF",
      },
      followerCount: {
        marginLeft: 5
      },
      percent: {
        color: this.props.agree ? "rgb(46, 204, 113)" : "rgb(231, 76, 60)",
        // padding: "3px 6px",
        // borderRadius: 3,
        // color: "white"
      },
      percentContainer: {
        marginRight: 15,
        minWidth: 45
      },
      commentContainer: {
        fontWeight: 300
      },
      commentText: {
        fontWeight: 300
      },
      container: {
        marginTop: 20,
      }
    };
  }
  render() {
    // social={comments[comment.tid].social}
    // comment={comments[comment.tid].txt}
    const styles = this.getStyles();
    return (
      <Flex
        styleOverrides={styles.container}
        alignItems="baseline"
        justifyContent="flex-start">

          {this.getStats()}

        <Flex alignSelf="baseline">
          {this.getImage()}
        </Flex>

            {this.props.social ? this.getRealName() : "Anonymous"}

            {this.props.social ? " • " : ""}
            {this.props.social && this.props.social.fb_user_id ? this.facebookIcon() : ""}
            {this.props.social && this.props.social.followers_count ? this.followers() : ""}
            {this.props.social && this.props.social.is_verified ? <VerifiedTwitterIcon/> : ""}

          {` • `}

            {this.props.txt}

          {
            !this.props.majority ? <Barchart tid={this.props.tid}/> : ""
          }

      </Flex>
    );
  }
}

export default SummaryComment;
<commit_msg>Adding font awesome to percent for reinforcement, increasing width<commit_after>import React from 'react';
import Radium from 'radium';
// import _ from 'lodash';
import Flex from '../framework/Flex';
// import { connect } from 'react-redux';
// import { FOO } from '../actions';
import Awesome from "react-fontawesome";
import VerifiedTwitterIcon from "../framework/verified-twitter-icon";
import colors from "../framework/colors";
import Barchart from "./summary-comment-barchart";

// @connect(state => {
//   return state.FOO;
// })
@Radium
class SummaryComment extends React.Component {
  constructor(props) {
    super(props);
    this.state = {

    };
  }
  static propTypes = {
    /* react */
    // dispatch: React.PropTypes.func,
    params: React.PropTypes.object,
    routes: React.PropTypes.array,
    /* component api */
    style: React.PropTypes.object,
    fb_name: React.PropTypes.string,
    social: React.PropTypes.object,
    // foo: React.PropTypes.string
  }
  static defaultProps = {
    // foo: "bar"
  }

  getRealName() {
    let name = "";

    if (this.props.social && this.props.social.name) {
      name = this.props.social.name;
    }

    if (this.props.social && this.props.social.fb_name) {
      name = this.props.social.fb_name;
    }

    return name;
  }
  getImage() {
    let image = "";
    if (this.props.social && this.props.social.fb_user_id) {
      image = (

      )
    } else if (this.props.social && this.props.social.profile_image_url_https) {
      image = (

      )
    } else if (this.props.social && this.props.social.twitter_profile_image_url_https) {
      image = (

      )
    }
    return image;
  }
  facebookIcon() {
    return (

        <Awesome
          style={{
            fontSize: 14,
            color: "#3b5998",

          }}
          name={"facebook"} />

    );
  }

  followers() {
    const styles = this.getStyles();
    return (
      <a
        target="_blank" href={`https://twitter.com/${this.props.screen_name}`}
        style={styles.twitterLink}>
        <Awesome
          style={styles.twitterIcon}
          name={"twitter"} />

          {this.props.social.followers_count}

    );
  }
  getStats() {
    const styles = this.getStyles();
    let stats;
    if (this.props.majority) {
      /* it's consensus */
      stats = `${Math.floor(this.props["n-success"] / this.props["n-trials"] * 100)}%`;
    } else {
      /* it's a group, so it's calculated above because complex accessor */
      stats = `${this.props.percent}%`
    }
    return stats;
  }
  getStyles() {
    return {
      image: {
        borderRadius: 100,
        height: 30,
        position: "relative",
        top: 10,
        marginRight: 7,
      },
      icons: {
        // marginLeft: this.props.social ? 8 : 0
        // marginLeft: 8

      },
      name: {
        fontStyle: "italic"
      },
      twitterLink: {
        textDecoration: "none",
        fontWeight: 300,
        color: "black",
        marginLeft: this.props.social && this.props.social.fb_user_id ? 10 : 0,
      },
      twitterIcon: {
        fontSize: 16,
        color: "#4099FF",
      },
      followerCount: {
        marginLeft: 5
      },
      percent: {
        color: this.props.agree ? "rgb(46, 204, 113)" : "rgb(231, 76, 60)",
        // padding: "3px 6px",
        // borderRadius: 3,
        // color: "white"
      },
      percentContainer: {
        marginRight: 15,
        minWidth: 65
      },
      commentContainer: {
        fontWeight: 300
      },
      commentText: {
        fontWeight: 300
      },
      container: {
        marginTop: 20,
      }
    };
  }
  render() {
    // social={comments[comment.tid].social}
    // comment={comments[comment.tid].txt}
    const styles = this.getStyles();
    return (
      <Flex
        styleOverrides={styles.container}
        alignItems="baseline"
        justifyContent="flex-start">

            <Awesome name={this.props.agree ? "check-circle-o" : "ban"}/>
            {` `}
            {this.getStats()}

        <Flex alignSelf="baseline">
          {this.getImage()}
        </Flex>

            {this.props.social ? this.getRealName() : "Anonymous"}

            {this.props.social ? " • " : ""}
            {this.props.social && this.props.social.fb_user_id ? this.facebookIcon() : ""}
            {this.props.social && this.props.social.followers_count ? this.followers() : ""}
            {this.props.social && this.props.social.is_verified ? <VerifiedTwitterIcon/> : ""}

          {` • `}

            {this.props.txt}

          {
            !this.props.majority && this.props.showHowOtherGroupsFelt ? <Barchart tid={this.props.tid}/> : ""
          }

      </Flex>
    );
  }
}

export default SummaryComment;
<|endoftext|>


<commit_before>var TTTApplication = {
  count: 0,
  svgCircle: '<circle cx="5" cy="5" r="4" stroke="black" stroke-width="2" fill-opacity="0" />',
  svgCross: '<line x1="0" y1="0" x2="10" y2="10" style="stroke:purple;stroke-width:2" />' +
    '<line x1="0" y1="10" x2="10" y2="0" style="stroke:purple;stroke-width:2" />',
  svgOpenTag: '<svg width="50%" height="50%" viewBox="0 0 10 10" style="display: block; margin: 0 auto;">',
  svgCloseTag: '</svg>',
  newRow: '

',
  cellsTable: $("table#cells"),
  lastBodyItemQuery: 'table#cells > tbody:last',
  mainDivItemQuery: "div#contents",
  cellClassName: 'cell',
  cellTemplateQuery: '#cell-template',
  firstMoveComputer: false,

  clearTable: function() {
    this.cellsTable.html(this.newRow);
    this.count = 0;
  },

  setup: function(firstMoveComputer) {
    this.firstMoveComputer = firstMoveComputer;
    this.clearTable();
    var cells = new Cells();
    for (var i = 1; i < 10; i++) {
      cells.add([new Cell({
        name: i
      })]);
    }
    var cellsView = new CellsView({
      collection: cells
    });
    cellsView.render();
    if (this.firstMoveComputer) {
      this.computerMove();
    }
  },

  computerMove: function() {
    var cellNumber = II.calculateComputerMove(this.getPositionsArray(), this.count);
    this.makeMove($('.' + this.cellClassName)[cellNumber], true);
  },

  getPositionsArray: function() {
    var positionsArray = ['', '', '', '', '', '', '', '', ''],
      X = 'X',
      O = 'O';

    for (var i = 0; i < 9; i++) {
      if ($('.' + this.cellClassName)[i].innerHTML.indexOf('circle') > 0) {
        positionsArray[i] = O;
      }
      if ($('.' + this.cellClassName)[i].innerHTML.indexOf('line') > 0) {
        positionsArray[i] = X;
      }
    };

    console.log(positionsArray);
    return positionsArray;
  },

  makeMove: function(el, computerMove) {
    if (TTTApplication.count === 9 ||
      el.innerHTML.indexOf('circle') > 0 ||
      el.innerHTML.indexOf('line') > 0) {
      return;
    }

    if (TTTApplication.count++ % 2 === 0) {
      el.innerHTML = TTTApplication.svgOpenTag + TTTApplication.svgCross + TTTApplication.svgCloseTag;
    } else {
      el.innerHTML = TTTApplication.svgOpenTag + TTTApplication.svgCircle + TTTApplication.svgCloseTag;
    }

    if (TTTApplication.count === 9) {
      return true;
    }

    if (TTTApplication.firstMoveComputer && TTTApplication.count % 2 === 0 ||
      (!TTTApplication.firstMoveComputer && !(TTTApplication.count % 2 === 0))) {
      TTTApplication.computerMove();
    }
  }
};
<commit_msg>stopping when game is over is implemented<commit_after>var TTTApplication = {
  count: 0,
  svgCircle: '<circle cx="5" cy="5" r="4" stroke="black" stroke-width="2" fill-opacity="0" />',
  svgCross: '<line x1="0" y1="0" x2="10" y2="10" style="stroke:purple;stroke-width:2" />' +
    '<line x1="0" y1="10" x2="10" y2="0" style="stroke:purple;stroke-width:2" />',
  svgOpenTag: '<svg width="50%" height="50%" viewBox="0 0 10 10" style="display: block; margin: 0 auto;">',
  svgCloseTag: '</svg>',
  newRow: '

',
  cellsTable: $("table#cells"),
  lastBodyItemQuery: 'table#cells > tbody:last',
  mainDivItemQuery: "div#contents",
  cellClassName: 'cell',
  cellTemplateQuery: '#cell-template',
  firstMoveComputer: false,

  clearTable: function() {
    this.cellsTable.html(this.newRow);
    this.count = 0;
  },

  setup: function(firstMoveComputer) {
    this.firstMoveComputer = firstMoveComputer;
    this.clearTable();
    var cells = new Cells();
    for (var i = 1; i < 10; i++) {
      cells.add([new Cell({
        name: i
      })]);
    }
    var cellsView = new CellsView({
      collection: cells
    });
    cellsView.render();
    if (this.firstMoveComputer) {
      this.computerMove();
    }
  },

  computerMove: function() {
    var cellNumber = II.calculateComputerMove(this.getPositionsArray(), this.count);
    this.makeMove($('.' + this.cellClassName)[cellNumber], true);
  },

  getPositionsArray: function() {
    var positionsArray = ['', '', '', '', '', '', '', '', ''],
      X = 'X',
      O = 'O';

    for (var i = 0; i < 9; i++) {
      if ($('.' + this.cellClassName)[i].innerHTML.indexOf('circle') > 0) {
        positionsArray[i] = O;
      }
      if ($('.' + this.cellClassName)[i].innerHTML.indexOf('line') > 0) {
        positionsArray[i] = X;
      }
    };

    return positionsArray;
  },

  makeMove: function(el, computerMove) {
    if (this.isFinished(this.getPositionsArray())) {
      return;
    }

    if (TTTApplication.count === 9 ||
      el.innerHTML.indexOf('circle') > 0 ||
      el.innerHTML.indexOf('line') > 0) {
      return;
    }

    if (TTTApplication.count++ % 2 === 0) {
      el.innerHTML = TTTApplication.svgOpenTag + TTTApplication.svgCross + TTTApplication.svgCloseTag;
    } else {
      el.innerHTML = TTTApplication.svgOpenTag + TTTApplication.svgCircle + TTTApplication.svgCloseTag;
    }

    if (TTTApplication.count === 9) {
      return true;
    }

    if (TTTApplication.firstMoveComputer && TTTApplication.count % 2 === 0 ||
      (!TTTApplication.firstMoveComputer && !(TTTApplication.count % 2 === 0))) {
      TTTApplication.computerMove();
    }
  },

  isFinished: function(positions) {
    var X = 'X',
      O = 'O';
    return (this.isFinishedFor(positions, X) || this.isFinishedFor(positions, O));
  },

  isFinishedFor: function(positions, X) {
    if ((positions[0] === X && positions[1] === X && positions[2] === X) ||
      (positions[3] === X && positions[4] === X && positions[5] === X) ||
      (positions[6] === X && positions[7] === X && positions[8] === X) ||
      (positions[0] === X && positions[3] === X && positions[6] === X) ||
      (positions[1] === X && positions[4] === X && positions[7] === X) ||
      (positions[2] === X && positions[5] === X && positions[8] === X) ||
      (positions[0] === X && positions[4] === X && positions[8] === X) ||
      (positions[2] === X && positions[4] === X && positions[6] === X)) {
      return true;
    }
    return false;
  }
};
<|endoftext|>


<commit_before><commit_msg>show role at summer institute of person<commit_after><|endoftext|>