<commit_before>/** ====================================================================
 * jsPDF Cell plugin
 * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
 *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
 *               2013 Lee Driscoll, https://github.com/lsdriscoll
 *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
 *               2014 James Hall, james@parall.ax
 *               2014 Diego Casorran, https://github.com/diegocr
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * ====================================================================
 */

(function (jsPDFAPI) {
    'use strict';
    /*jslint browser:true */
    /*global document: false, jsPDF */

    var fontName,
        fontSize,
        fontStyle,
        padding = 3,
        margin = 13,
        headerFunction,
        lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
        pages = 1,
        setLastCellPosition = function (x, y, w, h, ln) {
            lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln };
        },
        getLastCellPosition = function () {
            return lastCellPos;
        },
        NO_MARGINS = {left:0, top:0, bottom: 0};

    jsPDFAPI.setHeaderFunction = function (func) {
        headerFunction = func;
    };

    jsPDFAPI.getTextDimensions = function (txt) {
        fontName = this.internal.getFont().fontName;
        fontSize = this.table_font_size || this.internal.getFontSize();
        fontStyle = this.internal.getFont().fontStyle;
        // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point
        var px2pt = 0.264583 * 72 / 25.4,
            dimensions,
            text;

        text = document.createElement('font');
        text.id = "jsPDFCell";

        try {
            text.style.fontStyle = fontStyle;
        } catch(e) {
            text.style.fontWeight = fontStyle;
        }

        text.style.fontFamily = fontName;
        text.style.fontSize = fontSize + 'pt';
        try {
            text.textContent = txt;
        } catch(e) {
            text.innerText = txt;
        }

        document.body.appendChild(text);

        dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt};

        document.body.removeChild(text);

        return dimensions;
    };

    jsPDFAPI.cellAddPage = function () {
        var margins = this.margins || NO_MARGINS;

        this.addPage();

        setLastCellPosition(margins.left, margins.top, undefined, undefined);
        //setLastCellPosition(undefined, undefined, undefined, undefined, undefined);
        pages += 1;
    };

    jsPDFAPI.cellInitialize = function () {
        lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };
        pages = 1;
    };

    jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) {
        var curCell = getLastCellPosition();
        var pgAdded = false;

        // If this is not the first cell, we must change its position
        if (curCell.ln !== undefined) {
            if (curCell.ln === ln) {
                //Same line
                x = curCell.x + curCell.w;
                y = curCell.y;
            } else {
                //New line
                var margins = this.margins || NO_MARGINS;
                if ((curCell.y + curCell.h + h + margin) >= this.internal.pageSize.height - margins.bottom) {
                    this.cellAddPage();
                    pgAdded = true;
                    if (this.printHeaders && this.tableHeaderRow) {
                        this.printHeaderRow(ln, true);
                    }
                }
                //We ignore the passed y: the lines may have different heights
                y = (getLastCellPosition().y + getLastCellPosition().h);
                if (pgAdded) y = margin + 10;
            }
        }

        if (txt[0] !== undefined) {
            if (this.printingHeaderRow) {
                this.rect(x, y, w, h, 'FD');
            } else {
                this.rect(x, y, w, h);
            }
            if (align === 'right') {
                if (!(txt instanceof Array)) {
                    txt = [txt];
                }
                for (var i = 0; i < txt.length; i++) {
                    var currentLine = txt[i];
                    var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize();
                    this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight()*(i+1));
                }
            } else {
                this.text(txt, x + padding, y + this.internal.getLineHeight());
            }
        }
        setLastCellPosition(x, y, w, h, ln);
        return this;
    };

    /**
     * Return the maximum value from an array
     * @param array
     * @param comparisonFn
     * @returns {*}
     */
    jsPDFAPI.arrayMax = function (array, comparisonFn) {
        var max = array[0],
            i,
            ln,
            item;

        for (i = 0, ln = array.length; i < ln; i += 1) {
            item = array[i];

            if (comparisonFn) {
                if (comparisonFn(max, item) === -1) {
                    max = item;
                }
            } else {
                if (item > max) {
                    max = item;
                }
            }
        }

        return max;
    };

    /**
     * Create a table from a set of data.
     * @param {Integer} [x] : left-position for top-left corner of table
     * @param {Integer} [y] top-position for top-left corner of table
     * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data.
     * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost

     * @param {Object} [config.printHeaders] True to print column headers at the top of every page
     * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
     * @param {Object} [config.margins] margin values for left, top, bottom, and width
     * @param {Object} [config.fontSize] Integer fontSize to use (optional)
     */

    jsPDFAPI.table = function (x,y, data, headers, config) {
        if (!data) {
            throw 'No data for PDF table';
        }

        var headerNames = [],
            headerPrompts = [],
            header,
            i,
            ln,
            cln,
            columnMatrix = {},
            columnWidths = {},
            columnData,
            column,
            columnMinWidths = [],
            j,
            tableHeaderConfigs = [],
            model,
            jln,
            func,

        //set up defaults. If a value is provided in config, defaults will be overwritten:
           autoSize        = false,
           printHeaders    = true,
           fontSize        = 12,
           margins         = NO_MARGINS;

           margins.width = this.internal.pageSize.width;

        if (config) {
        //override config defaults if the user has specified non-default behavior:
            if(config.autoSize === true) {
                autoSize = true;
            }
            if(config.printHeaders === false) {
                printHeaders = false;
            }
            if(config.fontSize){
                fontSize = config.fontSize;
            }
            if (config.css && typeof(config.css['font-size']) !== "undefined") {
                fontSize = config.css['font-size'] * 16;
            }
            if(config.margins){
                margins = config.margins;
            }
        }

        /**
         * @property {Number} lnMod
         * Keep track of the current line number modifier used when creating cells
         */
        this.lnMod = 0;
        lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
        pages = 1;

        this.printHeaders = printHeaders;
        this.margins = margins;
        this.setFontSize(fontSize);
        this.table_font_size = fontSize;

        // Set header values
        if (headers === undefined || (headers === null)) {
            // No headers defined so we derive from data
            headerNames = Object.keys(data[0]);

        } else if (headers[0] && (typeof headers[0] !== 'string')) {
            var px2pt = 0.264583 * 72 / 25.4;

            // Split header configs into names and prompts
            for (i = 0, ln = headers.length; i < ln; i += 1) {
                header = headers[i];
                headerNames.push(header.name);
                headerPrompts.push(header.prompt);
                columnWidths[header.name] = header.width *px2pt;
            }

        } else {
            headerNames = headers;
        }

        if (autoSize) {
            // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
            func = function (rec) {
                return rec[header];
            };

            for (i = 0, ln = headerNames.length; i < ln; i += 1) {
                header = headerNames[i];

                columnMatrix[header] = data.map(
                    func
                );

                // get header width
                columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);
                column = columnMatrix[header];

                // get cell widths
                for (j = 0, cln = column.length; j < cln; j += 1) {
                    columnData = column[j];
                    columnMinWidths.push(this.getTextDimensions(columnData).w);
                }

                // get final column width
                columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);

                //have to reset
                columnMinWidths = [];
            }
        }

        // -- Construct the table

        if (printHeaders) {
            var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length?headerPrompts:headerNames);

            // Construct the header row
            for (i = 0, ln = headerNames.length; i < ln; i += 1) {
                header = headerNames[i];
                tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);
            }

            // Store the table header config
            this.setTableHeaderRow(tableHeaderConfigs);

            // Print the header for the start of the table
            this.printHeaderRow(1, false);
        }

        // Construct the data rows
        for (i = 0, ln = data.length; i < ln; i += 1) {
            var lineHeight;
            model = data[i];
            lineHeight = this.calculateLineHeight(headerNames, columnWidths, model);

            for (j = 0, jln = headerNames.length; j < jln; j += 1) {
                header = headerNames[j];
                this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align);
            }
        }
        this.lastCellPos = lastCellPos;
        this.table_x = x;
        this.table_y = y;
        return this;
    };
    /**
     * Calculate the height for containing the highest column
     * @param {String[]} headerNames is the header, used as keys to the data
     * @param {Integer[]} columnWidths is size of each column
     * @param {Object[]} model is the line of data we want to calculate the height of
     */
    jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) {
        var header, lineHeight = 0;
        for (var j = 0; j < headerNames.length; j++) {
            header = headerNames[j];
            model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding);
            var h = this.internal.getLineHeight() * model[header].length + padding;
            if (h > lineHeight)
                lineHeight = h;
        }
        return lineHeight;
    };

    /**
     * Store the config for outputting a table header
     * @param {Object[]} config
     * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
     * except the ln parameter is excluded
     */
    jsPDFAPI.setTableHeaderRow = function (config) {
        this.tableHeaderRow = config;
    };

    /**
     * Output the store header row
     * @param lineNumber The line number to output the header at
     */
    jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
        if (!this.tableHeaderRow) {
            throw 'Property tableHeaderRow does not exist.';
        }

        var tableHeaderCell,
            tmpArray,
            i,
            ln;

        this.printingHeaderRow = true;
        if (headerFunction !== undefined) {
            var position = headerFunction(this, pages);
            setLastCellPosition(position[0], position[1], position[2], position[3], -1);
        }
        this.setFontStyle('bold');
        var tempHeaderConf = [];
        for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) {
            this.setFillColor(200,200,200);

            tableHeaderCell = this.tableHeaderRow[i];
            if (new_page) {
                this.margins.top = margin;
                tableHeaderCell[1] = this.margins && this.margins.top || 0;
                tempHeaderConf.push(tableHeaderCell);
            }
            tmpArray = [].concat(tableHeaderCell);
            this.cell.apply(this, tmpArray.concat(lineNumber));
        }
        if (tempHeaderConf.length > 0){
            this.setTableHeaderRow(tempHeaderConf);
        }
        this.setFontStyle('normal');
        this.printingHeaderRow = false;
    };

})(jsPDF.API);
<commit_msg>Update cell.js<commit_after>/** ====================================================================
 * jsPDF Cell plugin
 * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
 *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
 *               2013 Lee Driscoll, https://github.com/lsdriscoll
 *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
 *               2014 James Hall, james@parall.ax
 *               2014 Diego Casorran, https://github.com/diegocr
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * ====================================================================
 */

