<commit_before>/**
 * @file MaterialDropdownFilter component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import LocalAutoComplete from '../LocalAutoComplete';
import MaterialFieldSeparator from '../_MaterialFieldSeparator';
import Theme from '../Theme';

import Util from '../_vendors/Util';

export default class MaterialDropdownFilter extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: '',
            filter: '',
            isFocus: false,
            isHover: false
        };

        this.triggerFocusHandler = ::this.triggerFocusHandler;
        this.triggerBlurHandler = ::this.triggerBlurHandler;
        this.triggerFilterChangeHandler = ::this.triggerFilterChangeHandler;
        this.triggerChangeHandler = ::this.triggerChangeHandler;
        this.triggerMouseOverHandler = ::this.triggerMouseOverHandler;
        this.triggerMouseOutHandler = ::this.triggerMouseOutHandler;
        this.closePopup = ::this.closePopup;

    }

    triggerFocusHandler(...args) {
        this.setState({
            isFocus: true
        }, () => {
            const {onFocus} = this.props;
            onFocus && onFocus(...args);
        });
    }

    triggerBlurHandler(...args) {
        this.setState({
            isFocus: false
        }, () => {
            const {onBlur} = this.props;
            onBlur && onBlur(...args);
        });
    }

    triggerFilterChangeHandler(filter) {
        this.setState({
            filter
        }, () => {
            const {onFilterChange} = this.props;
            onFilterChange && onFilterChange(filter);
        });
    }

    triggerChangeHandler(value) {
        this.setState({
            value
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value);
        });
    }

    triggerMouseOverHandler(...args) {
        this.setState({
            isHover: true
        }, () => {
            const {onMouseOver} = this.props;
            onMouseOver && onMouseOver(...args);
        });
    }

    triggerMouseOutHandler(...args) {
        this.setState({
            isHover: false
        }, () => {
            const {onMouseOut} = this.props;
            onMouseOut && onMouseOut(...args);
        });
    }

    closePopup() {
        this.refs.localAutoComplete && this.refs.localAutoComplete.closePopup();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== this.state.value) {
            this.setState({
                value: nextProps.value
            });
        }
    }

    componentDidMount() {
        this.setState({
            value: this.props.value
        });
    }

    render() {

        const {
                className, style, theme, label, isLabelAnimated, popupClassName,
                ...restProps
            } = this.props,
            {isFocus, isHover, value, filter} = this.state,

            wrapperClassName = (isLabelAnimated ? ' animated' : '') + (label ? ' has-label' : '')
                + (filter ? ' has-value' : '') + (isFocus ? ' focused' : '') + (className ? ' ' + className : '');

        return (

                {
                    label ?

                            {label}

                        :
                        null
                }

                <LocalAutoComplete {...restProps}
                                   ref="localAutoComplete"
                                   popupClassName={'material-dropdown-filter-popup ' + popupClassName}
                                   theme={theme}
                                   value={value}
                                   onFocus={this.triggerFocusHandler}
                                   onBlur={this.triggerBlurHandler}
                                   onTriggerMouseOver={this.triggerMouseOverHandler}
                                   onTriggerMouseOut={this.triggerMouseOutHandler}
                                   onFilterChange={this.triggerFilterChangeHandler}
                                   onChange={this.triggerChangeHandler}/>

                <MaterialFieldSeparator theme={theme}
                                        isHover={isHover}
                                        isFocus={isFocus}/>

        );

    }
};

MaterialDropdownFilter.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the popup element.
     */
    popupClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Override the styles of the popup element.
     */
    popupStyle: PropTypes.object,

    /**
     * The theme.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The name of the auto complete.
     */
    name: PropTypes.string,

    /**
     * The placeholder of the field.
     */
    placeholder: PropTypes.string,

    label: PropTypes.string,

    /**
     * Children passed into the List.
     */
    data: PropTypes.oneOfType([

        // not grouped
        PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

            /**
             * The CSS class name of the list button.
             */
            className: PropTypes.string,

            /**
             * Override the styles of the list button.
             */
            style: PropTypes.object,

            /**
             * The theme of the list button.
             */
            theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

            /**
             * The text value of the list button.Type can be string or number.
             */
            value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The desc value of the list button. Type can be string or number.
             */
            desc: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * If true, the list button will be disabled.
             */
            disabled: PropTypes.bool,

            /**
             * If true,the button will be have loading effect.
             */
            isLoading: PropTypes.bool,

            /**
             * If true,the element's ripple effect will be disabled.
             */
            disableTouchRipple: PropTypes.bool,

            /**
             * Use this property to display an icon. It will display on the left.
             */
            iconCls: PropTypes.string,

            /**
             * Use this property to display an icon. It will display on the right.
             */
            rightIconCls: PropTypes.string,

            /**
             * You can create a complicated renderer callback instead of value and desc prop.
             */
            itemRenderer: PropTypes.func,

            /**
             * Callback function fired when a list item touch-tapped.
             */
            onTouchTap: PropTypes.func

        }), PropTypes.string, PropTypes.number])),

        // grouped
        PropTypes.array

    ]).isRequired,

    /**
     * If true, the auto complete will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * The value field name in data. (default: "value")
     */
    valueField: PropTypes.string,

    /**
     * The display field name in data. (default: "text")
     */
    displayField: PropTypes.string,

    /**
     * The description field name in data. (default: "desc")
     */
    descriptionField: PropTypes.string,

    /**
     * If true, the popup list automatically closed after selection.
     */
    autoClose: PropTypes.bool,

    /**
     * Callback function fired when filter changed.
     */
    filterCallback: PropTypes.func,

    /**
     * Use this property to display an icon.
     */
    iconCls: PropTypes.string,

    /**
     * Use this property to display an icon.
     */
    rightIconCls: PropTypes.string,

    /**
     * The visiblity of no matched popup.
     */
    noMatchedPopupVisible: PropTypes.bool,

    /**
     * The message of no matched value.
     */
    noMatchedMsg: PropTypes.string,

    /**
     * If true,the list data will be grouped.
     */
    isGrouped: PropTypes.bool,

    isLabelAnimated: PropTypes.bool,

    popupChildren: PropTypes.any,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    renderer: PropTypes.func,

    /**
     * The function that trigger when filter changes.
     */
    onFilterChange: PropTypes.func,

    /**
     * The function that trigger when press enter.
     */
    onFilterPressEnter: PropTypes.func,

    /**
     * The function that trigger when filter cleared.
     */
    onFilterClear: PropTypes.func,

    /**
     * The function that trigger when value changed.
     */
    onChange: PropTypes.func,

    /**
     * The function that trigger when touch-tap the list items.
     */
    onItemTouchTap: PropTypes.func,

    /**
     * Callback function fired when LocalAutoComplete get focus.
     */
    onFocus: PropTypes.func,

    /**
     * Callback function fired when LocalAutoComplete lose focus.
     */
    onBlur: PropTypes.func,

    onTriggerMouseOver: PropTypes.func,
    onTriggerMouseOut: PropTypes.func

};

