<commit_before>import d3 from 'd3';
import _ from 'underscore';
import Grapher from './grapher';
import * as Helpers from './visualisation_helpers';

/**
 * Renders Length Distribution of all hits per query
 */

class Graph {
    static name() {
        return 'Length distribution of hits';
    }

    static className() {
        return 'length-distribution';
    }

    static collapseId(props) {
        return 'length_'+props.query.number;
    }

    static dataName(props) {
        return 'length-distribution-'+props.query.id;
    }

    constructor($svg_container, props) {
        this.query = props.query;
        this._seq_type = Helpers.get_seq_type(props.algorithm);
        this.svg_container = $svg_container;
        if (props.algorithm == 'blastx') {
            this.query_length = this.query.length / 3;
        } else if (props.algorithm == 'tblastn') {
            this.query_length = this.query.length * 3;
        } else {
            this.query_length = this.query.length;
        }
        this._margin = {top: 30, right: 25, bottom: 55, left: 12.5};
        this.initiate($svg_container.width(), $svg_container.height());
    }

    initiate(width, height) {
        this._width = width - this._margin.left - this._margin.right;
        this._height = height - this._margin.top - this._margin.bottom;
        this.svg = d3.select(this.svg_container[0]).insert('svg', ':first-child')
            .attr('width', this._width + this._margin.right + this._margin.left)
            .attr('height', this._height + this._margin.top + this._margin.bottom)
            .append('g')
            .attr('transform','translate('+this._margin.left+','+this._margin.top+')');
        this.hit_lengths();
        this.define_scale_and_bins();
        this.update_data();
        this.draw();
    }

    draw() {
        this.draw_rectangles();
        this.draw_query_line();
        this.draw_axes();
        this.setupTooltip();
    }

    define_scale_and_bins() {
        this._scale_x = d3.scale.linear()
            .domain([
                0,
                (d3.max([this.query_length,d3.max(this._data)]) * 1.05)
            ])
            .range([0, this._width]);
        this._bins = d3.layout.histogram()
            .range(this._scale_x.domain())
            .bins(this._scale_x.ticks(50))
            (this._data);
        this._scale_y = d3.scale.linear()
            .domain([0, d3.max(this._bins, function(d) { return d.length; })])
            .range([this._height, 0]);
    }

    hit_lengths() {
        this._data = _.map(this.query.hits, _.iteratee('length'));
    }

    setupTooltip() {
        this.svg_container.find('[data-toggle="tooltip"]').tooltip({
            'placement': 'top', 'container': 'body', 'html': 'true',
            'delay': 0, 'white-space': 'nowrap'
        });
    }

    setupResponsiveness() {
        var currentWidth = $(window).width();
        console.log('cureent '+currentWidth);
        var debounced_draw = _.debounce(_.bind(function () {
            if (currentWidth != $(window).width()) {
                console.log('redraw initiated '+this._height);
                this.draw();
                currentWidth = $(window).width();
            }
        }, this), 125);
        $(window).resize(debounced_draw);
    }

    tick_formatter(seq_type) {
        var ticks = this._scale_x.ticks();
        var format = d3.format('.1f');
        var prefix = d3.formatPrefix(ticks[ticks.length - 1]);
        var suffixes = {amino_acid: 'aa', nucleic_acid: 'bp'};
        return function (d) {
            if (d === 0) { return ; }
            if (_.indexOf(ticks,d) >= 0) {
                if (suffixes[seq_type] == 'aa') {
                    return (d + ' ' + suffixes[seq_type]);
                } else {
                    return (format(prefix.scale(d)) + ' ' + prefix.symbol + suffixes[seq_type]);
                }
            } else {
                return ;
            }
        };
    }

    update_data() {
        var self = this;
        var data2 = [];
        this._bins.map(function (bin) {
            var inner_data = [];
            bin.reverse();
            var y0 = bin.length;
            bin.map(function (d,i) {
                var y1 = bin.length - (i+1);
                var len_index = _.findIndex(self.query.hits, {length: d});
                var item = {
                    value: d,
                    id: self.query.hits[len_index].id,
                    evalue: self.query.hits[len_index].evalue,
                    url: '#Query_'+self.query.number+'_hit_'+self.query.hits[len_index].number,
                    y0: y0,
                    y1: y0 += (y1 - y0),
                    color: Helpers.get_colors_for_evalue(self.query.hits[len_index].evalue,self.query.hits)
                };
                inner_data.push(item);
            });
            var item = {data: inner_data, x: bin.x, dx: bin.dx, length: bin.length};
            data2.push(item);
        });
        this._update_data = data2;
    }

    draw_rectangles() {
        var self = this;
        var bar = this.svg.selectAll('.bar')
            .data(this._update_data)
            .enter().append('g')
            .attr('class', 'g')
            .attr('transform', function(d) {
                return 'translate('+(self._scale_x(d.x)+self._margin.left)+',0)';
            });

        bar.selectAll('rect')
            .data(function (d) { return d.data; })
            .enter().append('a')
            .attr('xlink:href', function(i) { return i.url; })
            .append('rect')
            .attr('class','bar')
            .attr('data-toggle','tooltip')
            .attr('title', function(i) {
                return i.id+' '+'
E value: '+Helpers.prettify_evalue(i.evalue)+'
Length: '+i.value;
            })
            .attr('x', 1)
            .attr('y', function(i) { return (self._scale_y(i.y0)); })
            .attr('width', self._scale_x(this._bins[1].x) - self._scale_x(this._bins[0].x) - 1)
            .attr('height', function (i) { return self._scale_y(i.y1) - self._scale_y(i.y0); })
            .attr('fill', function(i) {
                return i.color;
            });
    }

    draw_query_line() {
        var query_line = this.svg.append('g')
            .attr('class','query_line')
            .attr('transform','translate('+(this._margin.left+this._scale_x(this.query_length))+',0)');

        query_line.append('rect')
            .attr('x',1)
            .attr('class','bar')
            .attr('width',4)
            .attr('height',this._height)
            .style('fill','rgb(95,122,183)');

        query_line.append('text')
            .attr('dy', '0.75em')
            .attr('y', -10)
            .attr('x', 2)
            .attr('text-anchor','start')
            .text('Query')
            .style('fill','#000')
            .attr('transform','rotate(-45)');
    }

    draw_axes() {
        var space, len;
        len = this._scale_y.ticks().length;
        if (len >= 5) {
            space = 5;
        } else {
            space = len;
        }
        var formatter = this.tick_formatter(this._seq_type.subject_seq_type);
        var x_axis = d3.svg.axis()
            .scale(this._scale_x)
            .orient('bottom')
            .ticks(50)
            .tickFormat(formatter);
        var y_axis = d3.svg.axis()
            .scale(this._scale_y)
            .orient('left')
            .tickValues(this._scale_y.ticks(space))
            .tickFormat(function (e) {
                if (Math.floor(e) != e) {
                    return ;
                }
                return e;
            });
        var ticks = this._scale_y.ticks();
        for (var i in ticks) {
            if (ticks[i] % 1 != 0) {
                y_axis.tickValues(d3.range(0, d3.max(this._bins, function(d) { return d.length; })+1));
                break;
            }
        }
        var self = this;
        var xContainer = this.svg.append('g')
            .attr('class', 'axis axis--x')
            .attr('transform', 'translate('+this._margin.left+','+this._height+')')
            .call(x_axis);

        xContainer.selectAll('line').attr('y2',function (d) {
            var ticks = self._scale_x.ticks();
            if (_.indexOf(ticks, d) >= 0) {
                return 7;
            } else {
                return 4;
            }
        });

        xContainer.selectAll('text').style('text-anchor','end')
            .attr('x', '-8px')
            .attr('y', '3px')
            .attr('dy', '0')
            .attr('transform','rotate(-90)');

        var yContainer = this.svg.append('g')
            .attr('class','axis axis--y')
            .attr('transform','translate('+this._margin.left+',0)')
            .call(y_axis);
    }
}

var LengthDistribution = Grapher(Graph);
export default LengthDistribution;
<commit_msg>X and Y axis outer tick fix<commit_after>import d3 from 'd3';
import _ from 'underscore';
import Grapher from './grapher';
import * as Helpers from './visualisation_helpers';

/**
 * Renders Length Distribution of all hits per query
 */

class Graph {
    static name() {
        return 'Length distribution of hits';
    }

    static className() {
        return 'length-distribution';
    }

    static collapseId(props) {
        return 'length_'+props.query.number;
    }

    static dataName(props) {
        return 'length-distribution-'+props.query.id;
    }

    constructor($svg_container, props) {
        this.query = props.query;
        this._seq_type = Helpers.get_seq_type(props.algorithm);
        this.svg_container = $svg_container;
        if (props.algorithm == 'blastx') {
            this.query_length = this.query.length / 3;
        } else if (props.algorithm == 'tblastn') {
            this.query_length = this.query.length * 3;
        } else {
            this.query_length = this.query.length;
        }
        this._margin = {top: 30, right: 25, bottom: 55, left: 12.5};
        this.initiate($svg_container.width(), $svg_container.height());
    }

    initiate(width, height) {
        this._width = width - this._margin.left - this._margin.right;
        this._height = height - this._margin.top - this._margin.bottom;
        this.svg = d3.select(this.svg_container[0]).insert('svg', ':first-child')
            .attr('width', this._width + this._margin.right + this._margin.left)
            .attr('height', this._height + this._margin.top + this._margin.bottom)
            .append('g')
            .attr('transform','translate('+this._margin.left+','+this._margin.top+')');
        this.hit_lengths();
        this.define_scale_and_bins();
        this.update_data();
        this.draw();
    }

    draw() {
        this.draw_rectangles();
        this.draw_query_line();
        this.draw_axes();
        this.setupTooltip();
    }

    define_scale_and_bins() {
        this._scale_x = d3.scale.linear()
            .domain([
                0,
                (d3.max([this.query_length, d3.max(this._data)]) * 1.01)
            ]).nice()
            .range([0, this._width]);
        this._bins = d3.layout.histogram()
            .range(this._scale_x.domain())
            .bins(this._scale_x.ticks(50))
            (this._data);
        this._scale_y = d3.scale.linear()
            .domain([0, d3.max(this._bins, function(d) { return d.length; })])
            .range([this._height, 0]).nice();
    }

    hit_lengths() {
        this._data = _.map(this.query.hits, _.iteratee('length'));
    }

    setupTooltip() {
        this.svg_container.find('[data-toggle="tooltip"]').tooltip({
            'placement': 'top', 'container': 'body', 'html': 'true',
            'delay': 0, 'white-space': 'nowrap'
        });
    }

    setupResponsiveness() {
        var currentWidth = $(window).width();
        console.log('cureent '+currentWidth);
        var debounced_draw = _.debounce(_.bind(function () {
            if (currentWidth != $(window).width()) {
                console.log('redraw initiated '+this._height);
                this.draw();
                currentWidth = $(window).width();
            }
        }, this), 125);
        $(window).resize(debounced_draw);
    }