(function (jsPDFAPI) {
    'use strict';
    /*jslint browser:true */
    /*global document: false, jsPDF */

    var fontName,
        fontSize,
        fontStyle,
        padding = 3,
        margin = 13,
        headerFunction,
        lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
        pages = 1,
        setLastCellPosition = function (x, y, w, h, ln) {
            lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln };
        },
        getLastCellPosition = function () {
            return lastCellPos;
        },
        NO_MARGINS = {left:0, top:0, bottom: 0};

    jsPDFAPI.setHeaderFunction = function (func) {
        headerFunction = func;
    };

    jsPDFAPI.getTextDimensions = function (txt) {
        fontName = this.internal.getFont().fontName;
        fontSize = this.table_font_size || this.internal.getFontSize();
        fontStyle = this.internal.getFont().fontStyle;
        // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point
        var px2pt = 0.264583 * 72 / 25.4,
            dimensions,
            text;

        text = document.createElement('font');
        text.id = "jsPDFCell";

        try {
            text.style.fontStyle = fontStyle;
        } catch(e) {
            text.style.fontWeight = fontStyle;
        }

        text.style.fontSize = fontSize + 'pt';
        text.style.fontFamily = fontName;
        try {
            text.textContent = txt;
        } catch(e) {
            text.innerText = txt;
        }

        document.body.appendChild(text);

        dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt};

        document.body.removeChild(text);

        return dimensions;
    };

    jsPDFAPI.cellAddPage = function () {
        var margins = this.margins || NO_MARGINS;

        this.addPage();

        setLastCellPosition(margins.left, margins.top, undefined, undefined);
        //setLastCellPosition(undefined, undefined, undefined, undefined, undefined);
        pages += 1;
    };

    jsPDFAPI.cellInitialize = function () {
        lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };
        pages = 1;
    };

    jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) {
        var curCell = getLastCellPosition();
        var pgAdded = false;

        // If this is not the first cell, we must change its position
        if (curCell.ln !== undefined) {
            if (curCell.ln === ln) {
                //Same line
                x = curCell.x + curCell.w;
                y = curCell.y;
            } else {
                //New line
                var margins = this.margins || NO_MARGINS;
                if ((curCell.y + curCell.h + h + margin) >= this.internal.pageSize.height - margins.bottom) {
                    this.cellAddPage();
                    pgAdded = true;
                    if (this.printHeaders && this.tableHeaderRow) {
                        this.printHeaderRow(ln, true);
                    }
                }
                //We ignore the passed y: the lines may have different heights
                y = (getLastCellPosition().y + getLastCellPosition().h);
                if (pgAdded) y = margin + 10;
            }
        }

        if (txt[0] !== undefined) {
            if (this.printingHeaderRow) {
                this.rect(x, y, w, h, 'FD');
            } else {
                this.rect(x, y, w, h);
            }
            if (align === 'right') {
                if (!(txt instanceof Array)) {
                    txt = [txt];
                }
                for (var i = 0; i < txt.length; i++) {
                    var currentLine = txt[i];
                    var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize();
                    this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight()*(i+1));
                }
            } else {
                this.text(txt, x + padding, y + this.internal.getLineHeight());
            }
        }
        setLastCellPosition(x, y, w, h, ln);
        return this;
    };

    /**
     * Return the maximum value from an array
     * @param array
     * @param comparisonFn
     * @returns {*}
     */
    jsPDFAPI.arrayMax = function (array, comparisonFn) {
        var max = array[0],
            i,
            ln,
            item;

        for (i = 0, ln = array.length; i < ln; i += 1) {
            item = array[i];

            if (comparisonFn) {
                if (comparisonFn(max, item) === -1) {
                    max = item;
                }
            } else {
                if (item > max) {
                    max = item;
                }
            }
        }

        return max;
    };

    /**
     * Create a table from a set of data.
     * @param {Integer} [x] : left-position for top-left corner of table
     * @param {Integer} [y] top-position for top-left corner of table
     * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data.
     * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost

     * @param {Object} [config.printHeaders] True to print column headers at the top of every page
     * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
     * @param {Object} [config.margins] margin values for left, top, bottom, and width
     * @param {Object} [config.fontSize] Integer fontSize to use (optional)
     */

    jsPDFAPI.table = function (x,y, data, headers, config) {
        if (!data) {
            throw 'No data for PDF table';
        }

        var headerNames = [],
            headerPrompts = [],
            header,
            i,
            ln,
            cln,
            columnMatrix = {},
            columnWidths = {},
            columnData,
            column,
            columnMinWidths = [],
            j,
            tableHeaderConfigs = [],
            model,
            jln,
            func,

        //set up defaults. If a value is provided in config, defaults will be overwritten:
           autoSize        = false,
           printHeaders    = true,
           fontSize        = 12,
           margins         = NO_MARGINS;

           margins.width = this.internal.pageSize.width;

        if (config) {
        //override config defaults if the user has specified non-default behavior:
            if(config.autoSize === true) {
                autoSize = true;
            }
            if(config.printHeaders === false) {
                printHeaders = false;
            }
            if(config.fontSize){
                fontSize = config.fontSize;
            }
            if (config.css && typeof(config.css['font-size']) !== "undefined") {
                fontSize = config.css['font-size'] * 16;
            }
            if(config.margins){
                margins = config.margins;
            }
        }

        /**
         * @property {Number} lnMod
         * Keep track of the current line number modifier used when creating cells
         */
        this.lnMod = 0;
        lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
        pages = 1;

        this.printHeaders = printHeaders;
        this.margins = margins;
        this.setFontSize(fontSize);
        this.table_font_size = fontSize;

        // Set header values
        if (headers === undefined || (headers === null)) {
            // No headers defined so we derive from data
            headerNames = Object.keys(data[0]);

        } else if (headers[0] && (typeof headers[0] !== 'string')) {
            var px2pt = 0.264583 * 72 / 25.4;

            // Split header configs into names and prompts
            for (i = 0, ln = headers.length; i < ln; i += 1) {
                header = headers[i];
                headerNames.push(header.name);
                headerPrompts.push(header.prompt);
                columnWidths[header.name] = header.width *px2pt;
            }

        } else {
            headerNames = headers;
        }

        if (autoSize) {
            // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
            func = function (rec) {
                return rec[header];
            };

            for (i = 0, ln = headerNames.length; i < ln; i += 1) {
                header = headerNames[i];

                columnMatrix[header] = data.map(
                    func
                );

                // get header width
                columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);
                column = columnMatrix[header];

                // get cell widths
                for (j = 0, cln = column.length; j < cln; j += 1) {
                    columnData = column[j];
                    columnMinWidths.push(this.getTextDimensions(columnData).w);
                }

                // get final column width
                columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);

                //have to reset
                columnMinWidths = [];
            }
        }

        // -- Construct the table

        if (printHeaders) {
            var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length?headerPrompts:headerNames);

            // Construct the header row
            for (i = 0, ln = headerNames.length; i < ln; i += 1) {
                header = headerNames[i];
                tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);
            }

            // Store the table header config
            this.setTableHeaderRow(tableHeaderConfigs);

            // Print the header for the start of the table
            this.printHeaderRow(1, false);
        }

        // Construct the data rows
        for (i = 0, ln = data.length; i < ln; i += 1) {
            var lineHeight;
            model = data[i];
            lineHeight = this.calculateLineHeight(headerNames, columnWidths, model);

            for (j = 0, jln = headerNames.length; j < jln; j += 1) {
                header = headerNames[j];
                this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align);
            }
        }
        this.lastCellPos = lastCellPos;
        this.table_x = x;
        this.table_y = y;
        return this;
    };
    /**
     * Calculate the height for containing the highest column
     * @param {String[]} headerNames is the header, used as keys to the data
     * @param {Integer[]} columnWidths is size of each column
     * @param {Object[]} model is the line of data we want to calculate the height of
     */
    jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) {
        var header, lineHeight = 0;
        for (var j = 0; j < headerNames.length; j++) {
            header = headerNames[j];
            model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding);
            var h = this.internal.getLineHeight() * model[header].length + padding;
            if (h > lineHeight)
                lineHeight = h;
        }
        return lineHeight;
    };

    /**
     * Store the config for outputting a table header
     * @param {Object[]} config
     * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
     * except the ln parameter is excluded
     */
    jsPDFAPI.setTableHeaderRow = function (config) {
        this.tableHeaderRow = config;
    };

    /**
     * Output the store header row
     * @param lineNumber The line number to output the header at
     */
    jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
        if (!this.tableHeaderRow) {
            throw 'Property tableHeaderRow does not exist.';
        }

        var tableHeaderCell,
            tmpArray,
            i,
            ln;

        this.printingHeaderRow = true;
        if (headerFunction !== undefined) {
            var position = headerFunction(this, pages);
            setLastCellPosition(position[0], position[1], position[2], position[3], -1);
        }
        this.setFontStyle('bold');
        var tempHeaderConf = [];
        for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) {
            this.setFillColor(200,200,200);

            tableHeaderCell = this.tableHeaderRow[i];
            if (new_page) {
                this.margins.top = margin;
                tableHeaderCell[1] = this.margins && this.margins.top || 0;
                tempHeaderConf.push(tableHeaderCell);
            }
            tmpArray = [].concat(tableHeaderCell);
            this.cell.apply(this, tmpArray.concat(lineNumber));
        }
        if (tempHeaderConf.length > 0){
            this.setTableHeaderRow(tempHeaderConf);
        }
        this.setFontStyle('normal');
        this.printingHeaderRow = false;
    };

})(jsPDF.API);
<|endoftext|>


<commit_before>/** @jsx React.DOM */