MaterialDropdownFilter.defaultProps = {

    className: '',
    popupClassName: '',
    style: null,
    popupStyle: null,
    theme: Theme.DEFAULT,

    name: '',
    placeholder: '',
    label: '',
    isLabelAnimated: true,
    data: [],
    disabled: false,
    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',
    autoClose: false,
    iconCls: '',
    rightIconCls: 'fa fa-search',
    noMatchedPopupVisible: true,
    noMatchedMsg: '',
    isGrouped: false,

    popupChildren: null

};<commit_msg>add MaterialDropdownFilter<commit_after>/**
 * @file MaterialDropdownFilter component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import DropdownFilter from '../DropdownFilter';
import MaterialFieldSeparator from '../_MaterialFieldSeparator';
import Theme from '../Theme';

import Util from '../_vendors/Util';

export default class MaterialDropdownFilter extends Component {

    static Mode = DropdownFilter.Mode;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: '',
            filter: '',
            isFocus: false,
            isHover: false
        };

        this.triggerFocusHandler = ::this.triggerFocusHandler;
        this.triggerBlurHandler = ::this.triggerBlurHandler;
        this.triggerFilterChangeHandler = ::this.triggerFilterChangeHandler;
        this.triggerChangeHandler = ::this.triggerChangeHandler;
        this.triggerMouseOverHandler = ::this.triggerMouseOverHandler;
        this.triggerMouseOutHandler = ::this.triggerMouseOutHandler;
        this.closePopup = ::this.closePopup;

    }

    triggerFocusHandler(...args) {
        this.setState({
            isFocus: true
        }, () => {
            const {onFocus} = this.props;
            onFocus && onFocus(...args);
        });
    }

    triggerBlurHandler(...args) {
        this.setState({
            isFocus: false
        }, () => {
            const {onBlur} = this.props;
            onBlur && onBlur(...args);
        });
    }

    triggerFilterChangeHandler(filter) {
        this.setState({
            filter
        }, () => {
            const {onFilterChange} = this.props;
            onFilterChange && onFilterChange(filter);
        });
    }

    triggerChangeHandler(value) {
        this.setState({
            value
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value);
        });
    }

    triggerMouseOverHandler(...args) {
        this.setState({
            isHover: true
        }, () => {
            const {onMouseOver} = this.props;
            onMouseOver && onMouseOver(...args);
        });
    }

    triggerMouseOutHandler(...args) {
        this.setState({
            isHover: false
        }, () => {
            const {onMouseOut} = this.props;
            onMouseOut && onMouseOut(...args);
        });
    }

    closePopup() {
        this.refs.localAutoComplete && this.refs.localAutoComplete.closePopup();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== this.state.value) {
            this.setState({
                value: nextProps.value
            });
        }
    }

    componentDidMount() {
        this.setState({
            value: this.props.value
        });
    }

    render() {

        const {
                className, style, theme, label, isLabelAnimated, popupClassName,
                ...restProps
            } = this.props,
            {isFocus, isHover, value, filter} = this.state,

            wrapperClassName = (isLabelAnimated ? ' animated' : '') + (label ? ' has-label' : '')
                + (filter ? ' has-value' : '') + (isFocus ? ' focused' : '') + (className ? ' ' + className : '');

        return (

                {
                    label ?

                            {label}

                        :
                        null
                }

                <DropdownFilter {...restProps}
                                ref="localAutoComplete"
                                popupClassName={'material-local-auto-complete-popup ' + popupClassName}
                                theme={theme}
                                value={value}
                                onFocus={this.triggerFocusHandler}
                                onBlur={this.triggerBlurHandler}
                                onTriggerMouseOver={this.triggerMouseOverHandler}
                                onTriggerMouseOut={this.triggerMouseOutHandler}
                                onFilterChange={this.triggerFilterChangeHandler}
                                onChange={this.triggerChangeHandler}/>

                <MaterialFieldSeparator theme={theme}
                                        isHover={isHover}
                                        isFocus={isFocus}/>

        );

    }
};

MaterialDropdownFilter.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the popup element.
     */
    popupClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Override the styles of the popup element.
     */
    popupStyle: PropTypes.object,

    /**
     * The theme.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The name of the auto complete.
     */
    name: PropTypes.string,

    /**
     * The placeholder of the field.
     */
    placeholder: PropTypes.string,

    label: PropTypes.string,

    /**
     * Children passed into the List.
     */
    data: PropTypes.oneOfType([

        // not grouped
        PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

            /**
             * The CSS class name of the list button.
             */
            className: PropTypes.string,

            /**
             * Override the styles of the list button.
             */
            style: PropTypes.object,

            /**
             * The theme of the list button.
             */
            theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

            /**
             * The text value of the list button.Type can be string or number.
             */
            value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The desc value of the list button. Type can be string or number.
             */
            desc: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * If true, the list button will be disabled.
             */
            disabled: PropTypes.bool,

            /**
             * If true,the button will be have loading effect.
             */
            isLoading: PropTypes.bool,

            /**
             * If true,the element's ripple effect will be disabled.
             */
            disableTouchRipple: PropTypes.bool,

            /**
             * Use this property to display an icon. It will display on the left.
             */
            iconCls: PropTypes.string,

            /**
             * Use this property to display an icon. It will display on the right.
             */
            rightIconCls: PropTypes.string,

            /**
             * You can create a complicated renderer callback instead of value and desc prop.
             */
            itemRenderer: PropTypes.func,

            /**
             * Callback function fired when a list item touch-tapped.
             */
            onTouchTap: PropTypes.func

        }), PropTypes.string, PropTypes.number])),

        // grouped
        PropTypes.array

    ]).isRequired,

    /**
     * If true, the auto complete will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * The value field name in data. (default: "value")
     */
    valueField: PropTypes.string,

    /**
     * The display field name in data. (default: "text")
     */
    displayField: PropTypes.string,

    /**
     * The description field name in data. (default: "desc")
     */
    descriptionField: PropTypes.string,

    /**
     * If true, the popup list automatically closed after selection.
     */
    autoClose: PropTypes.bool,

    /**
     * The type of dropDown list,can be normal,checkbox,radio.
     */
    mode: PropTypes.oneOf(Util.enumerateValue(DropdownFilter.Mode)),

    /**
     * Callback function fired when filter changed.
     */
    filterCallback: PropTypes.func,

    /**
     * Use this property to display an icon.
     */
    iconCls: PropTypes.string,

    /**
     * Use this property to display an icon.
     */
    rightIconCls: PropTypes.string,

    /**
     * The visiblity of no matched popup.
     */
    noMatchedPopupVisible: PropTypes.bool,

    /**
     * The message of no matched value.
     */
    noMatchedMsg: PropTypes.string,

    /**
     * If true,the list data will be grouped.
     */
    isGrouped: PropTypes.bool,

    isLabelAnimated: PropTypes.bool,

    popupChildren: PropTypes.any,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    renderer: PropTypes.func,

    /**
     * The function that trigger when filter changes.
     */
    onFilterChange: PropTypes.func,

    /**
     * The function that trigger when press enter.
     */
    onFilterPressEnter: PropTypes.func,

    /**
     * The function that trigger when filter cleared.
     */
    onFilterClear: PropTypes.func,

    /**
     * The function that trigger when value changed.
     */
    onChange: PropTypes.func,

    /**
     * The function that trigger when touch-tap the list items.
     */
    onItemTouchTap: PropTypes.func,

    /**
     * Callback function fired when DropdownFilter get focus.
     */
    onFocus: PropTypes.func,

    /**
     * Callback function fired when DropdownFilter lose focus.
     */
    onBlur: PropTypes.func,

    onTriggerMouseOver: PropTypes.func,
    onTriggerMouseOut: PropTypes.func

};

MaterialDropdownFilter.defaultProps = {

    className: '',
    popupClassName: '',
    style: null,
    popupStyle: null,
    theme: Theme.DEFAULT,

    name: '',
    placeholder: '',
    label: '',
    isLabelAnimated: true,
    data: [],
    disabled: false,
    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',
    autoClose: false,
    iconCls: '',
    rightIconCls: 'fa fa-search',
    noMatchedPopupVisible: true,
    noMatchedMsg: '',
    isGrouped: false,

    popupChildren: null

};<|endoftext|>


<commit_before>ns("plugins");