    tick_formatter(seq_type) {
        var ticks = this._scale_x.ticks();
        var format = d3.format('.1f');
        var prefix = d3.formatPrefix(ticks[ticks.length - 1]);
        var suffixes = {amino_acid: 'aa', nucleic_acid: 'bp'};
        return function (d) {
            if (d === 0) { return ; }
            if (_.indexOf(ticks,d) >= 0) {
                if (suffixes[seq_type] == 'aa') {
                    return (d + ' ' + suffixes[seq_type]);
                } else {
                    return (format(prefix.scale(d)) + ' ' + prefix.symbol + suffixes[seq_type]);
                }
            } else {
                return ;
            }
        };
    }

    update_data() {
        var self = this;
        var data2 = [];
        this._bins.map(function (bin) {
            var inner_data = [];
            bin.reverse();
            var y0 = bin.length;
            bin.map(function (d,i) {
                var y1 = bin.length - (i+1);
                var len_index = _.findIndex(self.query.hits, {length: d});
                var item = {
                    value: d,
                    id: self.query.hits[len_index].id,
                    evalue: self.query.hits[len_index].evalue,
                    url: '#Query_'+self.query.number+'_hit_'+self.query.hits[len_index].number,
                    y0: y0,
                    y1: y0 += (y1 - y0),
                    color: Helpers.get_colors_for_evalue(self.query.hits[len_index].evalue,self.query.hits)
                };
                inner_data.push(item);
            });
            var item = {data: inner_data, x: bin.x, dx: bin.dx, length: bin.length};
            data2.push(item);
        });
        this._update_data = data2;
    }

    draw_rectangles() {
        var self = this;
        var bar = this.svg.selectAll('.bar')
            .data(this._update_data)
            .enter().append('g')
            .attr('class', 'g')
            .attr('transform', function(d) {
                return 'translate('+(self._scale_x(d.x)+self._margin.left)+',0)';
            });

        bar.selectAll('rect')
            .data(function (d) { return d.data; })
            .enter().append('a')
            .attr('xlink:href', function(i) { return i.url; })
            .append('rect')
            .attr('class','bar')
            .attr('data-toggle','tooltip')
            .attr('title', function(i) {
                return i.id+' '+'
E value: '+Helpers.prettify_evalue(i.evalue)+'
Length: '+i.value;
            })
            .attr('x', 1)
            .attr('y', function(i) { return (self._scale_y(i.y0)); })
            .attr('width', self._scale_x(this._bins[1].x) - self._scale_x(this._bins[0].x) - 1)
            .attr('height', function (i) { return self._scale_y(i.y1) - self._scale_y(i.y0); })
            .attr('fill', function(i) {
                return i.color;
            });
    }

    draw_query_line() {
        var query_line = this.svg.append('g')
            .attr('class','query_line')
            .attr('transform','translate('+(this._margin.left+this._scale_x(this.query_length))+',0)');

        query_line.append('rect')
            .attr('x',1)
            .attr('class','bar')
            .attr('width',4)
            .attr('height',this._height)
            .style('fill','rgb(95,122,183)');

        query_line.append('text')
            .attr('dy', '0.75em')
            .attr('y', -10)
            .attr('x', 2)
            .attr('text-anchor','start')
            .text('Query')
            .style('fill','#000')
            .attr('transform','rotate(-45)');
    }

    draw_axes() {
        var space, len;
        len = this._scale_y.ticks().length;
        if (len >= 5) {
            space = 5;
        } else {
            space = len;
        }
        var formatter = this.tick_formatter(this._seq_type.subject_seq_type);
        var x_axis = d3.svg.axis()
            .scale(this._scale_x)
            .orient('bottom')
            .ticks(50)
            .tickFormat(formatter);
        var y_axis = d3.svg.axis()
            .scale(this._scale_y)
            .orient('left')
            .tickValues(this._scale_y.ticks(space))
            .outerTickSize(0)
            .tickFormat(function (e) {
                if (Math.floor(e) != e) {
                    return ;
                }
                return e;
            });
        var ticks = this._scale_y.ticks();
        for (var i in ticks) {
            if (ticks[i] % 1 != 0) {
                y_axis.tickValues(d3.range(0, d3.max(this._bins, function(d) { return d.length; })+1));
                break;
            }
        }
        var self = this;
        var xContainer = this.svg.append('g')
            .attr('class', 'axis axis--x')
            .attr('transform', 'translate('+this._margin.left+','+this._height+')')
            .call(x_axis);

        xContainer.selectAll('line').attr('y2',function (d) {
            var ticks = self._scale_x.ticks();
            if (_.indexOf(ticks, d) >= 0) {
                return 7;
            } else {
                return 4;
            }
        });

        xContainer.selectAll('text').style('text-anchor','end')
            .attr('x', '-8px')
            .attr('y', '3px')
            .attr('dy', '0')
            .attr('transform','rotate(-90)');

        var yContainer = this.svg.append('g')
            .attr('class','axis axis--y')
            .attr('transform','translate('+this._margin.left+',0)')
            .call(y_axis);
    }
}

var LengthDistribution = Grapher(Graph);
export default LengthDistribution;
<|endoftext|>


<commit_before>/*global $, alert, console, document, trym2, window */

var trym2 = {
    lessonNr: 1,
    maxLesson: 1
};

trym2.MAXFILESIZE = 500000; // max size in bytes for file uploads

trym2.inspect = function(obj) {
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            console.log("inspect: " + prop + " : " + obj.prop);
        }
    }
};

trym2.scrollDown = function(area) {
    var mySize = $(area).val().length;
    $(area).scrollTop(mySize);
    return false;
    // Return false to cancel the default link action
};

/* get selected text, or current line, in the textarea #M2In */
trym2.getSelected = function(inputField) {
    var str = $(inputField).val(),
        start = $(inputField)[0].selectionStart,
        end = $(inputField)[0].selectionEnd,
        endPos;
    if (start === end) {
        // grab the current line
        start = 1 + str.lastIndexOf("\n", end - 1);
        endPos = str.indexOf("\n", start);
        if (endPos !== -1) {
            end = endPos;
        } else {
            end = str.length;
        }
    }
    return str.slice(start, end) + "\n";
};

trym2.showTerminal = function() {
    $("#lesson").hide();
    $("#inputarea").show();
    $("#sendBtn").show();
    $("#pageIndex").hide();
    $("#previousBtn").hide();
    $("#nextBtn").hide();
    $("#TOC").hide();
    return false;
};

trym2.loadLesson = function(ell) {
    $("#inputarea").hide();
    var lessonContent = $('[lessonid="' + ell + '"]').html();
    $("#sendBtn").hide();
    $("#previousBtn").show();
    $("#nextBtn").show();
    $("#pageIndex").button("option", "label", trym2.lessonNr + "/" + trym2.maxLesson).show();
    $("#lesson").html(lessonContent).show();
    $("#TOC").hide();
};

trym2.switchLesson = function(incr) {
    //console.log("Current lessonNr " + trym2.lessonNr);
    //console.log("maxlesson " + trym2.maxLesson);
    trym2.lessonNr = trym2.lessonNr + incr;
    if (trym2.lessonNr >= 1 && trym2.lessonNr <= trym2.maxLesson) {
        //console.log("Switch lesson");
        trym2.loadLesson(trym2.lessonNr);
        $("#lesson").scrollTop(0);
    } else {
        trym2.lessonNr = trym2.lessonNr - incr;
        //alert("lesson with " + trym2.lessonNr + "." + incr + " not available");
    }
};

trym2.postMessage = function(url, msg) {
    return function() {
        var xhr = new XMLHttpRequest(); // Create a new XHR
        //console.log( "URL: " + url);
        xhr.open("POST", url); // to POST to url.
        xhr.setRequestHeader("Content-Type", // Specify plain UTF-8 text
                             "text/plain;charset=UTF-8");
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                //console.log( "All ResponseHeaders: " + xhr.getAllResponseHeaders());
                var resHead = xhr.getResponseHeader('notEventSourceError');
                //console.log( "ResponseHeader: " + resHead);
                if (resHead) {
                    console.log("We must have lost the EventSource Stream, redoing it...");
                    //ask for new EventSource and send msg again
                    trym2.startEventSource();
                    setTimeout(function() {
                        trym2.postMessage("/chat", msg)();
                    }, 1000);
                }
            }
        };
        xhr.send(msg); // Send the message
        return true;
    }
};

trym2.sendCallback = function(inputField) {
    return function() {
        var str = trym2.getSelected(inputField);
        trym2.postMessage('/chat', str)();
        return false;
    };
};

trym2.sendOnEnterCallback = function(inputfield) {
    return function(e) {
        if (e.which === 13 && e.shiftKey) {
            e.preventDefault();
            // do not make a line break or remove selected text when sending
            trym2.postMessage('/chat', trym2.getSelected(inputfield))();
        }
    };
};

trym2.helpScreen = function() {
    //console.log("Display Help.");
    $("#help-dialog").dialog('open');
    $("#help-dialog").scrollTop(0);
};

// input: filename with tutorial content
// return a list of lessons title, each wrapped in a div and link,
//
" + title + "