define(
  [
    'react',
    'backbone',
    'stores',
    'moment',
    'crypto',
    'components/common/Gravatar.react',
    'url'
  ],
  function (React, Backbone, stores, moment, CryptoJS, Gravatar, url) {

    function getState() {
      return {
        instanceHistory: stores.InstanceHistoryStore.getAll(),
        isLoadingMoreResults: false
      };
    }

    return React.createClass({

      propTypes: {

      },

      getInitialState: function () {
        return getState();
      },

      updateState: function () {
        if (this.isMounted()) this.setState(getState());
      },

//      componentDidMount: function () {
//        stores.InstanceHistoryStore.addChangeListener(this.updateState);
//      },
//
//      componentWillUnmount: function () {
//        stores.InstanceHistoryStore.removeChangeListener(this.updateState);
//      },

      onLoadMoreInstanceHistory: function(){
        this.setState({isLoadingMoreResults: true});
        stores.InstanceHistoryStore.fetchMore();
      },

      render: function () {
        var instanceHistories = stores.InstanceHistoryStore.getAll();

        // we're fetching the applications before the app loads because we need to display links to the images
        // on the dashboard in the instance history, and (at the moment) there's no way to know which image a
        // machine belongs to without searching through the images
        var applications = stores.ApplicationStore.getAll();

        var title = "Instance History";
        var content, instanceHistoryItems;

        if(instanceHistories && applications){
          var historyCount = " (" + instanceHistories.meta.count + " instances launched)";
          title += historyCount;

          instanceHistoryItems = instanceHistories.map(function (instance) {
            var startDate = instance.get('start_date');
            var endDate = instance.get('end_date');

            var formattedStartDate = startDate.format("MMM DD, YYYY");
            var formattedEndDate = endDate.format("MMM DD, YYYY");
            if(!endDate.isValid()) formattedEndDate = "Present";

            var now = moment();
            var timeSpan = now.diff(startDate, "days");

            var instanceHistoryHash = CryptoJS.MD5(instance.id).toString();
            var iconSize = 63;

            var application = stores.ApplicationStore.getApplicationWithMachine(instance.get('machine_alias'));
            var applicationUrl = url.application(application);
            var applicationName = application.get('name');

            return (

                        <Gravatar hash={instanceHistoryHash} size={iconSize}/>

                          {instance.get('name')}

Launched from {applicationName}

{"Ran: " + formattedStartDate + " - " + formattedEndDate}

                          {timeSpan + " days ago"}
                          {" on " + instance.get('provider')}

            );
          }.bind(this));

          // Load more instances from history
          var buttonStyle = {
            margin: "auto",
            display: "block"
          };

          var loadingStyle= {
            margin: "0px auto"
          };

          var moreHistoryButton = null;
          if(instanceHistories.meta.next){
            if(this.state.isLoadingMoreResults){
              moreHistoryButton = (

              );
            }else {
              moreHistoryButton = (
                <button style={buttonStyle} className="btn btn-default" onClick={this.onLoadMoreInstanceHistory}>
                  Show More History
                </button>
              );
            }
          }

          content = (

              {instanceHistoryItems}
              {moreHistoryButton}

          );

        }else{
          content = (

          );
        }

        return (

{title}

            {content}

        );
      }

    });

  });
<commit_msg>fix bug where instance history spinner doesn't go away<commit_after>/** @jsx React.DOM */

define(
  [
    'react',
    'backbone',
    'stores',
    'moment',
    'crypto',
    'components/common/Gravatar.react',
    'url'
  ],
  function (React, Backbone, stores, moment, CryptoJS, Gravatar, url) {

    function getState() {
      return {
        instanceHistory: stores.InstanceHistoryStore.getAll(),
        isLoadingMoreResults: false
      };
    }

    return React.createClass({

      propTypes: {

      },

      getInitialState: function () {
        return getState();
      },

      updateState: function () {
        if (this.isMounted()) this.setState(getState());
      },

      // todo: find a better way to handle this
      // we're listening to changes to the store because the *assumption* is that when the store changes we
      // have a new page of results. This is only true because right now this is the only component that uses
      // the InstanceHistoryStore.  But if we launch an instance and add it to the store (which we don't
      // do currently) this would assume that "add" operations was a "oh, new page of results, sweet!"
      // And that would be an awful lie :(

      componentDidMount: function () {
        stores.InstanceHistoryStore.addChangeListener(this.updateState);
      },

      componentWillUnmount: function () {
        stores.InstanceHistoryStore.removeChangeListener(this.updateState);
      },

      onLoadMoreInstanceHistory: function(){
        this.setState({isLoadingMoreResults: true});
        stores.InstanceHistoryStore.fetchMore();
      },

      render: function () {
        var instanceHistories = stores.InstanceHistoryStore.getAll();

        // we're fetching the applications before the app loads because we need to display links to the images
        // on the dashboard in the instance history, and (at the moment) there's no way to know which image a
        // machine belongs to without searching through the images
        var applications = stores.ApplicationStore.getAll();

        var title = "Instance History";
        var content, instanceHistoryItems;

        if(instanceHistories && applications){
          var historyCount = " (" + instanceHistories.meta.count + " instances launched)";
          title += historyCount;

          instanceHistoryItems = instanceHistories.map(function (instance) {
            var startDate = instance.get('start_date');
            var endDate = instance.get('end_date');

            var formattedStartDate = startDate.format("MMM DD, YYYY");
            var formattedEndDate = endDate.format("MMM DD, YYYY");
            if(!endDate.isValid()) formattedEndDate = "Present";

            var now = moment();
            var timeSpan = now.diff(startDate, "days");

            var instanceHistoryHash = CryptoJS.MD5(instance.id).toString();
            var iconSize = 63;

            var application = stores.ApplicationStore.getApplicationWithMachine(instance.get('machine_alias'));
            var applicationUrl = url.application(application);
            var applicationName = application.get('name');

            return (

                        <Gravatar hash={instanceHistoryHash} size={iconSize}/>

                          {instance.get('name')}

Launched from {applicationName}

{"Ran: " + formattedStartDate + " - " + formattedEndDate}

                          {timeSpan + " days ago"}
                          {" on " + instance.get('provider')}

            );
          }.bind(this));

          // Load more instances from history
          var buttonStyle = {
            margin: "auto",
            display: "block"
          };

          var loadingStyle= {
            margin: "0px auto"
          };

          var moreHistoryButton = null;
          if(instanceHistories.meta.next){
            if(this.state.isLoadingMoreResults){
              moreHistoryButton = (

              );
            }else {
              moreHistoryButton = (
                <button style={buttonStyle} className="btn btn-default" onClick={this.onLoadMoreInstanceHistory}>
                  Show More History
                </button>
              );
            }
          }

          content = (

              {instanceHistoryItems}
              {moreHistoryButton}

          );

        }else{
          content = (

          );
        }

        return (

{title}

            {content}

        );
      }

    });

  });
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var conf = require('./gulp/conf');

var _ = require('lodash');
var wiredep = require('wiredep');

var pathSrcHtml = [
  path.join(conf.paths.src, '/**/*.html')
];

function listFiles() {
  var wiredepOptions = _.extend({}, conf.wiredep, {
    dependencies: true,
    devDependencies: true
  });

  return wiredep(wiredepOptions).js
    .concat([
      path.join(conf.paths.tmp, '/serve/app/index.module.js'),
    ])
    .concat(pathSrcHtml);
}

module.exports = function(config) {
  if (!process.env.SAUCE_USERNAME) {
    console.log('Expected credentials setup');
    process.exit(1);
  }

  var customLaunchers = {
      'SL_Chrome': {
        base: 'SauceLabs',
        browserName: 'chrome',
        version: '45'
      },
      'SL_Firefox': {
        base: 'SauceLabs',
        browserName: 'firefox',
        version: '39'
      },
      'SL_Safari': {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.10',
        version: '8'
      },
      'SL_IE_9': {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 2008',
        version: '9'
      },
      'SL_IE_10': {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 2012',
        version: '10'
      },
      'SL_IE_11': {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8.1',
        version: '11'
      },
      'SL_iOS': {
        base: "SauceLabs",
        browserName: "iphone",
        platform: "OS X 10.10",
        version: "8.1"
      }
  };

  var configuration = {
    files: listFiles(),

    singleRun: true,

    autoWatch: false,

    ngHtml2JsPreprocessor: {
      stripPrefix: conf.paths.src + '/',
      moduleName: 'disclosurePanel'
    },

    logLevel: 'WARN',

    frameworks: ['jasmine'],

    plugins : [
      'karma-phantomjs-launcher',
      'karma-firefox-launcher',
      'karma-coverage',
      'karma-jasmine',
      'karma-ng-html2js-preprocessor',
      'karma-sauce-launcher'
    ],

    sauceLabs: {
      testName: 'Angular disclosure panel'
    },

    captureTimeout: 360000,
    customLaunchers: customLaunchers,

    browsers: Object.keys(customLaunchers),

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

    reporters: ['dots', 'saucelabs']
  };

  // This is the default preprocessors configuration for a usage with Karma cli
  // The coverage preprocessor in added in gulp/unit-test.js only for single tests
  // It was not possible to do it there because karma doesn't let us now if we are
  // running a single test or not
  configuration.preprocessors = {};
  pathSrcHtml.forEach(function(path) {
    configuration.preprocessors[path] = ['ng-html2js'];
  });

  config.set(configuration);
};
<commit_msg>Updated capture timeout<commit_after>'use strict';

var path = require('path');
var conf = require('./gulp/conf');

var _ = require('lodash');
var wiredep = require('wiredep');

var pathSrcHtml = [
  path.join(conf.paths.src, '/**/*.html')
];

function listFiles() {
  var wiredepOptions = _.extend({}, conf.wiredep, {
    dependencies: true,
    devDependencies: true
  });

  return wiredep(wiredepOptions).js
    .concat([
      path.join(conf.paths.tmp, '/serve/app/index.module.js'),
    ])
    .concat(pathSrcHtml);
}

module.exports = function(config) {
  if (!process.env.SAUCE_USERNAME) {
    console.log('Expected credentials setup');
    process.exit(1);
  }

  var customLaunchers = {
      'SL_Chrome': {
        base: 'SauceLabs',
        browserName: 'chrome',
        version: '45'
      },
      'SL_Firefox': {
        base: 'SauceLabs',
        browserName: 'firefox',
        version: '39'
      },
      'SL_Safari': {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.10',
        version: '8'
      },
      'SL_IE_9': {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 2008',
        version: '9'
      },
      'SL_IE_10': {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 2012',
        version: '10'
      },
      'SL_IE_11': {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8.1',
        version: '11'
      },
      'SL_iOS': {
        base: "SauceLabs",
        browserName: "iphone",
        platform: "OS X 10.10",
        version: "8.1"
      }
  };

  var configuration = {
    files: listFiles(),

    singleRun: true,

    autoWatch: false,

    ngHtml2JsPreprocessor: {
      stripPrefix: conf.paths.src + '/',
      moduleName: 'disclosurePanel'
    },

    logLevel: 'WARN',

    frameworks: ['jasmine'],

    plugins : [
      'karma-phantomjs-launcher',
      'karma-firefox-launcher',
      'karma-coverage',
      'karma-jasmine',
      'karma-ng-html2js-preprocessor',
      'karma-sauce-launcher'
    ],

    sauceLabs: {
      testName: 'Angular disclosure panel'
    },

    captureTimeout: 3600000,
    customLaunchers: customLaunchers,

    browsers: Object.keys(customLaunchers),

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

    reporters: ['dots', 'saucelabs']
  };

  // This is the default preprocessors configuration for a usage with Karma cli
  // The coverage preprocessor in added in gulp/unit-test.js only for single tests
  // It was not possible to do it there because karma doesn't let us now if we are
  // running a single test or not
  configuration.preprocessors = {};
  pathSrcHtml.forEach(function(path) {
    configuration.preprocessors[path] = ['ng-html2js'];
  });

  config.set(configuration);
};
<|endoftext|>