(function() {

    var REFRESH_INTERVAL = 30 * 1000;

    analyzr.plugins.Repositories = analyzr.core.Observeable.extend({

        init: function(target) {
            this._super();

            this.dom = $(target);
        },

        prepareTable: function() {
            return $(
                "
" +
                    "
" +
                        "
" +
                            "" +
                                "A" +
                            "	" +
                            "" +
                                "M" +
                            "	" +
                            "" +
                                "S" +
                            "	" +
                            "Type	" +
                            "Location	" +
                            "	" +
                            "	" +
                        "
" +
                    "
" +
                    "
" +
                    "
" +
                "
"
            );
        },

        wrap: function(child, attrs) {
            var td = $("");

            if(attrs) {
                $.each(attrs, function(key, value) {
                    td.attr(key, value);
                });
            }

            td.append(child);

            return td;
        },

        icon: function(cls) {
            cls = cls || "icon-code icon-blank";

            return $("");
        },

        getAnalyzingState: function(repo) {
            var icon = this.getStatusIcon({
                running: repo.analyzing,
                finished: repo.analyzed
            });

            return this.wrap(icon, {
                "class": "status"
            });
        },

        getMeasuringState: function(repo) {
            var icon = this.getStatusIcon({
                running: repo.measuring,
                finished: repo.measured
            });

            return this.wrap(icon, {
                "class": "status"
            });
        },

        getStatusIcon: function(status) {
            if(status.running) {
                return this.icon("icon-refresh icon-spin");
            }

            if(status.finished) {
                return this.icon("icon-ok");
            }

            return this.icon("icon-question");
        },

        getRepoLink: function(repo) {
            if(repo.rep.busy || !repo.rep.analyzed) {
                return this.wrap(repo.rep.name);
            }

            return this.wrap($(
                "" + repo.rep.name + ""
            ));
        },

        getRepoStatus: function(repo) {
            if(repo.anonymous) {
                return this.icon("icon-unlock-alt");
            }

            return this.icon("icon-lock");
        },

        createDropdown: function(name, repo, clb) {
            var container = $(
                "
" +
                    "<button type='button' class='btn btn-default btn-sm dropdown-toggle' data-toggle='dropdown'>" +
                        name + " " +
                    "</button>" +
                    "
" +
                        "
" +
                            "Loading..." +
                        "
" +
                    "
" +
                "
"
            );

            var dropdown = container.find("ul");

            container.one("click", function() {
                $.ajax(repo.href + "/branches", {
                    success: function(branches) {
                        container.find(".loading").remove();

                        $.each(branches, function() {
                            var item = $("
");
                            var content = clb(this);

                            if(!content) {
                                return;
                            }

                            item.append(content);
                            dropdown.append(item);
                        });
                    }
                });
            });

            return container;
        },

        request: function(url, clb) {
            if(!url) {
                return;
            }

            $.ajax(url, {
                type: "POST",
                data: {
                    csrfmiddlewaretoken: $.cookie("csrftoken")
                },
                success: clb
            });
        },

        reload: function() {
            window.setTimeout(function() {
                window.location.reload();
            }, 100);
        },

        showResumeDialog: function(link, error) {
            var that = this;

            var text = "This action has been interrupted before. " +
                    "Would you like to resume where you left off, or start over?";

            if(error) {
                text += error;
            }

            var dialog = new analyzr.plugins.Dialog({
                width: 500,
                text: text,
                actions: [
                    {
                        text: "Cancel",
                        handler: function(dialog) {
                            dialog.remove();
                        }
                    },
                    {
                        text: "Restart",
                        handler: function() {
                            that.request(link.data("rel"));
                            that.reload();
                        }
                    },
                    {
                        text: "Resume",
                        cls: "btn-primary",
                        handler: function() {
                            that.request(link.data("rel") + "/resume");
                            that.reload();
                        }
                    }
                ]
            });

            dialog.show();
        },

        createLink: function(branch, action, clb) {
            var that = this;

            var link = $(
                "" +
                    branch.rep.name +
                ""
            );

            link.click(function() {
                var url = $(this).data("rel");

                var performAction = function() {
                    if(clb && !clb(link, branch)) {
                        return false;
                    }

                    that.request(url);
                    that.reload();
                };

                if(branch.rep[action].finished) {
                    analyzr.plugins.Dialog.confirm("This action has already finished on the selected branch. Do you want to restart it?", performAction);
                } else {
                    performAction();
                }

                return false;
            });

            return link;
        },

        createAction: function(title, action, repo, filter) {
            var that = this;

            filter = filter || function() { return true; };

            return this.createDropdown(title, repo, function(branch) {
                if(!filter(branch)) {
                    return false;
                }

                var link = that.createLink(branch, action, function(link, branch) {
                    if(!branch.rep[action].interrupted && !branch.rep[action].lastError) {
                        return true;
                    }

                    that.showResumeDialog(link, branch.rep[action].lastError);

                    return false;
                });

                if(branch.rep[action].finished) {
                    link.prepend(that.icon("icon-ok"));
                }

                if(branch.rep[action].interrupted || branch.rep[action].lastError) {
                    link.prepend(that.icon("icon-warning-sign"));
                }

                if(link.find(".icon-li").length === 0) {
                    link.prepend(that.icon());
                }

                return link;
            });
        },

        createActions: function(repo) {
            var rep = repo.rep;

            if(rep.busy) {
                var status = rep.status;

                if(status.action === "analyzing") {
                    return this.wrap("Analyzing branch " + status.rep.rep.name + "...");
                }

                return this.wrap("Measuring branch " + status.rep.rep.name + "...");
            }

            var wrap = this.wrap(this.createAction("Analyze", "analyze", repo));

            if(!rep.measurable) {
                return wrap;
            }

            wrap.append(this.createAction("Measure", "measure", repo, function(branch) {
                return branch.rep.analyze.finished;
            }));

            return wrap;
        },

        createRepo: function(info) {
            var that = this;
            var repo = $("
");

            var rep = info.rep;

            repo.append(this.getAnalyzingState(rep));
            repo.append(this.getMeasuringState(rep));
            repo.append(this.wrap(this.getRepoStatus(rep), {
                "class": "status"
            }));
            repo.append(this.wrap(rep.kind));
            repo.append(this.getRepoLink(info));

            repo.append(this.createActions(info));

            var edit = "", remove = "", purge = "";

            if(!rep.busy) {
                edit = $("");
                edit.append(this.icon("icon-edit"));

                remove = $("");
                remove.append(this.icon("icon-remove"));

                remove.click(function() {
                    analyzr.plugins.Dialog.confirm("Do you really want to delete the repo?", function() {
                        that.request(remove.data("action"), function() {
                            $("tr[data-href='" + info.href + "']").fadeOut(function() {
                                $(this).remove();
                            });
                        });
                    });

                    return false;
                });

                purge = $("");
                purge.append(this.icon("icon-folder-close-alt"));

                if(!rep.checkedOut) {
                    purge.prop("readonly", true);
                    purge.addClass("disabled");
                }

                purge.click(function() {
                    analyzr.plugins.Dialog.confirm("Do you really want to delete all files belonging to this repository?", function() {
                        var mask = new analyzr.core.Mask(that.dom, "Removing files...");
                        mask.show();

                        that.request(purge.data("action"), function() {
                            mask.remove();
                        });
                    });

                    return false;
                });
            }

            repo.append(this.wrap([edit, purge, remove], { "class": "actions" }));

            return repo;
        },

        createStatusIndicator: function(repo, branch, action) {
            if(branch.rep.activity.action !== action) {
                return;
            }

            var container = $(
                "
" +
                    "" +
                        "

" +
                    "	" +
                "
"
            );

            var that = this;

            var updateProgress = function() {
                $.ajax(branch.href, {
                    success: function(branch) {
                        if(typeof branch.rep.activity.progress === "undefined") {
                            container.fadeOut(function() {
                                that.load();
                            });

                            return;
                        }

                        var progress = (100 *  branch.rep.activity.progress / branch.rep.activity.count);

                        container.find(".progress-bar").css({
                            width: progress + "%"
                        });

                        if(progress !== 0 && !progress) {
                            window.setTimeout(updateProgress, REFRESH_INTERVAL);

                            return;
                        }

                        if(progress < 100) {
                            container.find(".progress-bar").html(Math.round(progress) + "%");

                            window.setTimeout(updateProgress, REFRESH_INTERVAL);
                        } else {
                            container.fadeOut(function() {
                                that.load();
                            });
                        }
                    }
                });
            };

            updateProgress();

            return container;
        },

        load: function() {
            var that = this;

            this.dom.html("");

            var table = this.prepareTable();

            this.dom.append(table);

            var body = table.find("tbody");

            $.ajax("/repositories", {
                success: function(repositories) {
                    $.each(repositories, function() {
                        var repo = that.createRepo(this);
                        body.append(repo);

                        if(this.rep.status.action !== "ready") {
                            var progess = that.createStatusIndicator(repo, this.rep.status.rep, this.rep.status.action);
                            body.append(progess);
                        }
                    });
                }
            });
        }

    });

}());
<commit_msg>loading mask for repos<commit_after>ns("plugins");

(function() {

    var REFRESH_INTERVAL = 30 * 1000;

    analyzr.plugins.Repositories = analyzr.core.Observeable.extend({

        init: function(target) {
            this._super();

            this.dom = $(target);
        },

        prepareTable: function() {
            return $(
                "
" +
                    "
" +
                        "
" +
                            "" +
                                "A" +
                            "	" +
                            "" +
                                "M" +
                            "	" +
                            "" +
                                "S" +
                            "	" +
                            "Type	" +
                            "Location	" +
                            "	" +
                            "	" +
                        "
" +
                    "
" +
                    "
" +
                    "
" +
                "
"
            );
        },

        wrap: function(child, attrs) {
            var td = $("");

            if(attrs) {
                $.each(attrs, function(key, value) {
                    td.attr(key, value);
                });
            }

            td.append(child);

            return td;
        },

        icon: function(cls) {
            cls = cls || "icon-code icon-blank";

            return $("");
        },

        getAnalyzingState: function(repo) {
            var icon = this.getStatusIcon({
                running: repo.analyzing,
                finished: repo.analyzed
            });

            return this.wrap(icon, {
                "class": "status"
            });
        },

        getMeasuringState: function(repo) {
            var icon = this.getStatusIcon({
                running: repo.measuring,
                finished: repo.measured
            });

            return this.wrap(icon, {
                "class": "status"
            });
        },

        getStatusIcon: function(status) {
            if(status.running) {
                return this.icon("icon-refresh icon-spin");
            }

            if(status.finished) {
                return this.icon("icon-ok");
            }

            return this.icon("icon-question");
        },

        getRepoLink: function(repo) {
            if(repo.rep.busy || !repo.rep.analyzed) {
                return this.wrap(repo.rep.name);
            }

            return this.wrap($(
                "" + repo.rep.name + ""
            ));
        },

        getRepoStatus: function(repo) {
            if(repo.anonymous) {
                return this.icon("icon-unlock-alt");
            }

            return this.icon("icon-lock");
        },

        createDropdown: function(name, repo, clb) {
            var container = $(
                "
" +
                    "<button type='button' class='btn btn-default btn-sm dropdown-toggle' data-toggle='dropdown'>" +
                        name + " " +
                    "</button>" +
                    "
" +
                        "
" +
                            "Loading..." +
                        "
" +
                    "
" +
                "
"
            );

            var dropdown = container.find("ul");

            container.one("click", function() {
                $.ajax(repo.href + "/branches", {
                    success: function(branches) {
                        container.find(".loading").remove();

                        $.each(branches, function() {
                            var item = $("
");
                            var content = clb(this);

                            if(!content) {
                                return;
                            }

                            item.append(content);
                            dropdown.append(item);
                        });
                    }
                });
            });

            return container;
        },

        request: function(url, clb) {
            if(!url) {
                return;
            }

            $.ajax(url, {
                type: "POST",
                data: {
                    csrfmiddlewaretoken: $.cookie("csrftoken")
                },
                success: clb
            });
        },

        reload: function() {
            window.setTimeout(function() {
                window.location.reload();
            }, 100);
        },

        showResumeDialog: function(link, error) {
            var that = this;

            var text = "This action has been interrupted before. " +
                    "Would you like to resume where you left off, or start over?";

            if(error) {
                text += error;
            }

            var dialog = new analyzr.plugins.Dialog({
                width: 500,
                text: text,
                actions: [
                    {
                        text: "Cancel",
                        handler: function(dialog) {
                            dialog.remove();
                        }
                    },
                    {
                        text: "Restart",
                        handler: function() {
                            that.request(link.data("rel"));
                            that.reload();
                        }
                    },
                    {
                        text: "Resume",
                        cls: "btn-primary",
                        handler: function() {
                            that.request(link.data("rel") + "/resume");
                            that.reload();
                        }
                    }
                ]
            });

            dialog.show();
        },

        createLink: function(branch, action, clb) {
            var that = this;

            var link = $(
                "" +
                    branch.rep.name +
                ""
            );

            link.click(function() {
                var url = $(this).data("rel");

                var performAction = function() {
                    if(clb && !clb(link, branch)) {
                        return false;
                    }

                    that.request(url);
                    that.reload();
                };

                if(branch.rep[action].finished) {
                    analyzr.plugins.Dialog.confirm("This action has already finished on the selected branch. Do you want to restart it?", performAction);
                } else {
                    performAction();
                }

                return false;
            });

            return link;
        },

        createAction: function(title, action, repo, filter) {
            var that = this;

            filter = filter || function() { return true; };

            return this.createDropdown(title, repo, function(branch) {
                if(!filter(branch)) {
                    return false;
                }

                var link = that.createLink(branch, action, function(link, branch) {
                    if(!branch.rep[action].interrupted && !branch.rep[action].lastError) {
                        return true;
                    }

                    that.showResumeDialog(link, branch.rep[action].lastError);

                    return false;
                });

                if(branch.rep[action].finished) {
                    link.prepend(that.icon("icon-ok"));
                }

                if(branch.rep[action].interrupted || branch.rep[action].lastError) {
                    link.prepend(that.icon("icon-warning-sign"));
                }

                if(link.find(".icon-li").length === 0) {
                    link.prepend(that.icon());
                }

                return link;
            });
        },

        createActions: function(repo) {
            var rep = repo.rep;

            if(rep.busy) {
                var status = rep.status;

                if(status.action === "analyzing") {
                    return this.wrap("Analyzing branch " + status.rep.rep.name + "...");
                }

                return this.wrap("Measuring branch " + status.rep.rep.name + "...");
            }

            var wrap = this.wrap(this.createAction("Analyze", "analyze", repo));

            if(!rep.measurable) {
                return wrap;
            }

            wrap.append(this.createAction("Measure", "measure", repo, function(branch) {
                return branch.rep.analyze.finished;
            }));

            return wrap;
        },

        createRepo: function(info) {
            var that = this;
            var repo = $("
");

            var rep = info.rep;

            repo.append(this.getAnalyzingState(rep));
            repo.append(this.getMeasuringState(rep));
            repo.append(this.wrap(this.getRepoStatus(rep), {
                "class": "status"
            }));
            repo.append(this.wrap(rep.kind));
            repo.append(this.getRepoLink(info));

            repo.append(this.createActions(info));

            var edit = "", remove = "", purge = "";

            if(!rep.busy) {
                edit = $("");
                edit.append(this.icon("icon-edit"));

                remove = $("");
                remove.append(this.icon("icon-remove"));

                remove.click(function() {
                    analyzr.plugins.Dialog.confirm("Do you really want to delete the repo?", function() {
                        that.request(remove.data("action"), function() {
                            $("tr[data-href='" + info.href + "']").fadeOut(function() {
                                $(this).remove();
                            });
                        });
                    });

                    return false;
                });

                purge = $("");
                purge.append(this.icon("icon-folder-close-alt"));

                if(!rep.checkedOut) {
                    purge.prop("readonly", true);
                    purge.addClass("disabled");
                }

                purge.click(function() {
                    analyzr.plugins.Dialog.confirm("Do you really want to delete all files belonging to this repository?", function() {
                        var mask = new analyzr.core.Mask(that.dom, "Removing files...");
                        mask.show();

                        that.request(purge.data("action"), function() {
                            mask.remove();
                        });
                    });

                    return false;
                });
            }

            repo.append(this.wrap([edit, purge, remove], { "class": "actions" }));

            return repo;
        },

        createStatusIndicator: function(repo, branch, action) {
            if(branch.rep.activity.action !== action) {
                return;
            }

            var container = $(
                "
" +
                    "" +
                        "

" +
                    "	" +
                "
"
            );

            var that = this;

            var updateProgress = function() {
                $.ajax(branch.href, {
                    success: function(branch) {
                        if(typeof branch.rep.activity.progress === "undefined") {
                            container.fadeOut(function() {
                                that.load();
                            });

                            return;
                        }

                        var progress = (100 *  branch.rep.activity.progress / branch.rep.activity.count);

                        container.find(".progress-bar").css({
                            width: progress + "%"
                        });

                        if(progress !== 0 && !progress) {
                            window.setTimeout(updateProgress, REFRESH_INTERVAL);

                            return;
                        }

                        if(progress < 100) {
                            container.find(".progress-bar").html(Math.round(progress) + "%");

                            window.setTimeout(updateProgress, REFRESH_INTERVAL);
                        } else {
                            container.fadeOut(function() {
                                that.load();
                            });
                        }
                    }
                });
            };

            updateProgress();

            return container;
        },

        load: function() {
            var that = this;

            this.dom.html("");

            var mask = new analyzr.core.Mask(this.dom, "Loading repositories...");
            mask.show();

            var table = this.prepareTable();

            this.dom.append(table);

            var body = table.find("tbody");

            $.ajax("/repositories", {
                success: function(repositories) {
                    $.each(repositories, function() {
                        var repo = that.createRepo(this);
                        body.append(repo);

                        if(this.rep.status.action !== "ready") {
                            var progess = that.createStatusIndicator(repo, this.rep.status.rep, this.rep.status.action);
                            body.append(progess);
                        }
                    });

                    mask.remove();
                }
            });
        }

    });

}());
<|endoftext|>


<commit_before>(function (global) {

    'use strict';

    function setHeaders (xhr, headers) {
        var resultHeaders = {},
            defaultHeadersKeys = Object.keys(XHR.defaults.headers),
            userHeadersKeys,
            resultHeadersKeys,
            header,
            value,
            i, l;
        for (i = 0, l = defaultHeadersKeys.length; i < l; i++) {
            header = defaultHeadersKeys[i].toLowerCase();
            resultHeaders[header] = XHR.defaultHeaders[header];
        }
        if (typeof headers === 'object') {
            userHeadersKeys = Object.keys(headers);
            for (i = 0, l = userHeadersKeys.length; i < l; i++) {
                header = userHeadersKeys[i].toLowerCase();
                resultHeaders[header] = headers[header];
            }
        }
        resultHeadersKeys = Object.keys(resultHeaders);
        for (i = 0, l = resultHeadersKeys.length; i < l; i++) {
            header = resultHeadersKeys[i];
            value = resultHeaders[header];
            if (!isNaN(value) && typeof value !== 'undefined' && value !== null) {
                xhr.setRequestHeader(header, String(value));
            }
        }
    }

    function XHR (config) {
        if (!config) {
            throw new Error('Config object is required.');
        } else {
            var xhr = new XMLHttpRequest(),
                result = new XHR.XHRPromise(xhr),
                queryParams = '',
                async = true,
                dataForSend = null;

            // setting HTTP method
            config.method = typeof config.method === 'string' ? config.method : XHR.defaults.method;

            // applying attributes to instance of XMLHttpRequest
            if (typeof config.attributes === 'object' && config.attributes) {
                var attributes = Object.keys(config.attributes);
                attributes.forEach(function (attribute) {
                    xhr[attribute] = config.attributes[attribute];
                });
            }

            // setting query params
            if (typeof config.params === 'object' && config.params) {
                var params = [],
                    paramsKeys = Object.keys(config.params);
                paramsKeys.forEach(function (param) {
                    var value = config.params[param];
                    if (Array.isArray(value)) {
                        value.forEach(function (val) {
                            params.push(param + '=' + val);
                        });
                    } else if (typeof value === 'object' && value) {
                        params.push(param + '=' + JSON.stringify(value));
                    } else if (typeof value !== 'undefined') {
                        params.push(param + '=' + value);
                    }
                });
                if (params.length) {
                    queryParams = '?' + params.join('&');
                }
            }

            // setting async
            if (config.async !== undefined) {
                async = !!config.async;
            }

            xhr.open(config.method, config.url + queryParams, async);

            // setting default and user settings
            setHeaders(xhr, config.headers);

            // setting data
            if (config.data !== undefined) {
                var d = config.data;
                if (d instanceof (global.ArrayBufferView || global.ArrayBuffer) || d instanceof global.Blob ||
                    d instanceof global.Document || d instanceof global.FormData) {
                    dataForSend = d;
                } else {
                    if (typeof d === 'object' && d) {
                        dataForSend = JSON.stringify(d);
                    } else {
                        dataForSend = String(d);
                    }
                }
            }

            // adding event listeners
            xhr.addEventListener('error', function (e) {
                result.applyCallback('error', e);
            });
            xhr.addEventListener('progress', function (e) {
                result.applyCallback('progress', e);
            });
            xhr.addEventListener('loadstart', function (e) {
                result.applyCallback('loadstart', e);
            });
            xhr.addEventListener('loadend', function (e) {
                result.applyCallback('loadend', e);
            });
            xhr.addEventListener('abort', function (e) {
                result.applyCallback('abort', e);
            });
            xhr.addEventListener('load', function (e) {
                result.applyCallback('load', e);
                var response = xhr.response;
                if (xhr.responseType !== 'json') {
                    try {
                        response = JSON.parse(xhr.responseText);
                    } catch (e) {
                        response = xhr.responseText;
                    }
                }
                if (xhr.status >= 200 && xhr.status < 400) {
                    result.applyCallback('success', response);
                } else if (xhr.status >= 400 && xhr.status < 600) {
                    result.applyCallback('error', e);
                }
            }, false);

            // sending
            setTimeout(function () {
                xhr.send(dataForSend);
            }, 0);
            return result.actions;
        }
    }

    Object.defineProperty(XHR, 'defaults', {
        value: {
            method: 'GET',
            headers: {},
            attributes: {
                responseType: '',
                timeout: 0
            }
        },
        configurable: false,
        writable: false
    });

    global.XHR = XHR;

    if (typeof define === 'function' && define.amd !== null) {
        define([], function () {
            return XHR;
        });
    }

}(window));

(function (XHR) {

    'use strict';

    function XHRPromise (xhr) {
        var _this = this;
        this.callbacks = {
            error: null,
            loadStart: null,
            progress: null,
            loadEnd: null,
            abort: null,
            load: null,
            success: null
        };
        this.actions = {
            error: function error (callback) {
                _this.callbacks.error = callback;
                return _this.actions;
            },
            loadStart: function loadStart (callback) {
                _this.callbacks.loadStart = callback;
                return _this.actions;
            },
            progress: function progress (callback) {
                _this.callbacks.progress = callback;
                return _this.actions;
            },
            loadEnd: function loadEnd (callback) {
                _this.callbacks.loadEnd = callback;
                return _this.actions;
            },
            abort: function abort (callback) {
                _this.callbacks.abort = callback;
                return _this.actions;
            },
            load: function load (callback) {
                _this.callbacks.load = callback;
                return _this.actions;
            },
            success: function success (callback) {
                _this.callbacks.success = callback;
                return _this.actions;
            },
            getXHR: function getXHR () {
                return xhr;
            }
        };

    }

    XHRPromise.prototype.applyCallback = function applyCallback (callbackName, data) {
        var callback = this.callbacks[callbackName];
        if (typeof callback === 'function') {
            callback(data);
        }
    };

    XHR.XHRPromise = XHRPromise;

}(window.XHR));
<commit_msg>converted to UTF-8<commit_after>(function (global) {

    'use strict';

    function setHeaders (xhr, headers) {
        var resultHeaders = {},
            defaultHeadersKeys = Object.keys(XHR.defaults.headers),
            userHeadersKeys,
            resultHeadersKeys,
            header,
            value,
            i, l;
        for (i = 0, l = defaultHeadersKeys.length; i < l; i++) {
            header = defaultHeadersKeys[i].toLowerCase();
            resultHeaders[header] = XHR.defaultHeaders[header];
        }
        if (typeof headers === 'object') {
            userHeadersKeys = Object.keys(headers);
            for (i = 0, l = userHeadersKeys.length; i < l; i++) {
                header = userHeadersKeys[i].toLowerCase();
                resultHeaders[header] = headers[header];
            }
        }
        resultHeadersKeys = Object.keys(resultHeaders);
        for (i = 0, l = resultHeadersKeys.length; i < l; i++) {
            header = resultHeadersKeys[i];
            value = resultHeaders[header];
            if (!isNaN(value) && typeof value !== 'undefined' && value !== null) {
                xhr.setRequestHeader(header, String(value));
            }
        }
    }

    function XHR (config) {
        if (!config) {
            throw new Error('Config object is required.');
        } else {
            var xhr = new XMLHttpRequest(),
                result = new XHR.XHRPromise(xhr),
                queryParams = '',
                async = true,
                dataForSend = null;

            // setting HTTP method
            config.method = typeof config.method === 'string' ? config.method : XHR.defaults.method;

            // applying attributes to instance of XMLHttpRequest
            if (typeof config.attributes === 'object' && config.attributes) {
                var attributes = Object.keys(config.attributes);
                attributes.forEach(function (attribute) {
                    xhr[attribute] = config.attributes[attribute];
                });
            }

            // setting query params
            if (typeof config.params === 'object' && config.params) {
                var params = [],
                    paramsKeys = Object.keys(config.params);
                paramsKeys.forEach(function (param) {
                    var value = config.params[param];
                    if (Array.isArray(value)) {
                        value.forEach(function (val) {
                            params.push(param + '=' + val);
                        });
                    } else if (typeof value === 'object' && value) {
                        params.push(param + '=' + JSON.stringify(value));
                    } else if (typeof value !== 'undefined') {
                        params.push(param + '=' + value);
                    }
                });
                if (params.length) {
                    queryParams = '?' + params.join('&');
                }
            }

            // setting async
            if (config.async !== undefined) {
                async = !!config.async;
            }

            xhr.open(config.method, config.url + queryParams, async);

            // setting default and user settings
            setHeaders(xhr, config.headers);

            // setting data
            if (config.data !== undefined) {
                var d = config.data;
                if (d instanceof (global.ArrayBufferView || global.ArrayBuffer) || d instanceof global.Blob ||
                    d instanceof global.Document || d instanceof global.FormData) {
                    dataForSend = d;
                } else {
                    if (typeof d === 'object' && d) {
                        dataForSend = JSON.stringify(d);
                    } else {
                        dataForSend = String(d);
                    }
                }
            }

            // adding event listeners
            xhr.addEventListener('error', function (e) {
                result.applyCallback('error', e);
            });
            xhr.addEventListener('progress', function (e) {
                result.applyCallback('progress', e);
            });
            xhr.addEventListener('loadstart', function (e) {
                result.applyCallback('loadstart', e);
            });
            xhr.addEventListener('loadend', function (e) {
                result.applyCallback('loadend', e);
            });
            xhr.addEventListener('abort', function (e) {
                result.applyCallback('abort', e);
            });
            xhr.addEventListener('load', function (e) {
                result.applyCallback('load', e);
                var response = xhr.response;
                if (xhr.responseType !== 'json') {
                    try {
                        response = JSON.parse(xhr.responseText);
                    } catch (e) {
                        response = xhr.responseText;
                    }
                }
                if (xhr.status >= 200 && xhr.status < 400) {
                    result.applyCallback('success', response);
                } else if (xhr.status >= 400 && xhr.status < 600) {
                    result.applyCallback('error', e);
                }
            }, false);

            // sending
            setTimeout(function () {
                xhr.send(dataForSend);
            }, 0);
            return result.actions;
        }
    }

    Object.defineProperty(XHR, 'defaults', {
        value: {
            method: 'GET',
            headers: {},
            attributes: {
                responseType: '',
                timeout: 0
            }
        },
        configurable: false,
        writable: false
    });

    global.XHR = XHR;

    if (typeof define === 'function' && define.amd !== null) {
        define('XHR', [], function () {
            return XHR;
        });
    }

}(window));

(function (XHR) {

    'use strict';

    function XHRPromise (xhr) {
        var _this = this;
        this.callbacks = {
            error: null,
            loadStart: null,
            progress: null,
            loadEnd: null,
            abort: null,
            load: null,
            success: null
        };
        this.actions = {
            error: function error (callback) {
                _this.callbacks.error = callback;
                return _this.actions;
            },
            loadStart: function loadStart (callback) {
                _this.callbacks.loadStart = callback;
                return _this.actions;
            },
            progress: function progress (callback) {
                _this.callbacks.progress = callback;
                return _this.actions;
            },
            loadEnd: function loadEnd (callback) {
                _this.callbacks.loadEnd = callback;
                return _this.actions;
            },
            abort: function abort (callback) {
                _this.callbacks.abort = callback;
                return _this.actions;
            },
            load: function load (callback) {
                _this.callbacks.load = callback;
                return _this.actions;
            },
            success: function success (callback) {
                _this.callbacks.success = callback;
                return _this.actions;
            },
            getXHR: function getXHR () {
                return xhr;
            }
        };

    }

    XHRPromise.prototype.applyCallback = function applyCallback (callbackName, data) {
        var callback = this.callbacks[callbackName];
        if (typeof callback === 'function') {
            callback(data);
        }
    };

    XHR.XHRPromise = XHRPromise;

}(window.XHR));
<|endoftext|>


<commit_before>'use strict';
//Add scripts in order.
var ProcessingScripts = ["lynximport"];
var ScriptsPath = "../addons/ProcessesingScripts/"; //path to the script folder, ralative to boot.js
exports.engineVersion = "1.7.6";
/*
The script should have the function "Process(string)" with a return type of string. Like so
exports.Process = function(somestring){
	//do stuff
	return somestring;
}
*/

//------------------------------------------------------------------

var Scripts = [];
ProcessingScripts.forEach(function(file){
	try{
		var fullpath = ScriptsPath + file + ".js";
		var required = require(fullpath);
		if(typeof required.Process != 'function'){
			console.log(file+ " script doesnt contain a Process function");
		}
		else{Scripts.push(required)}
	}catch(err){
		debugger;
		console.log(file+ " script not found or not valid.");
	}
});

var templatehandler = require("../engine/templateHandler.js");
var originalTestPageFields;

exports.init = function(){
	originalTestPageFields = templatehandler.testPageFields;

	templatehandler.testPageFields = function(document, page, errors){

		var pagestring = this[page.template].toString('utf8');
		Scripts.forEach(function(script){
			pagestring = script.Process(pagestring);
		});
		this[page.template] = Buffer.from(pagestring, 'utf8');
		document = require('jsdom').jsdom(this[page.template]);
		return originalTestPageFields(document, page, errors);
	}
}
<commit_msg>Made it also handle static files.<commit_after>'use strict';
//Add scripts in order.
var ProcessingScripts = ["lynximport"];
var ScriptsPath = "../addons/ProcessesingScripts/"; //path to the script folder, ralative to boot.js
exports.engineVersion = "1.7.6";
/*
The script should have the function "Process(string)" with a return type of string. Like so
exports.Process = function(somestring){
	//do stuff
	return somestring;
}
*/

//------------------------------------------------------------------

var Scripts = [];
ProcessingScripts.forEach(function(file){
	try{
		var fullpath = ScriptsPath + file + ".js";
		var required = require(fullpath);
		if(typeof required.Process != 'function'){
			console.log(file+ " script doesnt contain a Process function");
		}
		else{Scripts.push(required)}
	}catch(err){
		debugger;
		console.log(file+ " script not found or not valid.");
	}
});

var templatehandler = require("../engine/templateHandler.js");
var statichandler = require("../engine/staticHandler.js");
var miscOps = require("../engine/miscOps.js");

var originalTestPageFields;
var originalStaticCompress;

exports.init = function(){
	originalTestPageFields = templatehandler.testPageFields;
	originalStaticCompress = statichandler.compress;

	//static file processing (called upon first request of files)
	statichandler.compress = function(pathName, file, mime, callback){
		if(miscOps.isPlainText(mime)){
			var pagestring = file.content.toString('utf8');
			Scripts.forEach(function(script){
				pagestring = script.Process(pagestring);
			});
			file.content = Buffer.from(pagestring, 'utf8');
		}
		originalStaticCompress(pathName, file, mime, callback);
	}

	//template page processing (called on build)
	templatehandler.testPageFields = function(document, page, errors){

		var pagestring = this[page.template].toString('utf8');
		Scripts.forEach(function(script){
			pagestring = script.Process(pagestring);
		});
		this[page.template] = Buffer.from(pagestring, 'utf8');
		document = require('jsdom').jsdom(this[page.template]);
		return originalTestPageFields(document, page, errors);
	}
}
<|endoftext|>


<commit_before>/**
 * TourTooltips component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import { useMount } from 'react-use';
import Joyride, { ACTIONS, EVENTS, LIFECYCLE, STATUS } from 'react-joyride';
import PropTypes from 'prop-types';

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
import { useContext } from '@wordpress/element';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { CORE_UI } from '../googlesitekit/datastore/ui/constants';
import { CORE_USER } from '../googlesitekit/datastore/user/constants';
import { trackEvent } from '../util/tracking';
import ViewContextContext from '../components/Root/ViewContextContext';
import TourTooltip from './TourTooltip';
const { useSelect, useDispatch } = Data;

/** For available options, see: {@link https://github.com/gilbarbara/react-joyride/blob/3e08384415a831b20ce21c8423b6c271ad419fbf/src/styles.js}. */
const joyrideStyles = {
	options: {
		arrowColor: '#1A73E8', // $c-royal-blue
		backgroundColor: '#1A73E8', // $c-royal-blue
		overlayColor: 'rgba(0, 0, 0, 0.6)',
		textColor: '#ffffff', // $c-white
	},
};

// Provides button content as well as aria-label & title attribute values.
const joyrideLocale = {
	back: __( 'Back', 'google-site-kit' ),
	close: __( 'Close', 'google-site-kit' ),
	last: __( 'Got it', 'google-site-kit' ),
	next: __( 'Next', 'google-site-kit' ),
};

/** For available options, see: {@link https://github.com/gilbarbara/react-floater#props}. */
const floaterProps = {
	disableAnimation: true,
	styles: {
		arrow: {
			length: 8,
			margin: 56,
			spread: 16,
		},
		floater: {
			filter:
				'drop-shadow(rgba(60, 64, 67, 0.3) 0px 1px 2px) drop-shadow(rgba(60, 64, 67, 0.15) 0px 2px 6px)',
		},
	},
};

// GA Event Tracking actions (do not change!)
export const GA_ACTIONS = {
	VIEW: 'feature_tooltip_view',
	NEXT: 'feature_tooltip_advance',
	PREV: 'feature_tooltip_return',
	DISMISS: 'feature_tooltip_dismiss',
	COMPLETE: 'feature_tooltip_complete',
};

export default function TourTooltips( {
	steps,
	tourID,
	gaEventCategory,
	callback,
} ) {
	const stepKey = `${ tourID }-step`;
	const runKey = `${ tourID }-run`;
	const { setValue } = useDispatch( CORE_UI );
	const { dismissTour } = useDispatch( CORE_USER );

	const viewContext = useContext( ViewContextContext );

	const stepIndex = useSelect( ( select ) =>
		select( CORE_UI ).getValue( stepKey )
	);
	const run = useSelect( ( select ) => {
		return (
			select( CORE_UI ).getValue( runKey ) &&
			select( CORE_USER ).isTourDismissed( tourID ) === false
		);
	} );

	const changeStep = ( index, action ) =>
		setValue( stepKey, index + ( action === ACTIONS.PREV ? -1 : 1 ) );

	const startTour = () => {
		setValue( runKey, true );
	};

	const endTour = () => {
		// Dismiss tour to avoid unwanted repeat viewing.
		dismissTour( tourID );
	};

	const trackAllTourEvents = ( {
		index,
		action,
		lifecycle,
		size,
		status,
		type,
	} ) => {
		// The index is 0-based, but step numbers are 1-based.
		const stepNumber = index + 1;

		const eventCategory =
			typeof gaEventCategory === 'function'
				? gaEventCategory( viewContext )
				: gaEventCategory;

		if ( type === EVENTS.TOOLTIP && lifecycle === LIFECYCLE.TOOLTIP ) {
			trackEvent( eventCategory, GA_ACTIONS.VIEW, stepNumber );
		} else if (
			action === ACTIONS.CLOSE &&
			lifecycle === LIFECYCLE.COMPLETE
		) {
			trackEvent( eventCategory, GA_ACTIONS.DISMISS, stepNumber );
		} else if (
			action === ACTIONS.NEXT &&
			status === STATUS.FINISHED &&
			type === EVENTS.TOUR_END &&
			// Here we need to additionally check the size === stepNumber because
			// it is the only way to differentiate the status/event combination
			// from an identical combination that happens immediately after completion
			// on index `0` to avoid duplicate measurement.
			size === stepNumber
		) {
			trackEvent( eventCategory, GA_ACTIONS.COMPLETE, stepNumber );
		}

		if ( lifecycle !== LIFECYCLE.COMPLETE || status === STATUS.FINISHED ) {
			return;
		}

		if ( action === ACTIONS.PREV ) {
			trackEvent( eventCategory, GA_ACTIONS.PREV, stepNumber );
		}
		if ( action === ACTIONS.NEXT ) {
			trackEvent( eventCategory, GA_ACTIONS.NEXT, stepNumber );
		}
	};

	/**
	 * Handles `react-joyride` state changes using callback function.
	 *
	 * @typedef {Object} JoyrideCallbackData
	 * @property {string} action The action that updated the state.
	 * @property {status} status The tour's status.
	 * @property {number} index  Step index.
	 * @property {string} type   Specific type (tour, step, beacon).
	 *
	 * @since 1.28.0
	 * @since 1.38.0 Calls new callback prop.
	 * @see {@link https://docs.react-joyride.com/callback} Example data provided by `react-joyride`.
	 * @see {@link https://docs.react-joyride.com/constants} State & lifecycle constants used by `react-joyride`.
	 *
	 * @param {JoyrideCallbackData} data Data object provided via `react-joyride` callback prop.
	 */
	const handleJoyrideCallback = ( data ) => {
		trackAllTourEvents( data );
		const { action, index, status, step, type } = data;

		const hasCloseAction = action === ACTIONS.CLOSE;
		const shouldChangeStep =
			! hasCloseAction &&
			[ EVENTS.STEP_AFTER, EVENTS.TARGET_NOT_FOUND ].includes( type );
		const isFinishedOrSkipped = [
			STATUS.FINISHED,
			STATUS.SKIPPED,
		].includes( status );
		const shouldCloseFromButtonClick =
			hasCloseAction && type === EVENTS.STEP_AFTER;
		const shouldEndTour = isFinishedOrSkipped || shouldCloseFromButtonClick;

		// Center the target in the viewport when transitioning to the step.
		if ( EVENTS.STEP_BEFORE === type ) {
			let el = step.target;
			if ( 'string' === typeof step.target ) {
				el = global.document.querySelector( step.target );
			}
			el?.scrollIntoView?.( { block: 'center' } );
		}

		if ( shouldChangeStep ) {
			changeStep( index, action );
		} else if ( shouldEndTour ) {
			endTour();
		}

		if ( callback ) {
			callback( data );
		}
	};

	// Start tour on initial render
	useMount( startTour );

	const parsedSteps = steps.map( ( step ) => ( {
		disableBeacon: true,
		isFixed: true,
		placement: 'auto',
		...step,
	} ) );

	return (
		<Joyride
			callback={ handleJoyrideCallback }
			continuous
			disableOverlayClose
			disableScrolling
			floaterProps={ floaterProps }
			locale={ joyrideLocale }
			run={ run }
			showProgress
			stepIndex={ stepIndex }
			steps={ parsedSteps }
			styles={ joyrideStyles }
			tooltipComponent={ TourTooltip }
		/>
	);
}

/** For available properties & docs for `steps`, see: {@link https://docs.react-joyride.com/step#options}. */
TourTooltips.propTypes = {
	steps: PropTypes.arrayOf( PropTypes.object ).isRequired,
	tourID: PropTypes.string.isRequired,
	gaEventCategory: PropTypes.oneOfType( [ PropTypes.string, PropTypes.func ] )
		.isRequired,
	callback: PropTypes.func,
};
<commit_msg>Update TourTooltip component.<commit_after>/**
 * TourTooltips component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import { useMount } from 'react-use';
import Joyride, { ACTIONS, EVENTS, LIFECYCLE, STATUS } from 'react-joyride';
import PropTypes from 'prop-types';

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
import { useContext } from '@wordpress/element';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { CORE_UI } from '../googlesitekit/datastore/ui/constants';
import { CORE_USER } from '../googlesitekit/datastore/user/constants';
import { trackEvent } from '../util/tracking';
import ViewContextContext from '../components/Root/ViewContextContext';
import TourTooltip from './TourTooltip';
const { useSelect, useDispatch } = Data;

/** For available options, see: {@link https://github.com/gilbarbara/react-joyride/blob/3e08384415a831b20ce21c8423b6c271ad419fbf/src/styles.js}. */
const joyrideStyles = {
	options: {
		arrowColor: '#1A73E8', // $c-royal-blue
		backgroundColor: '#1A73E8', // $c-royal-blue
		overlayColor: 'rgba(0, 0, 0, 0.6)',
		textColor: '#ffffff', // $c-white
	},
};

// Provides button content as well as aria-label & title attribute values.
const joyrideLocale = {
	back: __( 'Back', 'google-site-kit' ),
	close: __( 'Close', 'google-site-kit' ),
	last: __( 'Got it', 'google-site-kit' ),
	next: __( 'Next', 'google-site-kit' ),
};

/** For available options, see: {@link https://github.com/gilbarbara/react-floater#props}. */
const floaterProps = {
	disableAnimation: true,
	styles: {
		arrow: {
			length: 8,
			margin: 56,
			spread: 16,
		},
		floater: {
			filter:
				'drop-shadow(rgba(60, 64, 67, 0.3) 0px 1px 2px) drop-shadow(rgba(60, 64, 67, 0.15) 0px 2px 6px)',
		},
	},
};

// GA Event Tracking actions (do not change!)
export const GA_ACTIONS = {
	VIEW: 'feature_tooltip_view',
	NEXT: 'feature_tooltip_advance',
	PREV: 'feature_tooltip_return',
	DISMISS: 'feature_tooltip_dismiss',
	COMPLETE: 'feature_tooltip_complete',
};

export default function TourTooltips( {
	steps,
	tourID,
	gaEventCategory,
	callback,
} ) {
	const stepKey = `${ tourID }-step`;
	const runKey = `${ tourID }-run`;
	const { setValue } = useDispatch( CORE_UI );
	const { dismissTour } = useDispatch( CORE_USER );

	const viewContext = useContext( ViewContextContext );

	const stepIndex = useSelect( ( select ) =>
		select( CORE_UI ).getValue( stepKey )
	);
	const run = useSelect( ( select ) => {
		return (
			select( CORE_UI ).getValue( runKey ) &&
			select( CORE_USER ).isTourDismissed( tourID ) === false
		);
	} );

	const changeStep = ( index, action ) =>
		setValue( stepKey, index + ( action === ACTIONS.PREV ? -1 : 1 ) );

	const startTour = () => {
		global.document.body.classList.add(
			'googlesitekit-showing-feature-tour'
		);
		setValue( runKey, true );
	};

	const endTour = () => {
		global.document.body.classList.remove(
			'googlesitekit-showing-feature-tour'
		);
		// Dismiss tour to avoid unwanted repeat viewing.
		dismissTour( tourID );
	};

	const trackAllTourEvents = ( {
		index,
		action,
		lifecycle,
		size,
		status,
		type,
	} ) => {
		// The index is 0-based, but step numbers are 1-based.
		const stepNumber = index + 1;

		const eventCategory =
			typeof gaEventCategory === 'function'
				? gaEventCategory( viewContext )
				: gaEventCategory;

		if ( type === EVENTS.TOOLTIP && lifecycle === LIFECYCLE.TOOLTIP ) {
			trackEvent( eventCategory, GA_ACTIONS.VIEW, stepNumber );
		} else if (
			action === ACTIONS.CLOSE &&
			lifecycle === LIFECYCLE.COMPLETE
		) {
			trackEvent( eventCategory, GA_ACTIONS.DISMISS, stepNumber );
		} else if (
			action === ACTIONS.NEXT &&
			status === STATUS.FINISHED &&
			type === EVENTS.TOUR_END &&
			// Here we need to additionally check the size === stepNumber because
			// it is the only way to differentiate the status/event combination
			// from an identical combination that happens immediately after completion
			// on index `0` to avoid duplicate measurement.
			size === stepNumber
		) {
			trackEvent( eventCategory, GA_ACTIONS.COMPLETE, stepNumber );
		}

		if ( lifecycle !== LIFECYCLE.COMPLETE || status === STATUS.FINISHED ) {
			return;
		}

		if ( action === ACTIONS.PREV ) {
			trackEvent( eventCategory, GA_ACTIONS.PREV, stepNumber );
		}
		if ( action === ACTIONS.NEXT ) {
			trackEvent( eventCategory, GA_ACTIONS.NEXT, stepNumber );
		}
	};

	/**
	 * Handles `react-joyride` state changes using callback function.
	 *
	 * @typedef {Object} JoyrideCallbackData
	 * @property {string} action The action that updated the state.
	 * @property {status} status The tour's status.
	 * @property {number} index  Step index.
	 * @property {string} type   Specific type (tour, step, beacon).
	 *
	 * @since 1.28.0
	 * @since 1.38.0 Calls new callback prop.
	 * @see {@link https://docs.react-joyride.com/callback} Example data provided by `react-joyride`.
	 * @see {@link https://docs.react-joyride.com/constants} State & lifecycle constants used by `react-joyride`.
	 *
	 * @param {JoyrideCallbackData} data Data object provided via `react-joyride` callback prop.
	 */
	const handleJoyrideCallback = ( data ) => {
		trackAllTourEvents( data );
		const { action, index, status, step, type } = data;

		const hasCloseAction = action === ACTIONS.CLOSE;
		const shouldChangeStep =
			! hasCloseAction &&
			[ EVENTS.STEP_AFTER, EVENTS.TARGET_NOT_FOUND ].includes( type );
		const isFinishedOrSkipped = [
			STATUS.FINISHED,
			STATUS.SKIPPED,
		].includes( status );
		const shouldCloseFromButtonClick =
			hasCloseAction && type === EVENTS.STEP_AFTER;
		const shouldEndTour = isFinishedOrSkipped || shouldCloseFromButtonClick;

		// Center the target in the viewport when transitioning to the step.
		if ( EVENTS.STEP_BEFORE === type ) {
			let el = step.target;
			if ( 'string' === typeof step.target ) {
				el = global.document.querySelector( step.target );
			}
			el?.scrollIntoView?.( { block: 'center' } );
		}

		if ( shouldChangeStep ) {
			changeStep( index, action );
		} else if ( shouldEndTour ) {
			endTour();
		}

		if ( callback ) {
			callback( data );
		}
	};

	// Start tour on initial render
	useMount( startTour );

	const parsedSteps = steps.map( ( step ) => ( {
		disableBeacon: true,
		isFixed: true,
		placement: 'auto',
		...step,
	} ) );

	return (
		<Joyride
			callback={ handleJoyrideCallback }
			continuous
			disableOverlayClose
			disableScrolling
			floaterProps={ floaterProps }
			locale={ joyrideLocale }
			run={ run }
			showProgress
			stepIndex={ stepIndex }
			steps={ parsedSteps }
			styles={ joyrideStyles }
			tooltipComponent={ TourTooltip }
		/>
	);
}

/** For available properties & docs for `steps`, see: {@link https://docs.react-joyride.com/step#options}. */
TourTooltips.propTypes = {
	steps: PropTypes.arrayOf( PropTypes.object ).isRequired,
	tourID: PropTypes.string.isRequired,
	gaEventCategory: PropTypes.oneOfType( [ PropTypes.string, PropTypes.func ] )
		.isRequired,
	callback: PropTypes.func,
};
<|endoftext|>


<commit_before>function Teams() {
    this.teams = [
        {
            id: "Renaissance",
            name: "Renaissance",
            streams: ["StreamR1", "StreamR2", "StreamR3"],
            teamLead: "Aliaksandr Koush",
            qaTeamLead: "Aliaksandra Kutynka",
            developers: [
                "Andrei Osipau2",
                "Dzianis Arlouski",
                "Siarhei Tkachenka",
                "Iryna Kucharenka1",
                "Ivan Izmer",
                "Mark Varabyou",
                "Raman But-Husaim",
                "Siarhei Abrazhevich",
                "Artsiom Rusak",
                "Raman Ivanou",
                "Aliaksandr Koush",
                "Nicolay Kostroma",
                "Valentina Napolnova",
                "Aliaksey Rahatka",
                "Pavel Kastsiuk",
                "Juliana Stolnik",
                "Artsiom Kazlou"
            ],
            testers: [
                "Pavel Vysotsky",
                "Viktoriya Harbatsenkava",
                "Hanna Prykhodzka",
                "Kseniya Kavalchuk",
                "Yuliya Tukaila",
                "Aliaksandra Kutynka"
            ]
        },
        {
            id: "Inspiration",
            name: "Inspiration",
            streams: ["StreamIn1", "StreamIn2", "StreamIn3"],
            teamLead: "Sergey Tischenko",
            qaTeamLead: "Denys Pugachov",
            developers: [
                "Borys Roshal",
                "Denys Poliakov",
                "Kostiantyn Lazurenko",
                "Oleksandr Stukalov",
                "Oleksii Bespalko",
                "Yevhenii Havryliuk",
                "Yuriy Shestyora",
                "Ihor Bershov",
                "Vladyslav Pilhui",
                "Oleksandr Zhyltsov",
                "Oleksii Suriadnyi",
                "Serhiy Haponenko",
                "Yevhenii Lomov",
                "Ihor Rudchenko",
                "Andrii Savinov",
                "Dmytro Petlia",
                "Olena Ostroverkhova"
            ],
            testers: [
                "Mila Botnar",
                "Yuri Timchenko",
                "Anastasia Kotenyova",
                "Pavlo Golovashchenko",
                "Oleksii Milman",
                "Denys Pugachov"
            ]
        },
        {
            id: "Nova",
            name: "Nova",
            streams: ["StreamN1", "StreamN2", "StreamN3"],
            teamLead: "Heorhi Vilkitski",
            qaTeamLead: "Valiantsina Krautsevich",
            developers: [
                "Andrei Kandybovich",
                "Dzmitry Siamchonak",
                "Mikita Stalpinski",
                "Uladzimir Harabtsou",
                "Aliaksandr Nikulin",
                "Ilya Kazlou1",
                "Katsiaryna Kaliukhovich",
                "Vadzim Vysotski",
                "Edhar Liashok",
                "Raman Prakofyeu",
                "Ruslan Khilmanovich",
                "Anton Kratenok",
                "Siarhei Maksimau1",
                "Dzmitry Chapurok",
                "Evgeny Sinitsyn",
                "Dzmitry Salodki"
            ],
            testers: [
                "Aliaksei Burnosenka",
                "Viktar Mikalayenka",
                "Eugeny Okulik",
                "Yuliya Kalasouskaya",
                "Hanna Maskalenka",
                "Valiantsina Krautsevich"
            ]
        },
        {
            id: "Liberty",
            name: "Liberty",
            streams: ["StreamL1", "StreamL2", "StreamL3"],
            teamLead: "Dzmitry Tabolich",
            qaTeamLead: "Iryna Kutsko",
            developers: [
                "Pavel Naumenka",
                "Sergei Kulick",
                "Volha Shandrokha",
                "Aliaksandr Rusak",
                "Andrei Kasak",
                "Andrei Krasnou",
                "Pavel Krakasevich",
                "Stepan Zelenin",
                "Dzmitry Isachenka",
                "Eugen Surovets",
                "Katsiaryna Tsalabanava",
                "Kate Tsalabanava",
                "Vitali Podobed",
                "Hleb Krotsik",
                "Uladzimir Vysotski"
            ],
            testers: [
                "Anna Novikova",
                "Anton Rapinchuk",
                "Igor Andros",
                "Maria Sobal",
                "Yuliya Karnatsevich",
                "Iryna Kutsko",
                "Natalya Krestelyova"
            ]
        },
        {
            id: "Viva",
            name: "Viva",
            streams: ["StreamV1", "StreamV2", "StreamV3"],
            teamLead: "Valentine Zhuck",
            qaTeamLead: "Katsiaryna Kuchko",
            developers: [
                "Valentine Zhuck",
                "Maryna Furman",
                "Siarhei Zhalezka",
                "Viachaslau Anufryiuk",
                "Yury Yamoryk",
                "Aliaksandr Kladau",
                "Dzmitry Kavaliou",
                "Dzmitry Shynkarou",
                "Maksim Tsikhan",
                "Petr Falitarchyk",
                "Yuri Chupyrkin",
                "Aliaksandr Rykau",
                "Ivan Dziameshka",
                "Siarhei Bahdanovich",
                "Andrei Lysenka",
                "Aleh Dukel",
                "Ivan Yanchuk"
            ],
            testers: [
                "Iryna Koush",
                "Maryia Kireyeva",
                "Iryna Shuliak",
                "Liudmila Barshcheuskaya",
                "Iryna Razorionova",
                "Katsiaryna Kuchko"
            ]
        },
        {
            id: "Elfish",
            name: "Elfish",
            teamLead: "Roman Golovchenko",
            qaTeamLead: "",
            developers: [
                "Roman Golovchenko",
                "Allaberdi Hojayev",
                "Bohdan Sorokin",
                "Yevhenii Koliesnik"
            ],
            testers: [
                "Ivan Nalyvaiko",
                "Oleksii Shchelkunov",
                "Valeriia Karabut"
            ]
        },
        {
            id: "TeamAutomation",
            name: "Automation",
            teamLead: "Aliaksandr Basau",
            developers: [
                "Nadzeya Mishurava",
                "Viachaslau Naimovich",
                "Vitali Sonchyk",
                "Katsiaryna Firsava",
                "Katsiaryna Kulbitskaya",
                "Maryia Kashtanava",
                "Rustam Allanazarau"
            ]
        }
    ]
}

exports.AllTeams = new Teams();

exports.OldDevelopers = function oldDevelopers(name) {
    if(name == 'Valentine Zhuck' ||
        name == 'Dzmitry Tabolich' ||
        name == 'Heorhi Vilkitski' ||
        name == "Hanna Kastsian" ||
        name == "Alena Charnova" ||
        name == "Aliaksei Astashkin" ||
        name == "yauheni_lohinau" ||
        name == "Dmytro Komar" ||
        name == "Aliaksei Labachou" ||
        name == "Mariya Babich" ||
        name == "Katsiaryna Sasina" ||
        name == "aliaksei_labachou aliaksei_labachou" ||
        name == undefined) {
        return true;
    }
    return false;
};
<commit_msg>teams updated<commit_after>function Teams() {
    this.teams = [
        {
            id: "Renaissance",
            name: "Renaissance",
            streams: ["StreamR1", "StreamR2", "StreamR3"],
            teamLead: "Aliaksandr Koush",
            qaTeamLead: "Aliaksandra Kutynka",
            developers: [
                "Andrei Osipau2",
                "Dzianis Arlouski",
                "Siarhei Tkachenka",
                "Iryna Kucharenka1",
                "Ivan Izmer",
                "Mark Varabyou",
                "Raman But-Husaim",
                "Siarhei Abrazhevich",
                "Artsiom Rusak",
                "Raman Ivanou",
                "Aliaksandr Koush",
                "Nicolay Kostroma",
                "Valentina Napolnova",
                "Aliaksey Rahatka",
                "Pavel Kastsiuk",
                "Juliana Stolnik",
                "Artsiom Kazlou"
            ],
            testers: [
                "Pavel Vysotsky",
                "Viktoriya Harbatsenkava",
                "Hanna Prykhodzka",
                "Kseniya Kavalchuk",
                "Yuliya Tukaila",
                "Aliaksandra Kutynka"
            ]
        },
        {
            id: "Inspiration",
            name: "Inspiration",
            streams: ["StreamIn1", "StreamIn2", "StreamIn3"],
            teamLead: "Sergey Tischenko",
            qaTeamLead: "Denys Pugachov",
            developers: [
                "Borys Roshal",
                "Denys Poliakov",
                "Kostiantyn Lazurenko",
                "Oleksandr Stukalov",
                "Oleksii Bespalko",
                "Yevhenii Havryliuk",
                "Yuriy Shestyora",
                "Ihor Bershov",
                "Vladyslav Pilhui",
                "Oleksandr Zhyltsov",
                "Oleksii Suriadnyi",
                "Serhiy Haponenko",
                "Yevhenii Lomov",
                "Ihor Rudchenko",
                "Andrii Savinov",
                "Dmytro Petlia",
                "Olena Ostroverkhova"
            ],
            testers: [
                "Mila Botnar",
                "Yuri Timchenko",
                "Anastasia Kotenyova",
                "Pavlo Golovashchenko",
                "Oleksii Milman",
                "Denys Pugachov"
            ]
        },
        {
            id: "Nova",
            name: "Nova",
            streams: ["StreamN1", "StreamN2", "StreamN3"],
            teamLead: "Heorhi Vilkitski",
            qaTeamLead: "Valiantsina Krautsevich",
            developers: [
                "Andrei Kandybovich",
                "Dzmitry Siamchonak",
                "Mikita Stalpinski",
                "Uladzimir Harabtsou",
                "Aliaksandr Nikulin",
                "Ilya Kazlou1",
                "Katsiaryna Kaliukhovich",
                "Vadzim Vysotski",
                "Edhar Liashok",
                "Raman Prakofyeu",
                "Ruslan Khilmanovich",
                "Anton Kratenok",
                "Siarhei Maksimau1",
                "Dzmitry Chapurok",
                "Evgeny Sinitsyn",
                "Dzmitry Salodki"
            ],
            testers: [
                "Aliaksei Burnosenka",
                "Viktar Mikalayenka",
                "Eugeny Okulik",
                "Yuliya Kalasouskaya",
                "Hanna Maskalenka",
                "Valiantsina Krautsevich"
            ]
        },
        {
            id: "Liberty",
            name: "Liberty",
            streams: ["StreamL1", "StreamL2", "StreamL3"],
            teamLead: "Dzmitry Tabolich",
            qaTeamLead: "Iryna Kutsko",
            developers: [
                "Pavel Naumenka",
                "Sergei Kulick",
                "Volha Shandrokha",
                "Aliaksandr Rusak",
                "Andrei Kasak",
                "Andrei Krasnou",
                "Pavel Krakasevich",
                "Stepan Zelenin",
                "Dzmitry Isachenka",
                "Eugen Surovets",
                "Katsiaryna Tsalabanava",
                "Kate Tsalabanava",
                "Vitali Podobed",
                "Hleb Krotsik",
                "Uladzimir Vysotski"
            ],
            testers: [
                "Anna Novikova",
                "Anton Rapinchuk",
                "Igor Andros",
                "Maria Sobal",
                "Yuliya Karnatsevich",
                "Iryna Kutsko",
                "Natalya Krestelyova"
            ]
        },
        {
            id: "Viva",
            name: "Viva",
            streams: ["StreamV1", "StreamV2", "StreamV3"],
            teamLead: "Valentine Zhuck",
            qaTeamLead: "Katsiaryna Kuchko",
            developers: [
                "Valentine Zhuck",
                "Siarhei Zhalezka",
                "Viachaslau Anufryiuk",
                "Yury Yamoryk",
                "Aliaksandr Kladau",
                "Dzmitry Kavaliou",
                "Dzmitry Shynkarou",
                "Maksim Tsikhan",
                "Petr Falitarchyk",
                "Yuri Chupyrkin",
                "Aliaksandr Rykau",
                "Ivan Dziameshka",
                "Siarhei Bahdanovich",
                "Andrei Lysenka",
                "Aleh Dukel",
                "Ivan Yanchuk",
                "Kanstantsin Ldou",
                "Katsiaryna Zeliankova"
            ],
            testers: [
                "Iryna Koush",
                "Maryia Kireyeva",
                "Iryna Shuliak",
                "Liudmila Barshcheuskaya",
                "Iryna Razorionova",
                "Katsiaryna Kuchko"
            ]
        },
        {
            id: "Elfish",
            name: "Elfish",
            teamLead: "Roman Golovchenko",
            qaTeamLead: "",
            developers: [
                "Roman Golovchenko",
                "Allaberdi Hojayev",
                "Bohdan Sorokin",
                "Yevhenii Koliesnik"
            ],
            testers: [
                "Ivan Nalyvaiko",
                "Oleksii Shchelkunov",
                "Valeriia Karabut"
            ]
        },
        {
            id: "TeamAutomation",
            name: "Automation",
            teamLead: "Aliaksandr Basau",
            developers: [
                "Nadzeya Mishurava",
                "Viachaslau Naimovich",
                "Vitali Sonchyk",
                "Katsiaryna Firsava",
                "Katsiaryna Kulbitskaya",
                "Maryia Kashtanava",
                "Rustam Allanazarau"
            ]
        }
    ]
}

exports.AllTeams = new Teams();

exports.OldDevelopers = function oldDevelopers(name) {
    if(name == 'Valentine Zhuck' ||
        name == 'Dzmitry Tabolich' ||
        name == 'Heorhi Vilkitski' ||
        name == "Hanna Kastsian" ||
        name == "Alena Charnova" ||
        name == "Aliaksei Astashkin" ||
        name == "yauheni_lohinau" ||
        name == "Dmytro Komar" ||
        name == "Aliaksei Labachou" ||
        name == "Mariya Babich" ||
        name == "Katsiaryna Sasina" ||
        name == "aliaksei_labachou aliaksei_labachou" ||
        name == "Maryna Furman" ||
        name == undefined) {
        return true;
    }
    return false;
};
<|endoftext|>