// attach a lesson ID
trym2.getLessonTitles = function(tutorialFile, callback) {
    $("#menuTutorial").load(tutorialFile, function() {
        var h3 = $("
").append($("#menuTutorial title").text());
        var ul = $('
');
        var i = 1;
        $("#menuTutorial h4").each(function() {
            var title = $(this).text();
            ul.append($('
').append("" + title + ""));
            i = i + 1;
            //console.log("Title in m2.js: " + title);
        });
        h3 = h3;
        var div = $("
").append(ul);
        //console.log("All titles: " + titles);
        var out = [h3, div];
        callback(out);
    });
};

trym2.doUpfileClick = function () {
    $("#upfile").click();
};

trym2.doUpload = function () {
    var obj = this;
    var file = obj.files[0];
    var fileName = obj.value.split("\\");
    var formData = new FormData();
    formData.append('file', file);
    console.log("process form " + file );
    console.log(file.size);
    if (file.size > trym2.MAXFILESIZE) {
        alert("Your file is too big to upload.  Sorry!");
        return false;
    }
    $.ajax({
        url: '/upload',
        type: 'POST',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        statusCode: {
            500: function(data) {
                alert("Uploading failed.");
            }
        },
        success: function(data) {
            console.log("File uploaded successfully!" + data);
            alert(fileName +
                  " has been uploaded and you can use it by loading it into your Macaulay2 session (use the input terminal).");

        }
    });
    return false;
}

// Register for notification of new messages using EventSource
trym2.startEventSource = function() {
    if ( !! window.EventSource) {
        var chat = new EventSource("/startSourceEvent");
        chat.addEventListener('image', function(event) {
            var imageUrl = event.origin + event.data;
            console.log("Image coming from: " + event.origin);
            //console.log("We got an image! " + imageUrl);
            if (imageUrl) {
                console.log("We got an image! " + imageUrl);
                $('#graphDialog').html('Click for image');
                $('#graphDialog').dialog();
                $('#newGraph').click(function() {
                    window.open(imageUrl, '_blank', 'height=200,width=200,toolbar=0,location=0,menubar=0');
                    $("#graphDialog").dialog("close");
                    return false;
                });
            }
        }, false);
        chat.addEventListener('viewHelp', function(event) {
            var helpUrl = event.origin + event.data;
            console.log("viewHelp coming from: " + event.origin);
            if (helpUrl) {
                console.log("We got a viewHelp! " + helpUrl);
                window.open(helpUrl, "M2 Help");
            }
        }, false);
        chat.onmessage = function(event) { // When a new message arrives
            var msg = event.data; // Get text from event object
            //console.log(event);
            if (msg !== "") {
                //console.log("We got a chat message: ");
                $("#M2Out").val($("#M2Out").val() + msg);
                trym2.scrollDown("#M2Out");
            }

        }
    }
};

trym2.getAllTitles = function(i, tutorials, next) {
    if ( i < tutorials.length) {
        trym2.getLessonTitles(tutorials[i],  function(list) {
    //

    list[0].addClass("ui-accordion-header ui-helper-reset ui-state-default ui-accordion-header-active ui-state-active ui-corner-top ui-accordion-icons")
//    .attr("id","ui-accordion-accordion-header-1")
//    .attr("role","tab")
//    .attr("aria-controls","ui-accordion-accordion-panel-1")
//    .attr("aria-selected","false")
//    .attr("tabindex","-1")
    .prepend('')
    .click(function() {
    //

      $(this)
        .toggleClass("ui-accordion-header-active ui-state-active ui-corner-all ui-corner-top")
//    .attr("id","ui-accordion-accordion-header-1")
//    .attr("aria-controls","ui-accordion-accordion-panel-0")
//    .attr("aria-selected","true")
//    .attr("tabindex","0")
        .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()
        .next().slideToggle();
      return false;
    })
    .next()
      .hide();
      //

      list[1].addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom")
//    .attr("style","display: block")
//    .attr("aria-labelledby","ui-accordion-accordion-header-1")
//    .attr("role","tabpanel")
//    .attr("aria-expanded","false")
//    .attr("aria-hidden","true");
    		$("#accordion").append(list[0]);
         $("#accordion").append(list[1]);
    		//console.log("Titles: " + titles);
    		trym2.getAllTitles(i+1, tutorials, next);
		});
    } else {
        next();
    }
};

$(document).ready(function() {
    // send server our client.eventStream
    trym2.startEventSource();

    $("button").button();
    $("#previousBtn").button({
        icons: {primary: "ui-icon-arrowthick-1-w" },
        text: false
    });
    $("#nextBtn").button({
        icons: {primary: "ui-icon-arrowthick-1-e" },
        text: false
    });

    $('#M2In').val(
        "Evaluate a line by typing Shift+Enter or by clicking on Evaluate.\nHere are some sample commands:\n---------------\nR = ZZ/101[a,b,c]\nS = ZZ/32003[vars(1..10)]\nQQ[x_1..x_6]\n\nS = ZZ/32003[vars(1..13)]\nres coker vars S\n");

    $(document).on("click", ".submenuItem", function() {
        var i = 1,
            lessonId = $(this).attr('lessonid');
        //console.log("You clicked a submenuItem: " + $(this).html());
        trym2.lessonNr = parseInt(lessonId.match(/\d/g), 10);
        $("#tutorial").html($("#menuTutorial").html());
        $("#tutorial h4").each(function() {
            $(this).parent().attr('lessonid', i); // add an ID to every lesson div
            i = i + 1;
        });
        trym2.maxLesson = i - 1;
        trym2.loadLesson(trym2.lessonNr);
    });

    if ( !! window.EventSource) {
        $('#help-dialog').dialog({
            height: 340,
            width: 460,
            modal: true,
            autoOpen: false
        });
        $('#helpBtn').click(trym2.helpScreen);
    }
    $("#sendBtn").click(trym2.sendCallback('#M2In'));
    $('#M2In').keypress(trym2.sendOnEnterCallback('#M2In'));
    $("#resetBtn").click(trym2.postMessage('/restart'));
    $("#interruptBtn").click(trym2.postMessage('/interrupt'));
    $("#terminalBtn").click(trym2.showTerminal);
    $(document).on("click", "#inputTerminalLink", trym2.showTerminal);
    $("#uploadBtn").click(trym2.doUpfileClick);
    $("#upfile").change(trym2.doUpload);

    $("#showLessonBtn").click(function() {
        trym2.loadLesson(trym2.lessonNr);
        //console.log("lesson!");
    });

    $("#TOCBtn").click(function(){
        $("#inputarea").hide();
        $("#sendBtn").hide();
        $("#lesson").hide();
        $("#pageIndex").hide();
        $("#previousBtn").hide();
        $("#nextBtn").hide();
        $("#TOC").show();
    });

    $(document).on("click", "code", function() {
        $(this).effect("highlight", {
            color: 'red'
        }, 300);
        var code = $(this).text();
        code = code + "\n";
        $("#M2In").val($("#M2In").val() + code);
        trym2.scrollDown("#M2In");
        trym2.postMessage('/chat', code)();
    });

    $("#inputarea").hide();
    $("#TOC").hide();
    $("#sendBtn").hide();
    $("#pageIndex").hide();
    $("#previousBtn").hide();
    $("#nextBtn").hide();

    var tutorials = ["tutorials/welcome.html", "tutorials/Beginning.html", "tutorials/Beginning.html"];
    $("#TOC").append("

");

    trym2.getAllTitles(0, tutorials, function() {
        console.log("accordion()");
    	$("#accordion").addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist");
    });

    var lessonContent = $('[lessonid="' + trym2.lessonNr + '"]').html();
    $("#lesson").html(lessonContent).show();

    trym2.maxLesson = $('#tutorial').children().length;
    //console.log("maxLesson: " + trym2.maxLesson);

    $("#nextBtn").click(function() {
        trym2.switchLesson(1);
    });
    $("#previousBtn").click(function() {
        trym2.switchLesson(-1);
    });

    // swipe changed to swipeXXX to remove functionality for testing
    $(function() {
        $("#leftwindow").bind("swipeXXX", function(event, info) {
            if (info.direction === "left") {
                trym2.switchLesson(1);
            } else if (info.direction === "right") {
                trym2.switchLesson(-1);
            } else {
                alert("swiped: huh?");
            }
        });
    });
});

<commit_msg>Now all Tutorials are hidden at start.<commit_after>/*global $, alert, console, document, trym2, window */

var trym2 = {
    lessonNr: 1,
    maxLesson: 1
};

trym2.MAXFILESIZE = 500000; // max size in bytes for file uploads

trym2.inspect = function(obj) {
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            console.log("inspect: " + prop + " : " + obj.prop);
        }
    }
};

trym2.scrollDown = function(area) {
    var mySize = $(area).val().length;
    $(area).scrollTop(mySize);
    return false;
    // Return false to cancel the default link action
};

/* get selected text, or current line, in the textarea #M2In */
trym2.getSelected = function(inputField) {
    var str = $(inputField).val(),
        start = $(inputField)[0].selectionStart,
        end = $(inputField)[0].selectionEnd,
        endPos;
    if (start === end) {
        // grab the current line
        start = 1 + str.lastIndexOf("\n", end - 1);
        endPos = str.indexOf("\n", start);
        if (endPos !== -1) {
            end = endPos;
        } else {
            end = str.length;
        }
    }
    return str.slice(start, end) + "\n";
};

trym2.showTerminal = function() {
    $("#lesson").hide();
    $("#inputarea").show();
    $("#sendBtn").show();
    $("#pageIndex").hide();
    $("#previousBtn").hide();
    $("#nextBtn").hide();
    $("#TOC").hide();
    return false;
};

trym2.loadLesson = function(ell) {
    $("#inputarea").hide();
    var lessonContent = $('[lessonid="' + ell + '"]').html();
    $("#sendBtn").hide();
    $("#previousBtn").show();
    $("#nextBtn").show();
    $("#pageIndex").button("option", "label", trym2.lessonNr + "/" + trym2.maxLesson).show();
    $("#lesson").html(lessonContent).show();
    $("#TOC").hide();
};

trym2.switchLesson = function(incr) {
    //console.log("Current lessonNr " + trym2.lessonNr);
    //console.log("maxlesson " + trym2.maxLesson);
    trym2.lessonNr = trym2.lessonNr + incr;
    if (trym2.lessonNr >= 1 && trym2.lessonNr <= trym2.maxLesson) {
        //console.log("Switch lesson");
        trym2.loadLesson(trym2.lessonNr);
        $("#lesson").scrollTop(0);
    } else {
        trym2.lessonNr = trym2.lessonNr - incr;
        //alert("lesson with " + trym2.lessonNr + "." + incr + " not available");
    }
};

trym2.postMessage = function(url, msg) {
    return function() {
        var xhr = new XMLHttpRequest(); // Create a new XHR
        //console.log( "URL: " + url);
        xhr.open("POST", url); // to POST to url.
        xhr.setRequestHeader("Content-Type", // Specify plain UTF-8 text
                             "text/plain;charset=UTF-8");
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                //console.log( "All ResponseHeaders: " + xhr.getAllResponseHeaders());
                var resHead = xhr.getResponseHeader('notEventSourceError');
                //console.log( "ResponseHeader: " + resHead);
                if (resHead) {
                    console.log("We must have lost the EventSource Stream, redoing it...");
                    //ask for new EventSource and send msg again
                    trym2.startEventSource();
                    setTimeout(function() {
                        trym2.postMessage("/chat", msg)();
                    }, 1000);
                }
            }
        };
        xhr.send(msg); // Send the message
        return true;
    }
};

trym2.sendCallback = function(inputField) {
    return function() {
        var str = trym2.getSelected(inputField);
        trym2.postMessage('/chat', str)();
        return false;
    };
};

trym2.sendOnEnterCallback = function(inputfield) {
    return function(e) {
        if (e.which === 13 && e.shiftKey) {
            e.preventDefault();
            // do not make a line break or remove selected text when sending
            trym2.postMessage('/chat', trym2.getSelected(inputfield))();
        }
    };
};

trym2.helpScreen = function() {
    //console.log("Display Help.");
    $("#help-dialog").dialog('open');
    $("#help-dialog").scrollTop(0);
};

// input: filename with tutorial content
// return a list of lessons title, each wrapped in a div and link,
//
" + title + "

// attach a lesson ID
trym2.getLessonTitles = function(tutorialFile, callback) {
    $("#menuTutorial").load(tutorialFile, function() {
        var h3 = $("
").append($("#menuTutorial title").text());
        var ul = $('
');
        var i = 1;
        $("#menuTutorial h4").each(function() {
            var title = $(this).text();
            ul.append($('
').append("" + title + ""));
            i = i + 1;
            //console.log("Title in m2.js: " + title);
        });
        h3 = h3;
        var div = $("
").append(ul);
        //console.log("All titles: " + titles);
        var out = [h3, div];
        callback(out);
    });
};

trym2.doUpfileClick = function () {
    $("#upfile").click();
};

trym2.doUpload = function () {
    var obj = this;
    var file = obj.files[0];
    var fileName = obj.value.split("\\");
    var formData = new FormData();
    formData.append('file', file);
    console.log("process form " + file );
    console.log(file.size);
    if (file.size > trym2.MAXFILESIZE) {
        alert("Your file is too big to upload.  Sorry!");
        return false;
    }
    $.ajax({
        url: '/upload',
        type: 'POST',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        statusCode: {
            500: function(data) {
                alert("Uploading failed.");
            }
        },
        success: function(data) {
            console.log("File uploaded successfully!" + data);
            alert(fileName +
                  " has been uploaded and you can use it by loading it into your Macaulay2 session (use the input terminal).");

        }
    });
    return false;
}

// Register for notification of new messages using EventSource
trym2.startEventSource = function() {
    if ( !! window.EventSource) {
        var chat = new EventSource("/startSourceEvent");
        chat.addEventListener('image', function(event) {
            var imageUrl = event.origin + event.data;
            console.log("Image coming from: " + event.origin);
            //console.log("We got an image! " + imageUrl);
            if (imageUrl) {
                console.log("We got an image! " + imageUrl);
                $('#graphDialog').html('Click for image');
                $('#graphDialog').dialog();
                $('#newGraph').click(function() {
                    window.open(imageUrl, '_blank', 'height=200,width=200,toolbar=0,location=0,menubar=0');
                    $("#graphDialog").dialog("close");
                    return false;
                });
            }
        }, false);
        chat.addEventListener('viewHelp', function(event) {
            var helpUrl = event.origin + event.data;
            console.log("viewHelp coming from: " + event.origin);
            if (helpUrl) {
                console.log("We got a viewHelp! " + helpUrl);
                window.open(helpUrl, "M2 Help");
            }
        }, false);
        chat.onmessage = function(event) { // When a new message arrives
            var msg = event.data; // Get text from event object
            //console.log(event);
            if (msg !== "") {
                //console.log("We got a chat message: ");
                $("#M2Out").val($("#M2Out").val() + msg);
                trym2.scrollDown("#M2Out");
            }

        }
    }
};

trym2.getAllTitles = function(i, tutorials, next) {
    if ( i < tutorials.length) {
        trym2.getLessonTitles(tutorials[i],  function(list) {
    //

    list[0].addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-accordion-icons")
//    .attr("id","ui-accordion-accordion-header-1")
//    .attr("role","tab")
//    .attr("aria-controls","ui-accordion-accordion-panel-1")
//    .attr("aria-selected","false")
//    .attr("tabindex","-1")
    .prepend('')
    .click(function() {
    //

      $(this)
        .toggleClass("ui-accordion-header-active ui-state-active ui-corner-all ui-corner-top")
//    .attr("id","ui-accordion-accordion-header-1")
//    .attr("aria-controls","ui-accordion-accordion-panel-0")
//    .attr("aria-selected","true")
//    .attr("tabindex","0")
        .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()
        .next().slideToggle();
      return false;
    })
    .next();
      //.hide();
      //

      list[1].addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide();
//    .attr("style","display: block")
//    .attr("aria-labelledby","ui-accordion-accordion-header-1")
//    .attr("role","tabpanel")
//    .attr("aria-expanded","false")
//    .attr("aria-hidden","true");
    		$("#accordion").append(list[0]);
         $("#accordion").append(list[1]);
    		//console.log("Titles: " + titles);
    		trym2.getAllTitles(i+1, tutorials, next);
		});
    } else {
        next();
    }
};

$(document).ready(function() {
    // send server our client.eventStream
    trym2.startEventSource();

    $("button").button();
    $("#previousBtn").button({
        icons: {primary: "ui-icon-arrowthick-1-w" },
        text: false
    });
    $("#nextBtn").button({
        icons: {primary: "ui-icon-arrowthick-1-e" },
        text: false
    });

    $('#M2In').val(
        "Evaluate a line by typing Shift+Enter or by clicking on Evaluate.\nHere are some sample commands:\n---------------\nR = ZZ/101[a,b,c]\nS = ZZ/32003[vars(1..10)]\nQQ[x_1..x_6]\n\nS = ZZ/32003[vars(1..13)]\nres coker vars S\n");

    $(document).on("click", ".submenuItem", function() {
        var i = 1,
            lessonId = $(this).attr('lessonid');
        //console.log("You clicked a submenuItem: " + $(this).html());
        trym2.lessonNr = parseInt(lessonId.match(/\d/g), 10);
        $("#tutorial").html($("#menuTutorial").html());
        $("#tutorial h4").each(function() {
            $(this).parent().attr('lessonid', i); // add an ID to every lesson div
            i = i + 1;
        });
        trym2.maxLesson = i - 1;
        trym2.loadLesson(trym2.lessonNr);
    });

    if ( !! window.EventSource) {
        $('#help-dialog').dialog({
            height: 340,
            width: 460,
            modal: true,
            autoOpen: false
        });
        $('#helpBtn').click(trym2.helpScreen);
    }
    $("#sendBtn").click(trym2.sendCallback('#M2In'));
    $('#M2In').keypress(trym2.sendOnEnterCallback('#M2In'));
    $("#resetBtn").click(trym2.postMessage('/restart'));
    $("#interruptBtn").click(trym2.postMessage('/interrupt'));
    $("#terminalBtn").click(trym2.showTerminal);
    $(document).on("click", "#inputTerminalLink", trym2.showTerminal);
    $("#uploadBtn").click(trym2.doUpfileClick);
    $("#upfile").change(trym2.doUpload);

    $("#showLessonBtn").click(function() {
        trym2.loadLesson(trym2.lessonNr);
        //console.log("lesson!");
    });

    $("#TOCBtn").click(function(){
        $("#inputarea").hide();
        $("#sendBtn").hide();
        $("#lesson").hide();
        $("#pageIndex").hide();
        $("#previousBtn").hide();
        $("#nextBtn").hide();
        $("#TOC").show();
    });

    $(document).on("click", "code", function() {
        $(this).effect("highlight", {
            color: 'red'
        }, 300);
        var code = $(this).text();
        code = code + "\n";
        $("#M2In").val($("#M2In").val() + code);
        trym2.scrollDown("#M2In");
        trym2.postMessage('/chat', code)();
    });

    $("#inputarea").hide();
    $("#TOC").hide();
    $("#sendBtn").hide();
    $("#pageIndex").hide();
    $("#previousBtn").hide();
    $("#nextBtn").hide();

    var tutorials = ["tutorials/welcome.html", "tutorials/Beginning.html", "tutorials/Beginning.html"];
    $("#TOC").append("

");

    trym2.getAllTitles(0, tutorials, function() {
        console.log("accordion()");
    	$("#accordion").addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist");
    });

    var lessonContent = $('[lessonid="' + trym2.lessonNr + '"]').html();
    $("#lesson").html(lessonContent).show();

    trym2.maxLesson = $('#tutorial').children().length;
    //console.log("maxLesson: " + trym2.maxLesson);

    $("#nextBtn").click(function() {
        trym2.switchLesson(1);
    });
    $("#previousBtn").click(function() {
        trym2.switchLesson(-1);
    });

    // swipe changed to swipeXXX to remove functionality for testing
    $(function() {
        $("#leftwindow").bind("swipeXXX", function(event, info) {
            if (info.direction === "left") {
                trym2.switchLesson(1);
            } else if (info.direction === "right") {
                trym2.switchLesson(-1);
            } else {
                alert("swiped: huh?");
            }
        });
    });
});

<|endoftext|>


<commit_before>'use strict';

angular.module('theLawFactory')
.directive('lawlist', ['$location', '$rootScope', 'api',
function ($location, $rootScope, api) {
    return {
        restrict: 'A',
        replace: false,
        link: function postLink(scope) {
            function update() {
                api.getLawlist().then(function (data) {
                    // Process data to a list of law object
                    // with properties' names set by headers
                    var rows = data.split(/[\r\n]+/).filter(function(x) { return x.trim(); }),
                    headers = rows.splice(0, 1)[0].split(";").map(function (x) {
                        return x.replace(/(^"|"$)/g, '')
                    }),
                    laws = $.map(rows, function (row) {
                        var law = {}, lawdata = row.split(';').map(function (x) {
                            return x.replace(/(^"|"$)/g, '')
                        });
                        $.each(headers, function (i, header) {
                            law[header] = lawdata[i];
                        });
                        law.searchable = thelawfactory.utils.searchableLaw(law);
                        return law;
                    }).sort(function (a, b) {
                        return b["Date de promulgation"] > a["Date de promulgation"];
                    });

                    $rootScope.lawlist = laws;

                    $("#search").mouseenter(function () {
                        $(".form-law").css('opacity', 1);
                    }).mouseleave(function () {
                        $(".form-law").css('opacity', 0.3);
                    }).autocomplete({
                        source: function (request, response) {
                            if (request.term.length < 3) return response([]);
                            var matcher = new RegExp($.ui.autocomplete.escapeRegex(thelawfactory.utils.clean_accents(request.term)), "i");
                            response($.map($.grep(laws, function (value) { return matcher.test(value.searchable); }), function (n) {
                                return {
                                    "label": (n.short_title || "").replace(/ \([^)]*\)/g, '') + " (" + (n.loi_dite ? n.loi_dite + " : " : "") + n.Titre + ")",
                                    "value": n.id,
                                    "themes": n["Thèmes"],
                                    "amendements": n.total_amendements,
                                    "words": n.total_mots,
                                    "dates": n["Date initiale"] + (n["Date de promulgation"] ? " → " + n["Date de promulgation"] : "")
                                }
                            }));
                        },
                        focus: function (event, ui) {
                            $(".form-law").css('opacity', 1);
                            event.preventDefault();
                            $(".src-fcs").removeClass("src-fcs");
                            $("." + ui.item.value).addClass("src-fcs");
                        },
                        open: function () {
                            $(".form-law").css('opacity', 1);
                            var h = $(".ui-autocomplete").position().top;
                            $(".ui-autocomplete").css({
                                'max-height': $(window).height() - h - 100,
                                'overflow-y': 'scroll'
                            });
                        },
                        close: function () {
                            $(".form-law").css('opacity', 0.3);
                            $('#header-search .message').text('');
                        },
                        appendTo: ".lawlist",
                        select: function (event, ui) {
                            $rootScope.$apply(function () {
                                $location.path(($location.path() === '/lois.html' ? 'loi' : 'article') + "s.html");
                                $location.search("loi=" + ui.item.value);
                                $(".form-law").css('opacity', 0.3);
                                $('#navbar-form .message').text('');
                            });
                        },
                        messages: {
                            noResults: function () {
                                var msg = 'Aucune loi trouvée';
                                $('#navbar-form .message').text(msg);
                                return msg;
                            },
                            results: function (d) {
                                var msg = d + " loi" + (d > 1 ? "s trouvées" : " trouvée");
                                $('#navbar-form .message').text(msg);
                                return msg;
                            }
                        }
                    })
                    .data("ui-autocomplete")._renderItem = function (ul, item) {
                        var themesdiv = $("
");
                        (item.themes || "").replace(/ et /g, ', ').split(', ').forEach(function (e) {
                            themesdiv.append(" " + e.toLowerCase() + " ");
                        });

                        var icodiv = $("
")
                            .append('
 ' + item.dates + "
")
                            .append('
 ' + item.amendements + "
")
                            .append('
 ' + 1000 * (Math.round(item.words / 1000.)) + "
")
                            .append(themesdiv);
                        $(".search").tooltip({ container: 'body' });

                        var txtdiv = $("
")
                            .append("" + item.label + "")
                            .append(icodiv);

                        return $("
")
                            .append(txtdiv)
                            .appendTo(ul);
                    };
                }, function () {
                    scope.display_error("impossible de trouver les données de recherche sur les textes");
                })
            }

            update();
        }
    }
}]);
<commit_msg>fix themes display in search bar<commit_after>'use strict';

angular.module('theLawFactory')
.directive('lawlist', ['$location', '$rootScope', 'api',
function ($location, $rootScope, api) {
    return {
        restrict: 'A',
        replace: false,
        link: function postLink(scope) {
            function update() {
                api.getLawlist().then(function (data) {
                    // Process data to a list of law object
                    // with properties' names set by headers
                    var rows = data.split(/[\r\n]+/).filter(function(x) { return x.trim(); }),
                    headers = rows.splice(0, 1)[0].split(";").map(function (x) {
                        return x.replace(/(^"|"$)/g, '')
                    }),
                    laws = $.map(rows, function (row) {
                        var law = {}, lawdata = row.split(';').map(function (x) {
                            return x.replace(/(^"|"$)/g, '')
                        });
                        $.each(headers, function (i, header) {
                            law[header] = lawdata[i];
                        });
                        law.searchable = thelawfactory.utils.searchableLaw(law);
                        return law;
                    }).sort(function (a, b) {
                        return b["Date de promulgation"] > a["Date de promulgation"];
                    });

                    $rootScope.lawlist = laws;

                    $("#search").mouseenter(function () {
                        $(".form-law").css('opacity', 1);
                    }).mouseleave(function () {
                        $(".form-law").css('opacity', 0.3);
                    }).autocomplete({
                        source: function (request, response) {
                            if (request.term.length < 3) return response([]);
                            var matcher = new RegExp($.ui.autocomplete.escapeRegex(thelawfactory.utils.clean_accents(request.term)), "i");
                            response($.map($.grep(laws, function (value) { return matcher.test(value.searchable); }), function (n) {
                                return {
                                    "label": (n.short_title || "").replace(/ \([^)]*\)/g, '') + " (" + (n.loi_dite ? n.loi_dite + " : " : "") + n.Titre + ")",
                                    "value": n.id,
                                    "themes": n["Thèmes"],
                                    "amendements": n.total_amendements,
                                    "words": n.total_mots,
                                    "dates": n["Date initiale"] + (n["Date de promulgation"] ? " → " + n["Date de promulgation"] : "")
                                }
                            }));
                        },
                        focus: function (event, ui) {
                            $(".form-law").css('opacity', 1);
                            event.preventDefault();
                            $(".src-fcs").removeClass("src-fcs");
                            $("." + ui.item.value).addClass("src-fcs");
                        },
                        open: function () {
                            $(".form-law").css('opacity', 1);
                            var h = $(".ui-autocomplete").position().top;
                            $(".ui-autocomplete").css({
                                'max-height': $(window).height() - h - 100,
                                'overflow-y': 'scroll'
                            });
                        },
                        close: function () {
                            $(".form-law").css('opacity', 0.3);
                            $('#header-search .message').text('');
                        },
                        appendTo: ".lawlist",
                        select: function (event, ui) {
                            $rootScope.$apply(function () {
                                $location.path(($location.path() === '/lois.html' ? 'loi' : 'article') + "s.html");
                                $location.search("loi=" + ui.item.value);
                                $(".form-law").css('opacity', 0.3);
                                $('#navbar-form .message').text('');
                            });
                        },
                        messages: {
                            noResults: function () {
                                var msg = 'Aucune loi trouvée';
                                $('#navbar-form .message').text(msg);
                                return msg;
                            },
                            results: function (d) {
                                var msg = d + " loi" + (d > 1 ? "s trouvées" : " trouvée");
                                $('#navbar-form .message').text(msg);
                                return msg;
                            }
                        }
                    })
                    .data("ui-autocomplete")._renderItem = function (ul, item) {
                        var themesdiv = $("
");
                        (item.themes || "").split(',').forEach(function (e) {
                            themesdiv.append(" " + e.toLowerCase() + " ");
                        });

                        var icodiv = $("
")
                            .append('
 ' + item.dates + "
")
                            .append('
 ' + item.amendements + "
")
                            .append('
 ' + 1000 * (Math.round(item.words / 1000.)) + "
")
                            .append(themesdiv);
                        $(".search").tooltip({ container: 'body' });

                        var txtdiv = $("
")
                            .append("" + item.label + "")
                            .append(icodiv);

                        return $("
")
                            .append(txtdiv)
                            .appendTo(ul);
                    };
                }, function () {
                    scope.display_error("impossible de trouver les données de recherche sur les textes");
                })
            }

            update();
        }
    }
}]);
<|endoftext|>


<commit_before>var ReadyList = [];
$(document).ready(function () {
    if(ReadyList && (ReadyList instanceof Array)) {
        for (var a=0;a<ReadyList.length;a++) {
            ReadyList[a]();
        }
    }
});
ReadyList.push(function() {
    var sEl,
        today=new Date(),
        tickerTime=2,
        BigDay=new Date("November 6, 2013"),
        msPerDay=24*60*60*1000,
        timeLeft=(BigDay.getTime()-today.getTime()),
        e_daysLeft=timeLeft/msPerDay,
        daysLeft=Math.floor(e_daysLeft)-1,
        startDays = daysLeft + 5,

        now = new Date(),
        sVal = startDays,
        tickCount = 0,
        tickerTimeFlip = 0,

        pad = function(val) {
            var ret = '0' + val;
            return ret.substring(ret.length-2);
        },
        initFlip = function(el,val) {
            el.flip = true;
            el.flipCount = 1;
            $(el).addClass('ani1');
            $(el.ani).removeClass('hide');
            el.top.num.innerHTML = val;
        },
        checkFlip = function (el,val) {
            if(el.flip) {
                //	tickerTimeFlip = tickerTimeFlip - 1;
                //	if (tickerTimeFlip < 1) tickerTimeFlip = 1;

                //		if (Math.log(tickerTimeFlip) <= 3.5){
                $(el).removeClass('ani'+el.flipCount);
                el.flipCount += el.flipDir;
                if(el.flipCount > 4) {
                    el.flipDir = -1;
                    el.flipCount = 4;
                    $(el).addClass('ani'+el.flipCount);
                    $(el.ani).removeClass('top').addClass('bottom');
                    el.ani.num.innerHTML = val;

                }
                else if (el.flipCount == 0) {
                    el.flipDir = 1;
                    $(el.ani).removeClass('bottom').addClass('top').addClass('hide');
                    el.btm.num.innerHTML = val;
                    el.flip = false;
                }
                else {
                    $(el).addClass('ani'+el.flipCount);
                }
                //	tickerTimeFlip = (startDays - daysLeft) - (sVal-daysLeft) / (startDays-daysLeft) * 150;

                //	}
            }
        },
        checkTime = function() {
            now = new Date();
            //	tickerTime = tickerTime - 1;
            //if (tickerTime < 1) tickerTime = 1;
            if (!sEl.flip){// && Math.log(tickerTime) <= 1) {
                oldSVal = sVal;
                sVal = (--sVal <= daysLeft)?(++sVal):(sVal);
                if (oldSVal != sVal) initFlip(sEl,pad(sVal));
                //	tickerTime = (startDays - daysLeft) - (sVal-daysLeft) / (startDays-daysLeft) * 150;
            }

        },
        tick = function() {
            checkFlip(sEl,pad(sVal));
            checkTime();
        };
    $('#sec,#min,#hou').each(function() {
        this.ani = $('.front',this).get(0);
        this.ani.num = $('span',this.ani).get(0);
        this.top = $('.top.back',this).get(0);
        this.top.num = $('span',this.top).get(0);
        this.btm = $('.bottom.back',this).get(0);
        this.btm.num = $('span',this.btm).get(0);
        this.flip = false;
        this.flipCount = 0;
        this.flipDir = 1;
        if (this.id == 'sec') {
            sEl = this;
            this.ani.num.innerHTML = this.top.num.innerHTML = this.btm.num.innerHTML = pad(sVal);
        }
    });
    tickTimer = window.setInterval(tick,30);
});
<commit_msg>minor day calculation fix<commit_after>var ReadyList = [];
$(document).ready(function () {
    if(ReadyList && (ReadyList instanceof Array)) {
        for (var a=0;a<ReadyList.length;a++) {
            ReadyList[a]();
        }
    }
});
ReadyList.push(function() {
    var sEl,
        today=new Date(),
        tickerTime=2,
        BigDay=new Date("November 6, 2013"),
        msPerDay=24*60*60*1000,
        timeLeft=(BigDay.getTime()-today.getTime()),
        e_daysLeft=timeLeft/msPerDay,
        daysLeft=Math.floor(e_daysLeft),
        startDays = daysLeft + 5,

        now = new Date(),
        sVal = startDays,
        tickCount = 0,
        tickerTimeFlip = 0,

        pad = function(val) {
            var ret = '0' + val;
            return ret.substring(ret.length-2);
        },
        initFlip = function(el,val) {
            el.flip = true;
            el.flipCount = 1;
            $(el).addClass('ani1');
            $(el.ani).removeClass('hide');
            el.top.num.innerHTML = val;
        },
        checkFlip = function (el,val) {
            if(el.flip) {
                //	tickerTimeFlip = tickerTimeFlip - 1;
                //	if (tickerTimeFlip < 1) tickerTimeFlip = 1;

                //		if (Math.log(tickerTimeFlip) <= 3.5){
                $(el).removeClass('ani'+el.flipCount);
                el.flipCount += el.flipDir;
                if(el.flipCount > 4) {
                    el.flipDir = -1;
                    el.flipCount = 4;
                    $(el).addClass('ani'+el.flipCount);
                    $(el.ani).removeClass('top').addClass('bottom');
                    el.ani.num.innerHTML = val;

                }
                else if (el.flipCount == 0) {
                    el.flipDir = 1;
                    $(el.ani).removeClass('bottom').addClass('top').addClass('hide');
                    el.btm.num.innerHTML = val;
                    el.flip = false;
                }
                else {
                    $(el).addClass('ani'+el.flipCount);
                }
                //	tickerTimeFlip = (startDays - daysLeft) - (sVal-daysLeft) / (startDays-daysLeft) * 150;

                //	}
            }
        },
        checkTime = function() {
            now = new Date();
            //	tickerTime = tickerTime - 1;
            //if (tickerTime < 1) tickerTime = 1;
            if (!sEl.flip){// && Math.log(tickerTime) <= 1) {
                oldSVal = sVal;
                sVal = (--sVal <= daysLeft)?(++sVal):(sVal);
                if (oldSVal != sVal) initFlip(sEl,pad(sVal));
                //	tickerTime = (startDays - daysLeft) - (sVal-daysLeft) / (startDays-daysLeft) * 150;
            }

        },
        tick = function() {
            checkFlip(sEl,pad(sVal));
            checkTime();
        };
    $('#sec,#min,#hou').each(function() {
        this.ani = $('.front',this).get(0);
        this.ani.num = $('span',this.ani).get(0);
        this.top = $('.top.back',this).get(0);
        this.top.num = $('span',this.top).get(0);
        this.btm = $('.bottom.back',this).get(0);
        this.btm.num = $('span',this.btm).get(0);
        this.flip = false;
        this.flipCount = 0;
        this.flipDir = 1;
        if (this.id == 'sec') {
            sEl = this;
            this.ani.num.innerHTML = this.top.num.innerHTML = this.btm.num.innerHTML = pad(sVal);
        }
    });
    tickTimer = window.setInterval(tick,30);
});
<|endoftext|>


<commit_before>/** @jsx React.DOM */
/* global require, module */

/*
 * Copyright (C) 2014 Johannes Baiter <johannes.baiter@gmail.com>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.

 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

(function() {
  'use strict';
  var React = require('react/addons'),
      _ = require('underscore'),
      ModelMixin = require('../../vendor/backbonemixin.js'),
      LoadingOverlay = require('./overlays.js').Activity,
      ProgressOverlay = require('./overlays.js').Progress,
      foundation = require('./foundation.js'),
      util = require('../util.js'),
      row = foundation.row,
      column = foundation.column,
      modal = foundation.modal,
      confirmModal = foundation.confirmModal,
      ActionBar, WorkflowItem;

  ActionBar = React.createClass({
    displayName: "ActionBar",
    getInitialState: function() {
      return {
        actionDropdownVisible: false,
        dropdownWidth: undefined
      };
    },
    toggleActionDropdown: function() {
      this.setState({actionDropdownVisible: !this.state.actionDropdownVisible});
    },
    componentDidUpdate: function() {
      if (this.state.actionDropdownVisible) {
        var domNode = this.getDOMNode();
        var dropdownWidth = this.getDOMNode().getElementsByClassName('action-select')[0]
                            .getBoundingClientRect().width;
        domNode.getElementsByClassName('button-list')[0].style.width = dropdownWidth + "px";
      }
    },
    render: function() {
      return (
        <row>

            {this.props.smallDisplay &&
              Actions
            }
            {(!this.props.smallDisplay || this.state.actionDropdownVisible) &&

                    {this.props.smallDisplay && " Edit"}

                    {this.props.smallDisplay && " Remove"}

                  {this.props.smallDisplay && " Download"}

              {window.config.web.mode !== 'processor' &&

                  {this.props.smallDisplay && " Capture"}

}
              {window.config.web.mode !== 'scanner' && this.props.hasPages &&

                     {this.props.smallDisplay && " Start Postprocessing"}

              }
              {window.config.web.mode !== 'scanner' && this.props.hasPages &&

                     {this.props.smallDisplay && "Start Output Generation"}

              }
              {window.config.web.standalone_device &&

                    {this.props.smallDisplay && " Transfer"}

}
              {window.config.web.mode === 'scanner' &&

                    {this.props.smallDisplay && " Submit"}

}

}

        </row>
      );
    }
  })

  /**
   * Display a single workflow with thumbnail, metadata and available actions.
   *
   * @property {Workflow} workflow  - Workflow to set configuration for
   */
  WorkflowItem = React.createClass({
    displayName: "WorkflowItem",
    getInitialState: function() {
      return {
        /** Display deletion confirmation modal? */
        deleteModal: false,
        downloadWaiting: false,
        downloadInProgress: false,
        transferWaiting: false,
        transferProgress: 0,
        transferCurrentFile: undefined,
        stepProgress: 0
      };
    },
    /**
     * Remove associated workflow object from the model collection.
     */
    doRemove: function() {
      // Finish capture if still in progress
      if (this.props.workflow.get('status').step === 'capture') {
        this.props.workflow.finishCapture(function() {
          this.doRemove();
        }.bind(this));
      } else {
        this.props.workflow.destroy();
      }
    },
    /**
     * Enable deletion confirmation modal
     */
    handleRemove: function() {
      this.setState({
        deleteModal: true
      });
    },
    /**
     * Continue to next step in workflow.
     */
    handleCapture: function() {
      window.router.navigate('/workflow/' + this.props.workflow.get('slug') + '/capture',
                             {trigger: true});
    },
    /**
     * Tries to initiate transfer of associated workflow to an external
     * storage device. Displays an error modal if something goes wrong,
     * otherwise displays a loading overlay as long as the transfer is not
     * completed.
     */
    handleTransfer:  function() {
      this.props.workflow.transfer(function(xhr, status) {
        if (status !== 'success') {
          var data = xhr.responseJSON,
              errorText;
          if (data && data.error) {
            errorText = data.error;
          } else {
            errorText = "Check the server logs for details";
          }
          // Display error modal
          this.setState({
            errorModal: true,
            errorModalHeading: "Transfer failed",
            errorModalText: errorText
          });
        } else {
          // Enable loading overlay
          this.setState({
            transferWaiting: true,
            transferProgress: 0,
            transferCurrentFile: undefined
          });
          // Bind progress events
          window.router.events.on('transfer:progressed', function(data) {
            if (this.isMounted()) {
              this.setState({
                transferProgress: data.progress*100 | 0,
                transferCurrentFile: data.status
              });
            }
          }.bind(this));
          // Register callback for when the transfer is completed
          window.router.events.on('transfer:completed', function() {
            // Disable loading overlay
            this.setState({
              transferWaiting: false
            });
          }.bind(this));
        }
      }.bind(this));
    },
    handleDownload: function() {
      this.setState({
        downloadWaiting: true,
        downloadInProgress: true
      });
      window.router.events.on('download:prepared', function() {
        this.setState({downloadWaiting: false});
      }, this);
      window.router.events.on('download:finished', function() {
        this.setState({downloadInProgress: false});
      }, this);
    },
    handleProcess: function() {
      this.props.workflow.startPostprocessing();
    },
    handleOutput: function() {
      this.props.workflow.startOutputting();
    },
    render: function() {
      var workflow = this.props.workflow,
          workflowUrl = '/workflow/' + workflow.get('slug'),
          removalBlocked = (this.state.downloadInProgress || this.state.transferWaiting),
          actionBar;

      actionBar = (<ActionBar workflowSlug={workflow.get('slug')}
                              hasPages={workflow.get('pages').length > 0}
                              handleRemove={this.handleRemove}
                              handleDownload={this.handleDownload}
                              handleCapture={this.handleCapture}
                              handleTransfer={this.handleTransfer}
                              handleProcess={this.handleProcess}
                              handleOutput={this.handleOutput}
                              removalBlocked={removalBlocked}
                              smallDisplay={this.props.smallDisplay}/>);
      return (

          <row>
            {/* Display waiting for download overlay? */}
            {this.state.downloadWaiting &&
              <LoadingOverlay message="Preparing download..."/>
            }
            {/* Display deletion confirmation modal? */}
            {this.state.deleteModal &&
              <confirmModal
                onCancel={function(){this.setState({deleteModal: false});}.bind(this)}
                onConfirm={this.doRemove} fixed={true}>

Remove?

Do you really want to permanently remove this workflow and all
                  of its related files?

              </confirmModal>}
            {/* Display error modal? */}
            {this.state.errorModal &&
              <modal onClose={function(){this.setState({errorModal: false});}.bind(this)}
                    fixed={true}>

{this.state.errorModalHeading}

{this.state.errorModalText}

              </modal>}
            {/* Display loading overlay */}
            {this.state.transferWaiting &&
              <ProgressOverlay progress={this.state.transferProgress}
                              statusMessage={this.state.transferCurrentFile || "Preparing transfer..."}/>}
            {/* Display preview image (second-to last page) if there are pages
                in the workflow */}
            <column size={[6, 4]}>
            {workflow.get('pages').length > 0 ?

              :
              'no pages'
            }
            </column>
            <column size={[6, 8]}>
              <row>
                <column>

{workflow.get('name')}

                </column>
              </row>
              <row>
                <column>

{workflow.has('pages') ? workflow.get('pages').length : 0} pages

                </column>
              </row>
              {_.contains(["process", "output"], workflow.get('status').step) &&
              <row>
                <column>
                  {workflow.get('status').step}:

                </column>
              </row>}
              {!this.props.smallDisplay && actionBar}
            </column>
          </row>
          {this.props.smallDisplay && actionBar}

      );
    }
  });

  /**
   * Container component that holds all WorkflowItems
   *
   * @property {Backbone.Collection<Workflow>} workflows
   */
  module.exports = React.createClass({
    displayName: "WorkflowList",

    /** Enables two-way databinding with Backbone model */
    mixins: [ModelMixin],

    /** Activates databinding for `workflows` model collection property. */
    getBackboneModels: function() {
      return [this.props.workflows];
    },
    getInitialState: function() {
      return { mqSmall: util.isSmall() };
    },
    componentWillMount: function() {
      matchMedia(util.mediaQueries.medium).addListener(function(mql){
        this.setState({ mqSmall: !mql.matches});
      }.bind(this));
    },
    render: function() {
      return(

          <row>
            <column size='18'>

Workflows

            </column>
          </row>

            {this.props.workflows.length > 0 ?
              this.props.workflows.map(function(workflow) {
                return <WorkflowItem key={workflow.id} workflow={workflow}
                                     smallDisplay={this.state.mqSmall}/>;
              }, this):
              <row>
                <column>
No workflows yet!

                  Once you have scanned a book, you can see it (and all
                  other books you have scanned so far) and do the following
                  things with it:

Open its detailed view

Edit its configuration

Delete it

Download it

Open its capture view

Transfer it to a removable storage device

Upload it to a remote postprocessing server

                  Create a new workflow

</column>
              </row>}

      );
    }
  });
}());
<commit_msg>web: Add new status display to workflows in worfklowlist<commit_after>/** @jsx React.DOM */
/* global require, module */

/*
 * Copyright (C) 2014 Johannes Baiter <johannes.baiter@gmail.com>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.

 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

(function() {
  'use strict';
  var React = require('react/addons'),
      _ = require('underscore'),
      ModelMixin = require('../../vendor/backbonemixin.js'),
      LoadingOverlay = require('./overlays.js').Activity,
      ProgressOverlay = require('./overlays.js').Progress,
      foundation = require('./foundation.js'),
      util = require('../util.js'),
      row = foundation.row,
      column = foundation.column,
      modal = foundation.modal,
      confirmModal = foundation.confirmModal,
      ActionBar, WorkflowItem, StepStatus;

  ActionBar = React.createClass({
    displayName: "ActionBar",
    getInitialState: function() {
      return {
        actionDropdownVisible: false,
        dropdownWidth: undefined
      };
    },
    toggleActionDropdown: function() {
      this.setState({actionDropdownVisible: !this.state.actionDropdownVisible});
    },
    componentDidUpdate: function() {
      if (this.state.actionDropdownVisible) {
        var domNode = this.getDOMNode();
        var dropdownWidth = this.getDOMNode().getElementsByClassName('action-select')[0]
                            .getBoundingClientRect().width;
        domNode.getElementsByClassName('button-list')[0].style.width = dropdownWidth + "px";
      }
    },
    render: function() {
      return (
        <row>

            {this.props.smallDisplay &&
              Actions
            }
            {(!this.props.smallDisplay || this.state.actionDropdownVisible) &&

                    {this.props.smallDisplay && " Edit"}

                    {this.props.smallDisplay && " Remove"}

                  {this.props.smallDisplay && " Download"}

              {window.config.web.mode !== 'processor' &&

                  {this.props.smallDisplay && " Capture"}

}
              {window.config.web.mode !== 'scanner' && this.props.hasPages &&

                     {this.props.smallDisplay && " Start Postprocessing"}

              }
              {window.config.web.mode !== 'scanner' && this.props.hasPages &&

                     {this.props.smallDisplay && "Start Output Generation"}

              }
              {window.config.web.standalone_device &&

                    {this.props.smallDisplay && " Transfer"}

}
              {window.config.web.mode === 'scanner' &&

                    {this.props.smallDisplay && " Submit"}

}

}

        </row>
      );
    }
  })

  StepStatus = React.createClass({
    displayName: "StepStatus",
    render: function() {
      var workflow = this.props.workflow,
          pages = workflow.get('pages'),
          step = workflow.get('status').step,
          progress = workflow.get('status').step_progress,
          captureDone = (pages.length > 0 && step !== 'capture'),
          captureBusy = (step === 'capture'),
          processDone = (!_.isEmpty(pages.slice(-1)[0].processed_images) &&
                         (step !== 'process' || progress == 1)),
          processBusy = (step === 'process' && progress < 1),
          outputDone = (workflow.get('out_files').length > 0 &&
                        (step !== 'output' || progress == 1)),
          outputBusy = (step === 'output' && progress < 1);
      return (
        <row>
          <column>

              {window.config.web.mode === 'full' &&

                    { (captureDone || captureBusy)  &&
                      }
                    { captureBusy ?
                      :
                      }
                   Captured

}

                  { (processDone || processBusy) &&
                    }
                  { processBusy ?
                    :
                    }
                 Post-Processed

                  { (outputDone || outputBusy) &&
                    }
                  { outputBusy ?
                    :
                    }
                 Output generated

          </column>
        </row>
      );
    }
  })

  /**
   * Display a single workflow with thumbnail, metadata and available actions.
   *
   * @property {Workflow} workflow  - Workflow to set configuration for
   */
  WorkflowItem = React.createClass({
    displayName: "WorkflowItem",
    getInitialState: function() {
      return {
        /** Display deletion confirmation modal? */
        deleteModal: false,
        downloadWaiting: false,
        downloadInProgress: false,
        transferWaiting: false,
        transferProgress: 0,
        transferCurrentFile: undefined,
        stepProgress: 0
      };
    },
    /**
     * Remove associated workflow object from the model collection.
     */
    doRemove: function() {
      // Finish capture if still in progress
      if (this.props.workflow.get('status').step === 'capture') {
        this.props.workflow.finishCapture(function() {
          this.doRemove();
        }.bind(this));
      } else {
        this.props.workflow.destroy();
      }
    },
    /**
     * Enable deletion confirmation modal
     */
    handleRemove: function() {
      this.setState({
        deleteModal: true
      });
    },
    /**
     * Continue to next step in workflow.
     */
    handleCapture: function() {
      window.router.navigate('/workflow/' + this.props.workflow.get('slug') + '/capture',
                             {trigger: true});
    },
    /**
     * Tries to initiate transfer of associated workflow to an external
     * storage device. Displays an error modal if something goes wrong,
     * otherwise displays a loading overlay as long as the transfer is not
     * completed.
     */
    handleTransfer:  function() {
      this.props.workflow.transfer(function(xhr, status) {
        if (status !== 'success') {
          var data = xhr.responseJSON,
              errorText;
          if (data && data.error) {
            errorText = data.error;
          } else {
            errorText = "Check the server logs for details";
          }
          // Display error modal
          this.setState({
            errorModal: true,
            errorModalHeading: "Transfer failed",
            errorModalText: errorText
          });
        } else {
          // Enable loading overlay
          this.setState({
            transferWaiting: true,
            transferProgress: 0,
            transferCurrentFile: undefined
          });
          // Bind progress events
          window.router.events.on('transfer:progressed', function(data) {
            if (this.isMounted()) {
              this.setState({
                transferProgress: data.progress*100 | 0,
                transferCurrentFile: data.status
              });
            }
          }.bind(this));
          // Register callback for when the transfer is completed
          window.router.events.on('transfer:completed', function() {
            // Disable loading overlay
            this.setState({
              transferWaiting: false
            });
          }.bind(this));
        }
      }.bind(this));
    },
    handleDownload: function() {
      this.setState({
        downloadWaiting: true,
        downloadInProgress: true
      });
      window.router.events.on('download:prepared', function() {
        this.setState({downloadWaiting: false});
      }, this);
      window.router.events.on('download:finished', function() {
        this.setState({downloadInProgress: false});
      }, this);
    },
    handleProcess: function() {
      this.props.workflow.startPostprocessing();
    },
    handleOutput: function() {
      this.props.workflow.startOutputting();
    },
    render: function() {
      var workflow = this.props.workflow,
          workflowUrl = '/workflow/' + workflow.get('slug'),
          removalBlocked = (this.state.downloadInProgress || this.state.transferWaiting),
          actionBar;

      actionBar = (<ActionBar workflowSlug={workflow.get('slug')}
                              hasPages={workflow.get('pages').length > 0}
                              handleRemove={this.handleRemove}
                              handleDownload={this.handleDownload}
                              handleCapture={this.handleCapture}
                              handleTransfer={this.handleTransfer}
                              handleProcess={this.handleProcess}
                              handleOutput={this.handleOutput}
                              removalBlocked={removalBlocked}
                              smallDisplay={this.props.smallDisplay}/>);
      return (

          <row>
            {/* Display waiting for download overlay? */}
            {this.state.downloadWaiting &&
              <LoadingOverlay message="Preparing download..."/>
            }
            {/* Display deletion confirmation modal? */}
            {this.state.deleteModal &&
              <confirmModal
                onCancel={function(){this.setState({deleteModal: false});}.bind(this)}
                onConfirm={this.doRemove} fixed={true}>

Remove?

Do you really want to permanently remove this workflow and all
                  of its related files?

              </confirmModal>}
            {/* Display error modal? */}
            {this.state.errorModal &&
              <modal onClose={function(){this.setState({errorModal: false});}.bind(this)}
                    fixed={true}>

{this.state.errorModalHeading}

{this.state.errorModalText}

              </modal>}
            {/* Display loading overlay */}
            {this.state.transferWaiting &&
              <ProgressOverlay progress={this.state.transferProgress}
                              statusMessage={this.state.transferCurrentFile || "Preparing transfer..."}/>}
            {/* Display preview image (second-to last page) if there are pages
                in the workflow */}
            <column size={[6, 4]}>
            {workflow.get('pages').length > 0 ?

              :
              'no pages'
            }
            </column>
            <column size={[6, 8]}>
              <row>
                <column>

{workflow.get('name')}

                </column>
              </row>
              <row>
                <column>

{workflow.has('pages') ? workflow.get('pages').length : 0} pages

                </column>
              </row>
              {window.config.web.mode !== 'scanner' && <StepStatus workflow={workflow}/>}
              {_.contains(["process", "output"], workflow.get('status').step) &&
              <row>
                <column>

                </column>
              </row>}
              {!this.props.smallDisplay && actionBar}
            </column>
          </row>
          {this.props.smallDisplay && actionBar}

      );
    }
  });

  /**
   * Container component that holds all WorkflowItems
   *
   * @property {Backbone.Collection<Workflow>} workflows
   */
  module.exports = React.createClass({
    displayName: "WorkflowList",

    /** Enables two-way databinding with Backbone model */
    mixins: [ModelMixin],

    /** Activates databinding for `workflows` model collection property. */
    getBackboneModels: function() {
      return [this.props.workflows];
    },
    getInitialState: function() {
      return { mqSmall: util.isSmall() };
    },
    componentWillMount: function() {
      matchMedia(util.mediaQueries.medium).addListener(function(mql){
        this.setState({ mqSmall: !mql.matches});
      }.bind(this));
    },
    render: function() {
      return(

          <row>
            <column size='18'>

Workflows

            </column>
          </row>

            {this.props.workflows.length > 0 ?
              this.props.workflows.map(function(workflow) {
                return <WorkflowItem key={workflow.id} workflow={workflow}
                                     smallDisplay={this.state.mqSmall}/>;
              }, this):
              <row>
                <column>
No workflows yet!

                  Once you have scanned a book, you can see it (and all
                  other books you have scanned so far) and do the following
                  things with it:

Open its detailed view

Edit its configuration

Delete it

Download it

Open its capture view

Transfer it to a removable storage device

Upload it to a remote postprocessing server

                  Create a new workflow

</column>
              </row>}

      );
    }
  });
}());
<|endoftext|>


<commit_before>const {readFile, writeFile} = require('fs');
const libui = require('../index.js');
libui.Ui.init();
const {
	label,
	window,
	tab,
	menu,
	multilineEntry
} = require('./utils.js');

const onClosing = () => libui.stopLoop();

const winProps = {
	hasMenubar: true,
	title: 'Node Pad',
	width: 640,
	height: 480,
	onClosing
};

libui.Ui.init();

let win;
let editor;
let status;
let currentFileName = '';

function newFile() {
	editor.text = '';
	currentFileName = '';
}

function openFile() {
	const filename = libui.UiDialogs.openFile(win);
	if (filename) {
		readFile(filename, 'utf8', function (err, content) {
			editor.text = content;
			status.text = `Open ${filename}`;
			currentFileName = filename;
		});
	}
}

function saveFileAs() {
	const filename = libui.UiDialogs.saveFile(win);
	if (filename) {
		writeFile(currentFileName, editor.text, function (err) {
			currentFileName = filename;
		});
	}
}

function saveFile() {
	if (!currentFileName) {
		return saveFileAs();
	}
	writeFile(currentFileName, editor.text, function (err) {
	});
}

menu([{
	label: 'File',
	submenu: [
		{
			label: 'New file',
			click: newFile
		}, {
			label: 'Open',
			click: openFile
		}, {
			label: 'Close current tab',
			click: () => {}
		}, {
			label: 'Save',
			click: saveFile
		}, {
			label: 'Save as',
			click: saveFileAs
		}, {
			role: 'quit'
		}
	]
}, {
	label: 'Edit',
	submenu: [
		{
			label: 'Copy'
		}, {
			label: 'Paste'
		}, {
			label: 'Cut'
		}, {
			label: 'Select all'
		}
	]
}, {
	label: 'Help',
	submenu: [
		{
			label: 'Help',
			click: () => {}
		}, {
			role: 'about'
		}
	]
}]);

win = window(winProps,
	tab({stretchy: true},
		editor = multilineEntry({stretchy: true, tabTitle: 'New file'})
	),
	status = label({stretchy: false, text: 'File not changed'})
);

win.show();
libui.startLoop();

<commit_msg>Add errors<commit_after>const {readFile, writeFile} = require('fs');
const libui = require('../index.js');
libui.Ui.init();
const {
	label,
	window,
	tab,
	menu,
	multilineEntry
} = require('./utils.js');

const onClosing = () => libui.stopLoop();

const winProps = {
	hasMenubar: true,
	title: 'Node Pad',
	width: 640,
	height: 480,
	onClosing
};

libui.Ui.init();

let win;
let editor;
let status;
let currentFileName = '';

function newFile() {
	editor.text = '';
	currentFileName = '';
}

function openFile() {
	const filename = libui.UiDialogs.openFile(win);
	if (filename) {
		readFile(filename, 'utf8', function (err, content) {
			if (err) {
				return libui.UiDialogs.msgBoxError(win, 'Error while reading file', err.stack);
			}
			editor.text = content;
			status.text = `Open ${filename}`;
			currentFileName = filename;
		});
	}
}

function saveFileAs() {
	const filename = libui.UiDialogs.saveFile(win);
	if (filename) {
		writeFile(currentFileName, editor.text, function (err) {
			if (err) {
				return libui.UiDialogs.msgBoxError(win, 'Error while writing file', err.stack);
			}
			currentFileName = filename;
		});
	}
}

function saveFile() {
	if (!currentFileName) {
		return saveFileAs();
	}

	writeFile(currentFileName, editor.text, function (err) {
		if (err) {
			return libui.UiDialogs.msgBoxError(win, 'Error while writing file', err.stack);
		}
	});
}

menu([{
	label: 'File',
	submenu: [
		{
			label: 'New file',
			click: newFile
		}, {
			label: 'Open',
			click: openFile
		}, {
			label: 'Close current tab',
			click: () => {}
		}, {
			label: 'Save',
			click: saveFile
		}, {
			label: 'Save as',
			click: saveFileAs
		}, {
			role: 'quit'
		}
	]
}, {
	label: 'Edit',
	submenu: [
		{
			label: 'Copy'
		}, {
			label: 'Paste'
		}, {
			label: 'Cut'
		}, {
			label: 'Select all'
		}
	]
}, {
	label: 'Help',
	submenu: [
		{
			label: 'Help',
			click: () => {}
		}, {
			role: 'about'
		}
	]
}]);

win = window(winProps,
	tab({stretchy: true},
		editor = multilineEntry({stretchy: true, tabTitle: 'New file'})
	),
	status = label({stretchy: false, text: 'File not changed'})
);

win.show();
libui.startLoop();

<|endoftext|>


<commit_before>// Bot as a singleton

const Telegraf = require('telegraf');
const Calendar = require('telegraf-calendar-telegram');

var bot = null;
var calendar = null;

class TelegrafWrapper {
	static getBot() {
		if (bot == null) {
			bot = new Telegraf(process.env.TELEGRAM_TOKEN);

			// todo: check if context is unique per user. Set 2 timers at the same time using different users
			//bot.context({ isAsking: ConfigState.NONE });

			bot.use(Telegraf.memorySession());

			console.log("Bot initialized");
		}

		return bot;
	}

	static getExtra() {
		return Telegraf.Extra;
	}

	static getCalendar() {
		if (!calendar) {
			calendar = new Calendar(TelegrafWrapper.getBot(), {
				startWeekDay: 1,
				weekDayNames: ["L", "M", "M", "G", "V", "S", "D"],
				monthNames: [
					"Gen", "Feb", "Mar", "Apr", "Mag", "Giu",
					"Lug", "Ago", "Set", "Ott", "Nov", "Dic"
				]
			});
		}

		const today = new Date();
		const minDate = new Date();
		minDate.setMonth(today.getMonth() - 1);
		minDate.setDate(1);

		const maxDate = new Date();
		maxDate.setMonth(today.getMonth() + 1);
		maxDate.setDate(0); // this will set date at last day of month

		return calendar.setMinDate(minDate).setMaxDate(maxDate);
	}
}

module.exports = TelegrafWrapper;<commit_msg>fix max date<commit_after>// Bot as a singleton

const Telegraf = require('telegraf');
const Calendar = require('telegraf-calendar-telegram');

var bot = null;
var calendar = null;

class TelegrafWrapper {
	static getBot() {
		if (bot == null) {
			bot = new Telegraf(process.env.TELEGRAM_TOKEN);

			// todo: check if context is unique per user. Set 2 timers at the same time using different users
			//bot.context({ isAsking: ConfigState.NONE });

			bot.use(Telegraf.memorySession());

			console.log("Bot initialized");
		}

		return bot;
	}

	static getExtra() {
		return Telegraf.Extra;
	}

	static getCalendar() {
		if (!calendar) {
			calendar = new Calendar(TelegrafWrapper.getBot(), {
				startWeekDay: 1,
				weekDayNames: ["L", "M", "M", "G", "V", "S", "D"],
				monthNames: [
					"Gen", "Feb", "Mar", "Apr", "Mag", "Giu",
					"Lug", "Ago", "Set", "Ott", "Nov", "Dic"
				]
			});
		}

		const today = new Date();
		const minDate = new Date();
		minDate.setMonth(today.getMonth() - 1);
		minDate.setDate(1);

		const maxDate = new Date();
		// these two lines will set date at last day of next month
		maxDate.setMonth(today.getMonth() + 2);
		maxDate.setDate(0);

		return calendar.setMinDate(minDate).setMaxDate(maxDate);
	}
}

module.exports = TelegrafWrapper;<|endoftext|>


<commit_before>async function rest_call_service(args) {
/*
description("REST API Ccall function")
base_component_id("rest_call_service")
load_once_from_file(true)
only_run_on_server(true)
*/

    console.log("REST Call args: " + JSON.stringify(args,null,2));

    var promise = new Promise(async function(returnFn) {

        //const url = "https://jsonplaceholder.typicode.com/posts/1";
        const url = args.URL;

        var useHttpOrHttps = https
        if (url.startsWith("http:")) {
            useHttpOrHttps = http
        }

        request(
            url
            ,
            {
                rejectUnauthorized : false,

                auth: {
                    user: 'adminuser',
                    pass: 'admin1!'
                }

            }
            ,

            function(error, res, body) {
                console.log("Error: " + JSON.stringify(error,null,2));
                console.log("Response: " + JSON.stringify(res,null,2));
                console.log("Body: " + JSON.stringify(body,null,2));

                var body = "";

                res.on(
                    "data",
                    function(data) {
                        body += data;
                    }
                );

                res.on(
                    "end",
                    function() {
                        //body = JSON.parse(body);
                        console.log(body);
                        returnFn({value: ""})
                        //returnFn({value: JSON.parse(body)})
                    }
                );
            }
        );

    })
    var ret = await promise

    return ret
}
<commit_msg>Trying to fix rest API<commit_after>async function rest_call_service(args) {
/*
description("REST API Ccall function")
base_component_id("rest_call_service")
load_once_from_file(true)
only_run_on_server(true)
*/

    console.log("REST Call args: " + JSON.stringify(args,null,2));

    var promise = new Promise(async function(returnFn) {

        //const url = "https://jsonplaceholder.typicode.com/posts/1";
        const url = args.URL;

        request(
            url
            ,
            {
                rejectUnauthorized : false

                //auth: {
                //    user: 'adminuser',
                //    pass: 'admin1!'
                //}

            }
            ,

            function(error, res, body) {
                console.log("Error: " + JSON.stringify(error,null,2));
                console.log("Response: " + JSON.stringify(res,null,2));
                console.log("Body: " + JSON.stringify(body,null,2));

                var body = "";

                res.on(
                    "data",
                    function(data) {
                        body += data;
                    }
                );

                res.on(
                    "end",
                    function() {
                        //body = JSON.parse(body);
                        console.log(body);
                        //returnFn({value: ""})
                        returnFn({value: JSON.parse(body)})
                    }
                );
            }
        );

    })
    var ret = await promise

    return ret
}
<|endoftext|>


<commit_before>import Users from "meteor/vulcan:users";
import moment from 'moment';

Users.addView('LWSunshinesList', function(terms) {
  return {
    selector: {groups:'sunshineRegiment'},
    options: {
      sort: terms.sort
    }
  }
});

Users.addView('LWTrustLevel1List', function(terms) {
  return {
    selector: {groups:'trustLevel1'},
    options: {
      sort: terms.sort
    }
  }
});

Users.addView('LWUsersAdmin', terms => ({
  options: {
    sort: terms.sort
  }
}));

Users.addView("usersWithBannedUsers", function () {
  return {
    selector: {
      bannedUserIds: {$exists: true}
    },
  }
})

Users.addView("sunshineNewUsers", function () {
  const twoDaysAgo = moment().subtract(2, 'days').toDate();
  return {
    selector: {
      createdAt: {$gt: twoDaysAgo},
      reviewedByUserId: {$exists: false}
    },
  }
})
<commit_msg>bannedUsers don't show up in dashboard<commit_after>import Users from "meteor/vulcan:users";
import moment from 'moment';

Users.addView('LWSunshinesList', function(terms) {
  return {
    selector: {groups:'sunshineRegiment'},
    options: {
      sort: terms.sort
    }
  }
});

Users.addView('LWTrustLevel1List', function(terms) {
  return {
    selector: {groups:'trustLevel1'},
    options: {
      sort: terms.sort
    }
  }
});

Users.addView('LWUsersAdmin', terms => ({
  options: {
    sort: terms.sort
  }
}));

Users.addView("usersWithBannedUsers", function () {
  return {
    selector: {
      bannedUserIds: {$exists: true}
    },
  }
})

Users.addView("sunshineNewUsers", function () {
  const twoDaysAgo = moment().subtract(2, 'days').toDate();
  return {
    selector: {
      createdAt: {$gt: twoDaysAgo},
      reviewedByUserId: {$exists: false},
      banned: {$exists: false},
    },
  }
})
<|endoftext|>