<commit_before><commit_msg>lint: make generateImages script eslint compliant (add semicolons etc)<commit_after><|endoftext|>


<commit_before>'use strict';

var mongoose     = require ('mongoose');
var Schema       = mongoose.Schema;

var DocumentSchema  = new Schema ({

 //    ------------------------------------------------------------
 //    Short form rules for e-PIC
 //    ------------------------------------------------------------

 //    Folder Type:
 //    ------------------------------
 //    r= Under Review
 //    p= Pre-Application
 //    w= Withdrawn
 //    t= Terminated
 //    a= Certificate Issued
 //    k= Amendments

 //    Folder Name short form:
 //    ------------------------------
 //    abo = Aboriginal Comments/Submissions
 //    amd = Amendment Certificate
 //    yaa = Amendment to Certificate Documentation
 //    ama = Amendment - Application
 //    app = Application and Supporting Studies
 //    tor = Application Terms of Reference/Information Requirements
 //    cag = Community Advisory Group
 //    cpp = Compendium: Public Comments / Proponent Responses
 //    crr = Compliance Reports/Reviews
 //    cpm = Concurrent Permitting
 //    waa = EA Certificate Documentation
 //    com = EAO Generated Documents
 //    fed = Federal Comments/Submissions
 //    gcd = General Consultiation Documents
 //    loc = Local Government Comments/Submissions
 //    mno = Ministerial Order
 //    new = Notices - News Releases
 //    ojc = Other Jurisdictions Comments/Submissions
 //    xaa = Post Certificate Documentation
 //    abc = Pre Application Documents
 //    pro = Proponent Comments/Correspondence
 //    pga = Provincial Govt Comments/Submissions
 //    pub = Public Comments/Submissions
 //    ------------------------------

 //    Example Links:
 //    ------------------------------
 //    // 1: Root level project page - shows root level folder type options for the project.
	// https://a100.gov.bc.ca/appsdata/epic/html/deploy/epic_project_home_362.html
	// 362=[projectID]

 //    // 2: Root level folder lists available Folder Type+Folder Name folders.
 //    // The Under Review/Pre-application/Withdrawn/etc. set of folders and their subfolders
	// https://a100.gov.bc.ca/appsdata/epic/html/deploy/epic_project_doc_list_362_r_app.html
	// 362= [projectID]
 //    Folder Type: r= [Under Review]
	// Folder Name Short Form: app= [Application and Supporting Studies]

 //    // 3: FolderName - The title of the folder containing the collection of documents
 //    EG: Application Main Report received January 18, 2016
 //    // This exists as content in "2: Root level folder lists available..." above

 //    // 4: Child folder where the collection of documents related to a specific Folder Type+Folder Name
 //    // can be found.
 //    https://a100.gov.bc.ca/appsdata/epic/html/deploy/epic_document_362_39700.html
 //    362= [projectID]
 //    39700= EPIC DirectoryID (becomes d39700) Not related to the specific project

 //    Actual Document Link:
 //    ------------------------------
 //    https://a100.gov.bc.ca/appsdata/epic/documents/p362/d39700/1453141986150_QzJ9WdsMpRJvp1GtL2JJmYjYw0jptTxFgrx6SyVKDJxRgQFvZ9Jq!1143392206!1453141196524.pdf
 //    p362= [ProjectID]
 //    d39700= [DirectoryID] Not related to the specific project
 //    1453141986150= (RANDOM) Probably the uploadID when it was originally placed
 //    QzJ9WdsMpRJvp1GtL2JJmYjYw0jptTxFgrx6SyVKDJxRgQFvZ9Jq!1143392206!1453141196524= (RANDOM) Probably the SessionID for a group of uploaded assets (in a folder only?)

    project                        : { type:'ObjectId', ref:'Project', default:null },
    dateAdded                      : { type: Date, default: Date.now },
    dateUpdated                    : { type: Date, default: Date.now },
    updatedBy                      : { type:'ObjectId', ref:'User', default:null },
    projectFolderType              : { type:String, default:'' }, // r=/p=/w=/t=/a=/k=
    projectFolderSubType           : { type:String, default:'' }, // abo/amd/etc.
    projectFolderName              : { type:String, default:'' }, // Title of the folder that's within the Folder Type+SubType
    projectFolderURL               : { type:String, default:'' }, // The specific DirectoryID instance of a collection of documents
    projectFolderDatePosted        : { type: Date, default: Date.now }, // We'll want to convert any incoming date to this fmt.
    projectFolderAuthor            : { type:String, default:'' },
    documentFileName               : { type:String, default:'' }, // A.K.A. Document File Name in EPIC
    documentFileURL                : { type:String, default:'' },
    documentFileSize               : { type:String, default:'' }, // Looks like everything is in KB
    documentFileFormat             : { type:String, default:'' },
    documentVersion                : { type:Number, default:0 }, // Used for keeping track of this documents version.
    documentIsLatestVersion        : { type:Boolean, default:true }, // We assume we are the latest.
    documentIsInReview             : { type:Boolean, default:false }, // Used to flag if this entry is a reviewable entry.
    documentAuthor                 : { type:String, default:'' },  // NB: We should add a document author in addition to the folderAuthor.
    internalURL                    : { type:String, default:'' },
    internalOriginalName           : { type:String, default:'' },
    internalName                   : { type:String, default:'' },
    internalMime                   : { type:String, default:'' },
    internalExt                    : { type:String, default:'' },
    internalSize                   : { type:Number, default:0 },
    internalEncoding               : { type:String, default:'' }

});
var mDocument = mongoose.model ('Document', DocumentSchema);
module.exports = mDocument;

var TypesSchema  = new Schema ({
    projectFolderType : { type:String, default:'' },
    projectFolderSubTypeObjects : []
});
var mTypesSchema = mongoose.model ('TypesSchema', TypesSchema);
module.exports = mTypesSchema;

var SubTypesSchema  = new Schema ({
    projectFolderSubType : { type:String, default:'' },
    projectFolderNames: []
});
var mSubTypesSchema = mongoose.model ('SubTypesSchema', SubTypesSchema);
module.exports = mSubTypesSchema;
<commit_msg>Quick comment to lay out the groundwork for ESM-156.<commit_after>'use strict';

var mongoose     = require ('mongoose');
var Schema       = mongoose.Schema;

var DocumentSchema  = new Schema ({

 //    ------------------------------------------------------------
 //    Short form rules for e-PIC
 //    ------------------------------------------------------------

 //    Folder Type:
 //    ------------------------------
 //    r= Under Review
 //    p= Pre-Application
 //    w= Withdrawn
 //    t= Terminated
 //    a= Certificate Issued
 //    k= Amendments

 //    Folder Name short form:
 //    ------------------------------
 //    abo = Aboriginal Comments/Submissions
 //    amd = Amendment Certificate
 //    yaa = Amendment to Certificate Documentation
 //    ama = Amendment - Application
 //    app = Application and Supporting Studies
 //    tor = Application Terms of Reference/Information Requirements
 //    cag = Community Advisory Group
 //    cpp = Compendium: Public Comments / Proponent Responses
 //    crr = Compliance Reports/Reviews
 //    cpm = Concurrent Permitting
 //    waa = EA Certificate Documentation
 //    com = EAO Generated Documents
 //    fed = Federal Comments/Submissions
 //    gcd = General Consultiation Documents
 //    loc = Local Government Comments/Submissions
 //    mno = Ministerial Order
 //    new = Notices - News Releases
 //    ojc = Other Jurisdictions Comments/Submissions
 //    xaa = Post Certificate Documentation
 //    abc = Pre Application Documents
 //    pro = Proponent Comments/Correspondence
 //    pga = Provincial Govt Comments/Submissions
 //    pub = Public Comments/Submissions
 //    ------------------------------

 //    Example Links:
 //    ------------------------------
 //    // 1: Root level project page - shows root level folder type options for the project.
	// https://a100.gov.bc.ca/appsdata/epic/html/deploy/epic_project_home_362.html
	// 362=[projectID]

 //    // 2: Root level folder lists available Folder Type+Folder Name folders.
 //    // The Under Review/Pre-application/Withdrawn/etc. set of folders and their subfolders
	// https://a100.gov.bc.ca/appsdata/epic/html/deploy/epic_project_doc_list_362_r_app.html
	// 362= [projectID]
 //    Folder Type: r= [Under Review]
	// Folder Name Short Form: app= [Application and Supporting Studies]

 //    // 3: FolderName - The title of the folder containing the collection of documents
 //    EG: Application Main Report received January 18, 2016
 //    // This exists as content in "2: Root level folder lists available..." above

 //    // 4: Child folder where the collection of documents related to a specific Folder Type+Folder Name
 //    // can be found.
 //    https://a100.gov.bc.ca/appsdata/epic/html/deploy/epic_document_362_39700.html
 //    362= [projectID]
 //    39700= EPIC DirectoryID (becomes d39700) Not related to the specific project

 //    Actual Document Link:
 //    ------------------------------
 //    https://a100.gov.bc.ca/appsdata/epic/documents/p362/d39700/1453141986150_QzJ9WdsMpRJvp1GtL2JJmYjYw0jptTxFgrx6SyVKDJxRgQFvZ9Jq!1143392206!1453141196524.pdf
 //    p362= [ProjectID]
 //    d39700= [DirectoryID] Not related to the specific project
 //    1453141986150= (RANDOM) Probably the uploadID when it was originally placed
 //    QzJ9WdsMpRJvp1GtL2JJmYjYw0jptTxFgrx6SyVKDJxRgQFvZ9Jq!1143392206!1453141196524= (RANDOM) Probably the SessionID for a group of uploaded assets (in a folder only?)

    project                        : { type:'ObjectId', ref:'Project', default:null },
    dateAdded                      : { type: Date, default: Date.now },
    dateUpdated                    : { type: Date, default: Date.now },
    updatedBy                      : { type:'ObjectId', ref:'User', default:null },
    projectFolderType              : { type:String, default:'' }, // r=/p=/w=/t=/a=/k=
    projectFolderSubType           : { type:String, default:'' }, // abo/amd/etc.
    projectFolderName              : { type:String, default:'' }, // Title of the folder that's within the Folder Type+SubType
    projectFolderURL               : { type:String, default:'' }, // The specific DirectoryID instance of a collection of documents
    projectFolderDatePosted        : { type: Date, default: Date.now }, // We'll want to convert any incoming date to this fmt.
    projectFolderAuthor            : { type:String, default:'' },
    documentFileName               : { type:String, default:'' }, // A.K.A. Document File Name in EPIC
    documentFileURL                : { type:String, default:'' },
    documentFileSize               : { type:String, default:'' }, // Looks like everything is in KB
    documentFileFormat             : { type:String, default:'' },
    documentVersion                : { type:Number, default:0 }, // Used for keeping track of this documents version.
    documentIsLatestVersion        : { type:Boolean, default:true }, // We assume we are the latest. Default will be false
                                                                     // when we hook in the reviewable interface which will
                                                                     // decide what is the latest based on approval of such
    documentIsInReview             : { type:Boolean, default:false }, // Used to flag if this entry is a reviewable entry.
    documentAuthor                 : { type:String, default:'' },  // NB: We should add a document author in addition to the folderAuthor.
    internalURL                    : { type:String, default:'' },
    internalOriginalName           : { type:String, default:'' },
    internalName                   : { type:String, default:'' },
    internalMime                   : { type:String, default:'' },
    internalExt                    : { type:String, default:'' },
    internalSize                   : { type:Number, default:0 },
    internalEncoding               : { type:String, default:'' }

});
var mDocument = mongoose.model ('Document', DocumentSchema);
module.exports = mDocument;

var TypesSchema  = new Schema ({
    projectFolderType : { type:String, default:'' },
    projectFolderSubTypeObjects : []
});
var mTypesSchema = mongoose.model ('TypesSchema', TypesSchema);
module.exports = mTypesSchema;

var SubTypesSchema  = new Schema ({
    projectFolderSubType : { type:String, default:'' },
    projectFolderNames: []
});
var mSubTypesSchema = mongoose.model ('SubTypesSchema', SubTypesSchema);
module.exports = mSubTypesSchema;
<|endoftext|>


<commit_before>// VVVV.js -- Visual Web Client Programming
// (c) 2011 Matthias Zauner
// VVVV.js is freely distributable under the MIT license.
// Additional authors of sub components are mentioned at the specific code locations.
// This component was developed is (c) 2014 Lukas Winter, distributed under the MIT license.

VVVV.PinTypes.WebAudio = {
  typeName: "WebAudio",
  reset_on_disconnect: true,
  defaultValue: function() {
    return "Unconnected Audio";
  },
  connectionChangedHandlers: {
    'webaudio': function() {
      if(this.direction == PinDirection.Input)
        this.audioConnectionChanged = true;
    }
  }
}

var audioContext = null;

function WebAudioNode(id, name, graph) {
  if(graph) //constructing actual node
  {
    this.constructor(id, name, graph);
    if(!audioContext)
    {
      audioContext = new AudioContext();
    }
    this.initialize = function()
    {
      this.createAPINode();
      this.createAudioPins();
      this.createParamPins();
    }
    this.audioInputPins = [];
    this.audioOutputPins = [];
  }
  else //constructing prototype
  {
    this.createAPINode = function()
    {
      this.apiNode = audioContext['create'+id].apply(audioContext, arguments);
    }
    this.auto_evaluate = false;
  }
}
WebAudioNode.prototype = new VVVV.Core.Node();
WebAudioNode.prototype.createAudioPins = function()
{
  for(var i = 0; i < this.apiNode.numberOfInputs; i++)
  {
    this.audioInputPins.push(this.addInputPin('Input '+(i+1), [], VVVV.PinTypes.WebAudio));
  }
  for(var i = 0; i < this.apiNode.numberOfInputs; i++)
  {
    this.audioOutputPins.push(this.addOutputPin('Output '+(i+1), [], VVVV.PinTypes.WebAudio));
  }
}
WebAudioNode.prototype.createParamPins = function()
{
  for(var key in this.apiNode)
  {
    var param = this.apiNode[key];
    if(key instanceof AudioParam)
    {
      this.addInputPin(key.replace(/([a-z^])([A-Z])/g, '$1 $2'), [param.defaultValue], VVVV.PinTypes.WebAudio);
    }
  }
}
WebAudioNode.prototype.updateAudioConnections = function()
{
  var that = this;
  this.audioInputPins.forEach(function(audioIn, i) {
    if(audioIn.audioConnectionChanged && audioIn.getValue(0) instanceof AudioNode)
    {
      console.log("Connecting!");
      audioIn.getValue(0).connect(that.apiNode, 0 /*FIXME*/, i);
      audioIn.audioConnectionChanged = false;
    }

  });
}

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: AnalyserNode (HTML5 Audio)
 Author(s): 'Lukas Winter'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.AnalyserNode = function(id, graph) {
  WebAudioNode.call(this, id, 'AnalyserNode (HTML5 Audio)', graph);

  this.meta = {
    authors: ['Lukas Winter'],
    original_authors: [],
    credits: [],
    compatibility_issues: []
  };

  var that = this;

  var fftSizeIn = this.addInputPin('FFTSize', ['2048'], VVVV.PinTypes.Value);
  var smoothingIn = this.addInputPin('Smoothing', [0.8], VVVV.PinTypes.Value);
  var fftOut = this.addOutputPin('FFT', [], VVVV.PinTypes.Value);
  var fftData;

  function setFFTSize(size)
  {
    if(!size)
      size = 32;
    fftOut.setSliceCount(size);
    fftData = new Float32Array(size);
  }

  setFFTSize(2048);

  this.evaluate = function()
  {
    if(fftSizeIn.pinIsChanged())
      setFFTSize(fftSizeIn.getValue(0));
    if(smoothingIn.pinIsChanged())
      this.apiNode.smoothingTimeConstant = smoothingIn.getValue(0);

    this.updateAudioConnections();
    this.apiNode.getFloatFrequencyData(fftData);
    for(var i = 0; i < fftData.length; i++)
    {
      fftOut.setValue(i, fftData[i]); //FIXME: veeeeery inefficient!
    }
  }
}
VVVV.Nodes.AnalyserNode.prototype = new WebAudioNode('Analyser');

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: MediaElementSource (HTML5 Audio)
 Author(s): 'Lukas Winter'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.MediaElementSource = function(id, graph) {
  WebAudioNode.call(this, id, 'MediaElementSource (HTML5 Audio)', graph);

  this.meta = {
    authors: ['Lukas Winter'],
    original_authors: [],
    credits: [],
    compatibility_issues: []
  };

  var audioIn = this.addInputPin('Audio', [], this);
  var audioOut = this.addOutputPin('Output', [], VVVV.PinTypes.WebAudio);

  this.initialize = function() {};

  var mediaElements = [ 7 ];

  this.evaluate = function() {
    if(audioIn.pinIsChanged())
    {
      var inElement = audioIn.getValue(0);
      if(inElement != mediaElements[0] && inElement)
      {
        mediaElements[0] = inElement;
        this.createAPINode(audioIn.getValue(0));
      }

      if(this.apiNode)
      {
        audioOut.setValue(0, this.apiNode);
      }
    }

  }
}
VVVV.Nodes.MediaElementSource.prototype = new WebAudioNode('MediaElementSource');

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: BeatDetector (HTML5 Audio)
 Author(s): 'Lukas Winter'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.BeatDetector = function(id, graph) {
  WebAudioNode.call(this, id, 'BeatDetector (HTML5 Audio)', graph);

  this.meta = {
    authors: ['Lukas Winter'],
    original_authors: [],
    credits: [],
    compatibility_issues: []
  };

  var that = this;
  var fftSize = 1024;
  var fftData = new Float32Array(fftSize);
  var beatDetector;

  var beatCounterOut = this.addOutputPin('Beat Counter', [ 0 ], VVVV.PinTypes.Value);
  var bpmOut = this.addOutputPin('BPM', [ 0 ], VVVV.PinTypes.Value);

  var initialize = this.initialize;
  this.initialize = function() {
    initialize.call(this);
    this.apiNode.fftSize = fftSize;
    this.apiNode.smoothingTimeConstant = 0;
  }

  this.evaluate = function()
  {
    if(!beatDetector)
      beatDetector = new BeatDetektor();
    this.updateAudioConnections();
    this.apiNode.getFloatFrequencyData(fftData);
    beatDetector.process(audioContext.currentTime, fftData);
    beatCounterOut.setValue(0, beatDetector.beat_counter);
    bpmOut.setValue(0, beatDetector.win_bpm_int / 10);
  }
}
VVVV.Nodes.BeatDetector.prototype = new WebAudioNode('Analyser');

/*VVVV.Nodes.BiquadFilterNode = makeAudioNodeConstructor('BiquadFilter');
VVVV.Nodes.ChannelMergerNode = makeAudioNodeConstructor('ChannelMerger');
VVVV.Nodes.ChannelSplitterNode = makeAudioNodeConstructor('ChannelSplitter');
VVVV.Nodes.ConvolverNode = makeAudioNodeConstructor('Convolver');
VVVV.Nodes.DelayNode = makeAudioNodeConstructor('Delay');
VVVV.Nodes.DynamicsCompressorNode = makeAudioNodeConstructor('DynamicsCompressor');
VVVV.Nodes.GainNode = makeAudioNodeConstructor('Gain');
VVVV.Nodes.OscillatorNode = makeAudioNodeConstructor('Oscillator');
VVVV.Nodes.PannerNode = makeAudioNodeConstructor('Panner');
VVVV.Nodes.ScriptProcessorNode = makeAudioNodeConstructor('ScriptProcessor');
VVVV.Nodes.WaveShaperNode = makeAudioNodeConstructor('WaveShaper');*/

<commit_msg>Fix typ in audio code and WebAudio not working in Firefox when muted<commit_after>// VVVV.js -- Visual Web Client Programming
// (c) 2011 Matthias Zauner
// VVVV.js is freely distributable under the MIT license.
// Additional authors of sub components are mentioned at the specific code locations.
// This component was developed is (c) 2014 Lukas Winter, distributed under the MIT license.

VVVV.PinTypes.WebAudio = {
  typeName: "WebAudio",
  reset_on_disconnect: true,
  defaultValue: function() {
    return "Unconnected Audio";
  },
  connectionChangedHandlers: {
    'webaudio': function() {
      if(this.direction == PinDirection.Input)
        this.audioConnectionChanged = true;
    }
  }
}

var audioContext = null;

function WebAudioNode(id, name, graph) {
  if(graph) //constructing actual node
  {
    this.constructor(id, name, graph);
    if(!audioContext)
    {
      audioContext = new AudioContext();
    }
    this.initialize = function()
    {
      this.createAPINode();
      this.createAudioPins();
      this.createParamPins();
    }
    this.audioInputPins = [];
    this.audioOutputPins = [];
  }
  else //constructing prototype
  {
    this.createAPINode = function()
    {
      this.apiNode = audioContext['create'+id].apply(audioContext, arguments);
    }
    this.auto_evaluate = false;
  }
}
WebAudioNode.prototype = new VVVV.Core.Node();
WebAudioNode.prototype.createAudioPins = function()
{
  for(var i = 0; i < this.apiNode.numberOfInputs; i++)
  {
    this.audioInputPins.push(this.addInputPin('Input '+(i+1), [], VVVV.PinTypes.WebAudio));
  }
  for(var i = 0; i < this.apiNode.numberOfOutputs; i++)
  {
    this.audioOutputPins.push(this.addOutputPin('Output '+(i+1), [], VVVV.PinTypes.WebAudio));
  }
}
WebAudioNode.prototype.createParamPins = function()
{
  for(var key in this.apiNode)
  {
    var param = this.apiNode[key];
    if(key instanceof AudioParam)
    {
      this.addInputPin(key.replace(/([a-z^])([A-Z])/g, '$1 $2'), [param.defaultValue], VVVV.PinTypes.WebAudio);
    }
  }
}
WebAudioNode.prototype.updateAudioConnections = function()
{
  var that = this;
  this.audioInputPins.forEach(function(audioIn, i) {
    if(audioIn.audioConnectionChanged && audioIn.getValue(0) instanceof AudioNode)
    {
      console.log("Connecting!");
      audioIn.getValue(0).connect(that.apiNode, 0 /*FIXME*/, i);
      audioIn.audioConnectionChanged = false;
    }

  });
}

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: AnalyserNode (HTML5 Audio)
 Author(s): 'Lukas Winter'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.AnalyserNode = function(id, graph) {
  WebAudioNode.call(this, id, 'AnalyserNode (HTML5 Audio)', graph);

  this.meta = {
    authors: ['Lukas Winter'],
    original_authors: [],
    credits: [],
    compatibility_issues: []
  };

  var that = this;

  var fftSizeIn = this.addInputPin('FFTSize', ['2048'], VVVV.PinTypes.Value);
  var smoothingIn = this.addInputPin('Smoothing', [0.8], VVVV.PinTypes.Value);
  var fftOut = this.addOutputPin('FFT', [], VVVV.PinTypes.Value);
  var fftData;

  function setFFTSize(size)
  {
    if(!size)
      size = 32;
    fftOut.setSliceCount(size);
    fftData = new Float32Array(size);
  }

  setFFTSize(2048);

  this.evaluate = function()
  {
    if(fftSizeIn.pinIsChanged())
      setFFTSize(fftSizeIn.getValue(0));
    if(smoothingIn.pinIsChanged())
      this.apiNode.smoothingTimeConstant = smoothingIn.getValue(0);

    this.updateAudioConnections();
    this.apiNode.getFloatFrequencyData(fftData);
    for(var i = 0; i < fftData.length; i++)
    {
      fftOut.setValue(i, fftData[i]); //FIXME: veeeeery inefficient!
    }
  }
}
VVVV.Nodes.AnalyserNode.prototype = new WebAudioNode('Analyser');

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: MediaElementSource (HTML5 Audio)
 Author(s): 'Lukas Winter'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.MediaElementSource = function(id, graph) {
  WebAudioNode.call(this, id, 'MediaElementSource (HTML5 Audio)', graph);

  this.meta = {
    authors: ['Lukas Winter'],
    original_authors: [],
    credits: [],
    compatibility_issues: []
  };

  var audioIn = this.addInputPin('Audio', [], this);
  var audioOut = this.addOutputPin('Output', [], VVVV.PinTypes.WebAudio);

  this.initialize = function() {};

  var mediaElements = [ 7 ];

  this.evaluate = function() {
    if(audioIn.pinIsChanged())
    {
      var inElement = audioIn.getValue(0);
      if(inElement != mediaElements[0] && inElement)
      {
        mediaElements[0] = inElement;
        this.createAPINode(audioIn.getValue(0));
        inElement.volume = 1;
      }

      if(this.apiNode)
      {
        audioOut.setValue(0, this.apiNode);
      }
    }

  }
}
VVVV.Nodes.MediaElementSource.prototype = new WebAudioNode('MediaElementSource');

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: BeatDetector (HTML5 Audio)
 Author(s): 'Lukas Winter'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.BeatDetector = function(id, graph) {
  WebAudioNode.call(this, id, 'BeatDetector (HTML5 Audio)', graph);

  this.meta = {
    authors: ['Lukas Winter'],
    original_authors: [],
    credits: [],
    compatibility_issues: []
  };

  var that = this;
  var fftSize = 1024;
  var fftData = new Float32Array(fftSize);
  var beatDetector;

  var beatCounterOut = this.addOutputPin('Beat Counter', [ 0 ], VVVV.PinTypes.Value);
  var bpmOut = this.addOutputPin('BPM', [ 0 ], VVVV.PinTypes.Value);

  var initialize = this.initialize;
  this.initialize = function() {
    initialize.call(this);
    this.apiNode.fftSize = fftSize;
    this.apiNode.smoothingTimeConstant = 0;
  }

  this.evaluate = function()
  {
    if(!beatDetector)
      beatDetector = new BeatDetektor();
    this.updateAudioConnections();
    this.apiNode.getFloatFrequencyData(fftData);
    beatDetector.process(audioContext.currentTime, fftData);
    beatCounterOut.setValue(0, beatDetector.beat_counter);
    bpmOut.setValue(0, beatDetector.win_bpm_int / 10);
  }
}
VVVV.Nodes.BeatDetector.prototype = new WebAudioNode('Analyser');

/*VVVV.Nodes.BiquadFilterNode = makeAudioNodeConstructor('BiquadFilter');
VVVV.Nodes.ChannelMergerNode = makeAudioNodeConstructor('ChannelMerger');
VVVV.Nodes.ChannelSplitterNode = makeAudioNodeConstructor('ChannelSplitter');
VVVV.Nodes.ConvolverNode = makeAudioNodeConstructor('Convolver');
VVVV.Nodes.DelayNode = makeAudioNodeConstructor('Delay');
VVVV.Nodes.DynamicsCompressorNode = makeAudioNodeConstructor('DynamicsCompressor');
VVVV.Nodes.GainNode = makeAudioNodeConstructor('Gain');
VVVV.Nodes.OscillatorNode = makeAudioNodeConstructor('Oscillator');
VVVV.Nodes.PannerNode = makeAudioNodeConstructor('Panner');
VVVV.Nodes.ScriptProcessorNode = makeAudioNodeConstructor('ScriptProcessor');
VVVV.Nodes.WaveShaperNode = makeAudioNodeConstructor('WaveShaper');*/

<|endoftext|>


<commit_before>export const NEW_GAME_ACTION_TYPE = 'NEW_GAME';
<commit_msg>Removing obsolete file.<commit_after><|endoftext|>


<commit_before>// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Atoms for frame handling.
 *
 */

goog.provide('bot.frame');

goog.require('bot.locators');
goog.require('goog.array');
goog.require('goog.dom');

/**
 * @return {!Window} The top window.
 */
bot.frame.defaultContent = function() {
  return bot.getWindow().top;
};

/**
 * @return {!Element} The currently active element.
 */
bot.frame.activeElement = function() {
  return document.activeElement || document.body;
};

/**
 * Returns a reference to the window object corresponding to the given element.
 * Note that the element must be a frame or an iframe.
 *
 * @param {!HTMLIFrameElement|!HTMLFrameElement} element The iframe or frame
 *     element.
 * @return {Window} The window reference for the given iframe or frame element.
 */
bot.frame.getFrameWindow = function(element) {
  if (/^i?frame$/i.test(element.tagName)) {
    var frame = /** @type {HTMLFrameElement|HTMLIFrameElement} */ element;
    return goog.dom.getFrameContentWindow(frame);
  }
  throw new bot.Error(bot.ErrorCode.NO_SUCH_FRAME,
      "The given element isn't a frame or an iframe.");
};

/**
 * Looks for a frame by its name or id (preferring name over id)
 * under the given root. If no frame was found, we look for an
 * iframe by name or id.
 *
 * @param {(string|number)} nameOrId The frame's name or the frame's id.
 * @param {Window} opt_root The window to perform the search under.
 *     Defaults to {@code bot.getWindow()}.
 * @return {Window} The window if found, null otherwise.
 */
bot.frame.findFrameByNameOrId = function(nameOrId, opt_root) {
  var domWindow = opt_root || bot.getWindow();

  // Lookup frame by name
  var frame = domWindow.frames[nameOrId];
  if (frame) {
    // This is needed because Safari 4 returns
    // an HTMLFrameElement instead of a Window object.
    if (frame.document) {
      return frame;
    } else {
      return goog.dom.getFrameContentWindow(frame);
    }
  }

  // Lookup frame by id
  var isFrame = function(element) {
    return bot.dom.isElement(element, goog.dom.TagName.FRAME) ||
        bot.dom.isElement(element, goog.dom.TagName.IFRAME);
  }
  var elements = bot.locators.findElements({id: nameOrId},
      domWindow.document);
  for (var i = 0; i < elements.length; i++) {
    if (isFrame(elements[i])) {
      return goog.dom.getFrameContentWindow(elements[i]);
    }
  }
  return null;
};

/**
 * Looks for a frame by its index under the given root.
 *
 * @param {number} index The frame's index.
 * @param {Window} opt_root The window to perform
 *     the search under. Defaults to {@code bot.getWindow()}.
 * @return {Window} The frame if found, null otherwise.
 */
bot.frame.findFrameByIndex = function(index, opt_root) {
  var domWindow = opt_root || bot.getWindow();
  return domWindow.frames[index] || null;
};

/**
 * Gets the index of a frame in the given window. Note that the element must
 * be a frame or an iframe.
 *
 * @param {!HTMLIFrameElement|!HTMLFrameElement} element The iframe or frame
 *     element.
 * @param {Window} opt_root The window to perform
 *     the search under. Defaults to {@code bot.getWindow()}.
 * @return {number=} The index of the frame if found, null otherwise.
 */
bot.frame.getFrameIndex = function(element, opt_root) {
  var domWindow = opt_root || bot.getWindow();

  if (!bot.dom.isElement(element, goog.dom.TagName.FRAME) &&
      !bot.dom.isElement(element, goog.dom.TagName.IFRAME)
  ) {
    return null;
  }
  for (var i = 0; i < domWindow.frames.length; i++) {
    if (element.contentWindow == domWindow.frames[i]) {
      return i;
    }
  }
  return null;
};
<commit_msg>JasonLeyba: Nit-picky fixes for jsdoc type-annotations from r13805.<commit_after>// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Atoms for frame handling.
 *
 */

goog.provide('bot.frame');

goog.require('bot.locators');
goog.require('goog.array');
goog.require('goog.dom');

/**
 * @return {!Window} The top window.
 */
bot.frame.defaultContent = function() {
  return bot.getWindow().top;
};

/**
 * @return {!Element} The currently active element.
 */
bot.frame.activeElement = function() {
  return document.activeElement || document.body;
};

/**
 * Returns a reference to the window object corresponding to the given element.
 * Note that the element must be a frame or an iframe.
 *
 * @param {!(HTMLIFrameElement|HTMLFrameElement)} element The iframe or frame
 *     element.
 * @return {Window} The window reference for the given iframe or frame element.
 */
bot.frame.getFrameWindow = function(element) {
  if (/^i?frame$/i.test(element.tagName)) {
    var frame = /** @type {HTMLFrameElement|HTMLIFrameElement} */ element;
    return goog.dom.getFrameContentWindow(frame);
  }
  throw new bot.Error(bot.ErrorCode.NO_SUCH_FRAME,
      "The given element isn't a frame or an iframe.");
};

/**
 * Looks for a frame by its name or id (preferring name over id)
 * under the given root. If no frame was found, we look for an
 * iframe by name or id.
 *
 * @param {(string|number)} nameOrId The frame's name or the frame's id.
 * @param {!Window=} opt_root The window to perform the search under.
 *     Defaults to {@code bot.getWindow()}.
 * @return {Window} The window if found, null otherwise.
 */
bot.frame.findFrameByNameOrId = function(nameOrId, opt_root) {
  var domWindow = opt_root || bot.getWindow();

  // Lookup frame by name
  var frame = domWindow.frames[nameOrId];
  if (frame) {
    // This is needed because Safari 4 returns
    // an HTMLFrameElement instead of a Window object.
    if (frame.document) {
      return frame;
    } else {
      return goog.dom.getFrameContentWindow(frame);
    }
  }

  // Lookup frame by id
  var isFrame = function(element) {
    return bot.dom.isElement(element, goog.dom.TagName.FRAME) ||
        bot.dom.isElement(element, goog.dom.TagName.IFRAME);
  }
  var elements = bot.locators.findElements({id: nameOrId},
      domWindow.document);
  for (var i = 0; i < elements.length; i++) {
    if (isFrame(elements[i])) {
      return goog.dom.getFrameContentWindow(elements[i]);
    }
  }
  return null;
};

/**
 * Looks for a frame by its index under the given root.
 *
 * @param {number} index The frame's index.
 * @param {!Window=} opt_root The window to perform
 *     the search under. Defaults to {@code bot.getWindow()}.
 * @return {Window} The frame if found, null otherwise.
 */
bot.frame.findFrameByIndex = function(index, opt_root) {
  var domWindow = opt_root || bot.getWindow();
  return domWindow.frames[index] || null;
};

/**
 * Gets the index of a frame in the given window. Note that the element must
 * be a frame or an iframe.
 *
 * @param {!(HTMLIFrameElement|HTMLFrameElement)} element The iframe or frame
 *     element.
 * @param {!Window=} opt_root The window to perform
 *     the search under. Defaults to {@code bot.getWindow()}.
 * @return {number} The index of the frame if found, null otherwise.
 */
bot.frame.getFrameIndex = function(element, opt_root) {
  var domWindow = opt_root || bot.getWindow();

  if (!bot.dom.isElement(element, goog.dom.TagName.FRAME) &&
      !bot.dom.isElement(element, goog.dom.TagName.IFRAME)
  ) {
    return null;
  }
  for (var i = 0; i < domWindow.frames.length; i++) {
    if (element.contentWindow == domWindow.frames[i]) {
      return i;
    }
  }
  return null;
};
<|endoftext|>


<commit_before>/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
ABOUT THIS NODE.JS EXAMPLE: This example works with AWS SDK for JavaScript version 3 (v3),
which is available at https://github.com/aws/aws-sdk-js-v3. For information about how AWS CodeBuild works,
see https://docs.aws.amazon.com/codebuild/latest/userguide/concepts.html.

Purpose:
createProject.js demonstrates how to create an AWS CodeBuild project.

Inputs (replace in code):
- TYPE_OF_BUILD_OUTPUT
- COMPUTE_TYPE
- IMAGE_NAME
- ENVIRONMENT_TYPE
- PROJECT_NAME
- IAM_ROLE
- SOURCE_TYPE
- LOCATION_TO_BUILD_SOURCE_CODE

Note: This sample specifies the mimimum parameters required, and depending on your choices, alternative parameters may be required.
For further details on all available parameters, see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CodeBuild.html#createProject-property. (This is for V2, but V3 has similar
parameters).

Running the code:
node createProject.js
*/
// snippet-start:[codeBuild.JavaScript.createProjectV3]
// Get service clients module and commands using ES6 syntax.
import { CreateProjectCommand } from "@aws-sdk/client-codebuild";
import { codeBuildClient } from "./libs/codeBuildClient.js";

// Set the bucket parameters.

export const params = {
    name: 'mynewname', /* Required. */
    serviceRole: "mynewservicerole",
    ProjectSource:
};

// Create the AWS CodeBuild project.
export const run = async () => {
    try {
        const data = await codeBuildClient.send(new CreateProjectCommand(params));
        console.log("Success", data);
        return data; // For unit tests.
    } catch (err) {
        console.log("Error", err);
    }
};
run();
// snippet-start:[codeBuild.JavaScript.createProjectV3]

<commit_msg>Add AWS CodeBuild examples (AWS SDK for JS v3)<commit_after><|endoftext|>


<commit_before>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM Agent for NodeJS is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
'use strict'
var SpmAgent = require('spm-agent')
var Agent = SpmAgent.Agent
var config = SpmAgent.Config
var os = require('os')
var cluster = require('cluster')
var diskfree = require('node-df')
var logger = SpmAgent.Logger
var cluster = require('cluster')
/**
 * This module generates OS Metrics. Names are compatible with collectd. SpmSender uses collectd format
 * @returns {Agent}
 */
module.exports = function () {
  if (os.platform() === 'linux') {
    try {
      var LinuxAgent = require('./linuxAgent.js')
      var lAgent = new LinuxAgent()
      return lAgent
    } catch (err) {
      SpmAgent.Logger.error('Cannot initialize linux agent:' + err)
    }
  }
  var osAgent = new Agent(
    {
      diskFree: function (agent) {
        if (os.platform() !== 'darwin') {
          return
        }
        diskfree(function dfMetrics (err, data) {
          if (err) {
            return logger.error('Error in df() for disk-usage metrics:' + err)
          }
          if (data && data.length > 0) {
            data.forEach(function (disk) {
            if (/\/dev\/.+/i.test(disk.filesystem)) {
              var dev = disk.filesystem.split('/')[2]
              var usedName = 'collectd5-disk-space-used\tdf-' + dev + '/df_complex-used'
              var usedValue = disk.used * 1024
              var freeName = 'collectd5-disk-space-free\tdf-' + dev + '/df_complex-free'
              var freeValue = disk.available * 1024
              agent.addMetrics({
                ts: Date.now(),
                name: usedName,
                value: usedValue,
                sct: 'OS'
              })
              agent.addMetrics({
                ts: Date.now(),
                name: freeName,
                value: freeValue,
                sct: 'OS'
              })
            }
          })
          }
        })
      },
      start: function (agent) {
        var self = this
        var cpuLastValues = {}
        os.cpus().forEach(function (cpu, i) {
          cpuLastValues[i] = {idle: 0, user: 0, sys: 0, irq: 0, nice: 0}
        })
        var cpuProperties = ['user', 'nice', 'irq', 'sys', 'idle']
        // on PM2 cluster.isMAster might fail, using PM2 env var instead
        if (cluster.isMaster || process.env.NODE_APP_INSTANCE===0) {
          var timerId = setInterval(function () {
            var time = new Date().getTime()
            var metrics = {}
            self.diskFree(agent)
            metrics['collectd-sys-load'] = os.loadavg()
            metrics['collectd-mem-free'] = os.freemem()
            metrics['collectd-mem-used'] = os.totalmem() - os.freemem()
            os.cpus().forEach(function (cpu, i) {
              var cpuTotal = 0
              cpuProperties.forEach(function (property) {
                cpuLastValues[i][property] = cpu.times[property] - cpuLastValues[i][property]
                cpuTotal = cpuTotal + cpuLastValues[i][property]
              })
              metrics['collectd-cpu-usr\tcpu-' + i + '/cpu-user'] = (cpuLastValues[i].user / cpuTotal) * 100
              metrics['collectd-cpu-nic\tcpu-' + i + '/cpu-nice'] = (cpuLastValues[i].nice / cpuTotal) * 100
              metrics['collectd-cpu-sys\tcpu-' + i + '/cpu-system'] = (cpuLastValues[i].sys / cpuTotal) * 100
              metrics['collectd-cpu-idl\tcpu-' + i + '/cpu-idle'] = (cpuLastValues[i].idle / cpuTotal) * 100
              metrics['collectd-cpu-int\tcpu-' + i + '/cpu-interrupt'] = (cpuLastValues[i].irq / cpuTotal) * 100
              // We can't get this values from node.js standard API
              metrics['collectd-cpu-ste\tcpu-' + i + '/cpu-steal'] = 0.0001
              metrics['collectd-cpu-sir\tcpu-' + i + '/cpu-softirq'] = 0.0001
              metrics['collectd-cpu-wait\tcpu-' + i + '/cpu-wait'] = 0.0001
            })
            // setting "sct" parameter for spm-sender to use specific collectd format when transmitting to receiver.
            for (var x in metrics) {
              agent.addMetrics({ts: time, name: x, value: metrics[x], sct: 'OS'})
            }
            agent.addMetrics({
              ts: time,
              name: 'numWorkers',
              value: Object.keys(cluster.workers).length
            })
          }, config.collectionInterval || 30000)
          if (timerId.unref) {
            timerId.unref()
          }
        }
      }
    }
  )
  return osAgent
}
<commit_msg>add env var SPM_MASTER_MODE to enable OS metrics collection<commit_after>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM Agent for NodeJS is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
'use strict'
var SpmAgent = require('spm-agent')
var Agent = SpmAgent.Agent
var config = SpmAgent.Config
var os = require('os')
var cluster = require('cluster')
var diskfree = require('node-df')
var logger = SpmAgent.Logger
var cluster = require('cluster')
/**
 * This module generates OS Metrics. Names are compatible with collectd. SpmSender uses collectd format
 * @returns {Agent}
 */
module.exports = function () {
  if (os.platform() === 'linux') {
    try {
      var LinuxAgent = require('./linuxAgent.js')
      var lAgent = new LinuxAgent()
      return lAgent
    } catch (err) {
      SpmAgent.Logger.error('Cannot initialize linux agent:' + err)
    }
  }
  var osAgent = new Agent(
    {
      diskFree: function (agent) {
        if (os.platform() !== 'darwin') {
          return
        }
        diskfree(function dfMetrics (err, data) {
          if (err) {
            return logger.error('Error in df() for disk-usage metrics:' + err)
          }
          if (data && data.length > 0) {
            data.forEach(function (disk) {
            if (/\/dev\/.+/i.test(disk.filesystem)) {
              var dev = disk.filesystem.split('/')[2]
              var usedName = 'collectd5-disk-space-used\tdf-' + dev + '/df_complex-used'
              var usedValue = disk.used * 1024
              var freeName = 'collectd5-disk-space-free\tdf-' + dev + '/df_complex-free'
              var freeValue = disk.available * 1024
              agent.addMetrics({
                ts: Date.now(),
                name: usedName,
                value: usedValue,
                sct: 'OS'
              })
              agent.addMetrics({
                ts: Date.now(),
                name: freeName,
                value: freeValue,
                sct: 'OS'
              })
            }
          })
          }
        })
      },
      start: function (agent) {
        var self = this
        var cpuLastValues = {}
        os.cpus().forEach(function (cpu, i) {
          cpuLastValues[i] = {idle: 0, user: 0, sys: 0, irq: 0, nice: 0}
        })
        var cpuProperties = ['user', 'nice', 'irq', 'sys', 'idle']
        // on PM2 cluster.isMAster might fail, using PM2 env var instead
        if (cluster.isMaster || process.env.NODE_APP_INSTANCE===0 || process.env.SPM_MASTER_MODE===1) {
          var timerId = setInterval(function () {
            var time = new Date().getTime()
            var metrics = {}
            self.diskFree(agent)
            metrics['collectd-sys-load'] = os.loadavg()
            metrics['collectd-mem-free'] = os.freemem()
            metrics['collectd-mem-used'] = os.totalmem() - os.freemem()
            os.cpus().forEach(function (cpu, i) {
              var cpuTotal = 0
              cpuProperties.forEach(function (property) {
                cpuLastValues[i][property] = cpu.times[property] - cpuLastValues[i][property]
                cpuTotal = cpuTotal + cpuLastValues[i][property]
              })
              metrics['collectd-cpu-usr\tcpu-' + i + '/cpu-user'] = (cpuLastValues[i].user / cpuTotal) * 100
              metrics['collectd-cpu-nic\tcpu-' + i + '/cpu-nice'] = (cpuLastValues[i].nice / cpuTotal) * 100
              metrics['collectd-cpu-sys\tcpu-' + i + '/cpu-system'] = (cpuLastValues[i].sys / cpuTotal) * 100
              metrics['collectd-cpu-idl\tcpu-' + i + '/cpu-idle'] = (cpuLastValues[i].idle / cpuTotal) * 100
              metrics['collectd-cpu-int\tcpu-' + i + '/cpu-interrupt'] = (cpuLastValues[i].irq / cpuTotal) * 100
              // We can't get this values from node.js standard API
              metrics['collectd-cpu-ste\tcpu-' + i + '/cpu-steal'] = 0.0001
              metrics['collectd-cpu-sir\tcpu-' + i + '/cpu-softirq'] = 0.0001
              metrics['collectd-cpu-wait\tcpu-' + i + '/cpu-wait'] = 0.0001
            })
            // setting "sct" parameter for spm-sender to use specific collectd format when transmitting to receiver.
            for (var x in metrics) {
              agent.addMetrics({ts: time, name: x, value: metrics[x], sct: 'OS'})
            }
            agent.addMetrics({
              ts: time,
              name: 'numWorkers',
              value: Object.keys(cluster.workers||{}).length || 1
            })
          }, config.collectionInterval || 30000)
          if (timerId.unref) {
            timerId.unref()
          }
        }
      }
    }
  )
  return osAgent
}
<|endoftext|>


<commit_before>//FileName: jqueryvalidation.date.js
//Author:   Kenson Man <kenson@kenson.idv.hk>
//
//Description: The file provide the date validation rules for (jqueryvalidation)[https://jqueryvalidation.org]
//
//Required:
//    - (monent.js)[http://momentjs.com]
//
//Methods:
//     dateformat:  Used to required the input must be fit with specific date-format[http://momentjs.com/docs/#/displaying/].
//            e.g: dateformat="YYYY-MM-DD"
//            e.g: dateformat="DD/MM/YYYY"
//
//     mindate:     Used to request a date that greater than or equals to the specific date[http://momentjs.com/docs/#/displaying/].
//                  The parameter should be specified by JSON format.
//            e.g: mindate="{&quote;dateformat&quote;:&quote;YYYY-MM-DD&quote;, &quote;value&quote;:&quote;2017-08-09&quote;}"
//
//     maxdate:     Used to request a date that less than or equals to the specific date[http://momentjs.com/docs/#/displaying/].
//                  The parameter should be specified by JSON format.
//            e.g: maxdate="{&quote;dateformat&quote;:&quote;YYYY-MM-DD&quote;, &quote;value&quote;:&quote;2017-08-09&quote;}"

jQuery.validator.addMethod('dateformat', function(val, element, params){
	if(typeof(params)=='undefined')
		params='YYYY-MM-DD';
	return this.optional(element) || moment(val, params, true).isValid();
}, 'Please enter the value in valid date-format');

jQuery.validator.addMethod('mindate', function(val, element, params){
   val=val.trim();
   if(this.optional(element) && val=="")return true;
	if(typeof(params)=='undefined')
		params='{}';
   try{
      params=JSON.parse(params);
      params=jQuery.extend({}, JSON.parse(params), {"dateformat":"YYYY-MM-DD", "value":monent().format("YYYY-MM-DD")});
      params.value=monent(params.value, params.dateformat, true);
      val=moment(val, params.dateformat, true);
      return val.isSame(params.value) || params.value.isBefore(val);
   }catch(err){
      return false;
   }
}, 'Please enter the value in valid date-format');

jQuery.validator.addMethod('maxdate', function(val, element, params){
   val=val.trim();
   if(this.optional(element) && val=="")return true;
	if(typeof(params)=='undefined')
		params='{}';
   try{
      params=JSON.parse(params);
      params=jQuery.extend({}, JSON.parse(params), {"dateformat":"YYYY-MM-DD", "value":monent().format("YYYY-MM-DD")});
      params.value=monent(params.value, params.dateformat, true);
      val=moment(val, params.dateformat, true);
      return val.isSame(params.value) || params.value.isAfter(val);
   }catch(err){
      return false;
   }
}, 'Please enter the value in valid date-format');
<commit_msg>Fixing the mindate and maxdate validation rules<commit_after>//FileName: jqueryvalidation.date.js
//Author:   Kenson Man <kenson@kenson.idv.hk>
//
//Description: The file provide the date validation rules for (jqueryvalidation)[https://jqueryvalidation.org]
//
//Required:
//    - (moment.js)[http://momentjs.com]
//
//Methods:
//     dateformat:  Used to required the input must be fit with specific date-format[http://momentjs.com/docs/#/displaying/].
//            e.g: dateformat="YYYY-MM-DD"
//            e.g: dateformat="DD/MM/YYYY"
//
//     mindate:     Used to request a date that greater than or equals to the specific date[http://momentjs.com/docs/#/displaying/].
//                  The parameter should be specified by JSON format.
//            e.g: mindate="{&quote;dateformat&quote;:&quote;YYYY-MM-DD&quote;, &quote;value&quote;:&quote;2017-08-09&quote;}"
//
//     maxdate:     Used to request a date that less than or equals to the specific date[http://momentjs.com/docs/#/displaying/].
//                  The parameter should be specified by JSON format.
//            e.g: maxdate="{&quote;dateformat&quote;:&quote;YYYY-MM-DD&quote;, &quote;value&quote;:&quote;2017-08-09&quote;}"

jQuery.validator.addMethod('dateformat', function(val, element, params){
	if(typeof(params)=='undefined')
		params='YYYY-MM-DD';
	return this.optional(element) || moment(val, params, true).isValid();
}, 'Please enter the value in valid date-format');

jQuery.validator.addMethod('mindate', function(val, element, params){
   val=val.trim();
   if(this.optional(element) && val=="")return true;
	if(typeof(params)=='undefined')
		params='{}';
   try{
      params=jQuery.extend({}, {"dateformat":"YYYY-MM-DD", "value":moment().format("YYYY-MM-DD")}, JSON.parse(params));
      params.value=moment(params.value, params.dateformat, true);
      val=moment(val, params.dateformat, true);
      return val.isSame(params.value) || params.value.isBefore(val);
   }catch(err){
      return false;
   }
}, jQuery.validator.format('The minimum value is {0}'));

jQuery.validator.addMethod('maxdate', function(val, element, params){
   val=val.trim();
   if(this.optional(element) && val=="")return true;
	if(typeof(params)=='undefined')
		params='{}';
   try{
      params=jQuery.extend({}, {"dateformat":"YYYY-MM-DD", "value":moment().format("YYYY-MM-DD")}, JSON.parse(params));
      params.value=moment(params.value, params.dateformat, true);
      val=moment(val, params.dateformat, true);
      return val.isSame(params.value) || params.value.isAfter(val);
   }catch(err){
      return false;
   }
}, jQuery.validator.format('The maximum valud is {0}'));
<|endoftext|>


<commit_before>'use strict';

describe('Crud Controller', function() {

	it('should do what...');

});
<commit_msg>remove stub tests<commit_after><|endoftext|>


<commit_before>(function () {
    $(function () {
        if(localStorage['cookies'] === undefined) {
            // Europe Cookie Consent Law - shows for all visitors as GeoBytes sometimes doesn't work
            $('head').append('');

            $('body').prepend('

We use cookies on this site. Our Privacy Policy outlines how we use cookies and what they are.
Close
');
        }
    });
})();
<commit_msg>Cookie law 2<commit_after>(function () {
    $(function () {
        if(localStorage['cookies'] === undefined) {
            // Europe Cookie Consent Law - shows for all visitors as GeoBytes sometimes doesn't work
            $('head').append('');

            $('body').prepend('

We use cookies on this site. Our Privacy Policy outlines how we use cookies and what they are.
Close
');
        }
    });
})();
<|endoftext|>