<commit_before>var DURATION = 30,
    MINVALUE = 0,
    MAXVALUE = 3000,
    GRANULARITY = 10,
    MAXSTROKE = 20,
    MAXRADIUS = 200,
    MINSHARES = 0,
    nbCities,
    nbNodes,
    nbSteps,
    arcs = {},
    halfCircles = {},
    currentStrokes = {},
    currentRadii = {},
    currentAnimations = [],
    currentScale,
    currentTime,
    isPlaying = false,
    focusedCity = -1,
    maxShareCount,
    strokeFactor = 0,
    radiusFactor = 0;

var initState = function() {
    nbCities = cities.length;
    nbNodes = finalShares.length;
    nbSteps = shareHistory.length;

    findMaxShareCount();
};

var findMaxShareCount = function() {
    maxShareCount = 0;

    for(var i = 0; i < finalShares.length; i += 1) {
        if(finalShares[i][2] > maxShareCount) {
            maxShareCount = finalShares[i][2];
        }
    }

    console.log(maxShareCount);
    strokeFactor = MAXSTROKE / maxShareCount;
    radiusFactor = MAXRADIUS / maxShareCount;
};

var switchToUserHistory = function() {
    shareHistory = userHistory;
    finalShares = userFinalShares;

    MAXSTROKE /= 2;
    MAXRADIUS /= 2;

    findMaxShareCount();
};

var switchToGlobalHistory = function() {
    shareHistory = globalHistory;
    finalShares = globalFinalShares;

    MAXSTROKE *=2;
    MAXRADIUS *=2;

    findMaxShareCount();
};

// gets the current value of the time slider
var updateCurrentTime = function() {
    currentTime = $timelapse.slider("value");
};

// gets the current value of the zoom slider
var updateCurrentScale = function() {
    currentScale = $zoom.slider("value");
};

var resetObjectValues = function(obj) {
    for(var key in obj) {
        obj[key] = 0;
    }
};

var resetHalfCircles = function() {
    for(id in halfCircles) {
        halfCircles[id].attr({arc: [0, 0, 0, 0, 1]});
    }
};

var resetArcs = function() {
    for(var key in currentStrokes) {
        var node = document.getElementById(key);
        node.style.strokeWidth = 0;
    }
};

var clearAll = function() {
    resetHalfCircles();
    resetArcs();
};

var refreshNodes = function() {
    var stroke,
        radius,
        xPos;

    clearAll();

    for(var key in currentStrokes) {
        if(currentStrokes[key] !== 0) {
            stroke = currentStrokes[key];
            var node = document.getElementById(key);
            node.style.strokeWidth = stroke;
        }
    }

    for(var key in currentRadii) {
        if(currentRadii[key] !== 0) {
            radius = currentRadii[key];
            xPos = (key - 1) * (width / nbCities);

            halfCircles[key].attr({arc: [xPos - radius, 650, xPos + radius, 650, 1]})
        }
    }
};

var fastForward = function(currentTime) {
    clearAnimations();
    resetObjectValues(currentStrokes);
    resetObjectValues(currentRadii);

    var stepsToCurrentTime = Math.floor(currentTime / GRANULARITY);

    for (var i = 0; i < stepsToCurrentTime; i += 1) {
        var nbPairs = shareHistory[i].length;

        for(var j = 0; j < nbPairs; j += 1) {
            var city1 = shareHistory[i][j][0],
                city2 = shareHistory[i][j][1],
                nbShares = shareHistory[i][j][2],
                nodeId = city1 + ":" + city2,
                node = document.getElementById(nodeId),
                stroke = nbShares * strokeFactor,
                radius = nbShares * radiusFactor;

            if((city2 - city1) <= 5) {
                stroke /= 4;
            }

            if((city2 - city1) === 1) {
                stroke /= 8;
            }

            if(city1 === focusedCity || city2 === focusedCity || focusedCity === -1) {
                if(city1 === city2) {
                    if(nbShares >= MINSHARES) {
                        currentRadii[city1] = radius;
                    }
                } else {
                    if(nbShares >= MINSHARES) {
                        currentStrokes[nodeId] = stroke;
                    }
                }
            }
        }
    }

    refreshNodes();
};

var togglePlay = function() {
    isPlaying = !isPlaying;

    if(isPlaying) {
        playTimelapse();
        showPauseButton();
    } else {
        stopTimelapse();
        showPlayButton();
    }
};

var drawFinalState = function() {
    fastForward(MAXVALUE);
};

var resetTimelapse = function() {
    $timelapse.slider('value', MINVALUE);
};

var resetToCurrentTime = function() {
    updateCurrentTime();
    fastForward(currentTime);
    if(!isPlaying && currentTime === MINVALUE) {
        fastForward(MAXVALUE);
    }
};<commit_msg>removing forgotten console.log<commit_after>var DURATION = 30,
    MINVALUE = 0,
    MAXVALUE = 3000,
    GRANULARITY = 10,
    MAXSTROKE = 20,
    MAXRADIUS = 200,
    MINSHARES = 0,
    nbCities,
    nbNodes,
    nbSteps,
    arcs = {},
    halfCircles = {},
    currentStrokes = {},
    currentRadii = {},
    currentAnimations = [],
    currentScale,
    currentTime,
    isPlaying = false,
    focusedCity = -1,
    maxShareCount,
    strokeFactor = 0,
    radiusFactor = 0;

var initState = function() {
    nbCities = cities.length;
    nbNodes = finalShares.length;
    nbSteps = shareHistory.length;

    findMaxShareCount();
};

var findMaxShareCount = function() {
    maxShareCount = 0;

    for(var i = 0; i < finalShares.length; i += 1) {
        if(finalShares[i][2] > maxShareCount) {
            maxShareCount = finalShares[i][2];
        }
    }

    strokeFactor = MAXSTROKE / maxShareCount;
    radiusFactor = MAXRADIUS / maxShareCount;
};

var switchToUserHistory = function() {
    shareHistory = userHistory;
    finalShares = userFinalShares;

    MAXSTROKE /= 2;
    MAXRADIUS /= 2;

    findMaxShareCount();
};

var switchToGlobalHistory = function() {
    shareHistory = globalHistory;
    finalShares = globalFinalShares;

    MAXSTROKE *=2;
    MAXRADIUS *=2;

    findMaxShareCount();
};

// gets the current value of the time slider
var updateCurrentTime = function() {
    currentTime = $timelapse.slider("value");
};

// gets the current value of the zoom slider
var updateCurrentScale = function() {
    currentScale = $zoom.slider("value");
};

var resetObjectValues = function(obj) {
    for(var key in obj) {
        obj[key] = 0;
    }
};

var resetHalfCircles = function() {
    for(id in halfCircles) {
        halfCircles[id].attr({arc: [0, 0, 0, 0, 1]});
    }
};

var resetArcs = function() {
    for(var key in currentStrokes) {
        var node = document.getElementById(key);
        node.style.strokeWidth = 0;
    }
};

var clearAll = function() {
    resetHalfCircles();
    resetArcs();
};

var refreshNodes = function() {
    var stroke,
        radius,
        xPos;

    clearAll();

    for(var key in currentStrokes) {
        if(currentStrokes[key] !== 0) {
            stroke = currentStrokes[key];
            var node = document.getElementById(key);
            node.style.strokeWidth = stroke;
        }
    }

    for(var key in currentRadii) {
        if(currentRadii[key] !== 0) {
            radius = currentRadii[key];
            xPos = (key - 1) * (width / nbCities);

            halfCircles[key].attr({arc: [xPos - radius, 650, xPos + radius, 650, 1]})
        }
    }
};

var fastForward = function(currentTime) {
    clearAnimations();
    resetObjectValues(currentStrokes);
    resetObjectValues(currentRadii);

    var stepsToCurrentTime = Math.floor(currentTime / GRANULARITY);

    for (var i = 0; i < stepsToCurrentTime; i += 1) {
        var nbPairs = shareHistory[i].length;

        for(var j = 0; j < nbPairs; j += 1) {
            var city1 = shareHistory[i][j][0],
                city2 = shareHistory[i][j][1],
                nbShares = shareHistory[i][j][2],
                nodeId = city1 + ":" + city2,
                node = document.getElementById(nodeId),
                stroke = nbShares * strokeFactor,
                radius = nbShares * radiusFactor;

            if((city2 - city1) <= 5) {
                stroke /= 4;
            }

            if((city2 - city1) === 1) {
                stroke /= 8;
            }

            if(city1 === focusedCity || city2 === focusedCity || focusedCity === -1) {
                if(city1 === city2) {
                    if(nbShares >= MINSHARES) {
                        currentRadii[city1] = radius;
                    }
                } else {
                    if(nbShares >= MINSHARES) {
                        currentStrokes[nodeId] = stroke;
                    }
                }
            }
        }
    }

    refreshNodes();
};

var togglePlay = function() {
    isPlaying = !isPlaying;

    if(isPlaying) {
        playTimelapse();
        showPauseButton();
    } else {
        stopTimelapse();
        showPlayButton();
    }
};

var drawFinalState = function() {
    fastForward(MAXVALUE);
};

var resetTimelapse = function() {
    $timelapse.slider('value', MINVALUE);
};

var resetToCurrentTime = function() {
    updateCurrentTime();
    fastForward(currentTime);
    if(!isPlaying && currentTime === MINVALUE) {
        fastForward(MAXVALUE);
    }
};<|endoftext|>


<commit_before>/*
Copyright 2017 Vector Creations Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import PropTypes from 'prop-types';
import AccessibleButton from './AccessibleButton';
import dis from '../../../dispatcher';
import sdk from '../../../index';
import Analytics from '../../../Analytics';

export default React.createClass({
    displayName: 'RoleButton',

    propTypes: {
        size: PropTypes.string,
        tooltip: PropTypes.bool,
        action: PropTypes.string.isRequired,
        mouseOverAction: PropTypes.string,
        label: PropTypes.string.isRequired,
        iconPath: PropTypes.string.isRequired,
    },

    getDefaultProps: function() {
        return {
            size: "25",
            tooltip: false,
        };
    },

    getInitialState: function() {
        return {
            showTooltip: false,
        };
    },

    _onClick: function(ev) {
        ev.stopPropagation();
        Analytics.trackEvent('Action Button', 'click', this.props.action);
        dis.dispatch({action: this.props.action});
    },

    _onMouseEnter: function() {
        if (this.props.tooltip) this.setState({showTooltip: true});
        if (this.props.mouseOverAction) {
            dis.dispatch({action: this.props.mouseOverAction});
        }
    },

    _onMouseLeave: function() {
        this.setState({showTooltip: false});
    },

    render: function() {
        const TintableSvg = sdk.getComponent("elements.TintableSvg");

        let tooltip;
        if (this.state.showTooltip) {
            const RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
            tooltip = <RoomTooltip className="mx_RoleButton_tooltip" label={this.props.label} />;
        }

        return (
            <AccessibleButton className="mx_RoleButton"
                onClick={this._onClick}
                onMouseEnter={this._onMouseEnter}
                onMouseLeave={this._onMouseLeave}
            >
                <TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />
                { tooltip }
            </AccessibleButton>
        );
    },
});
<commit_msg>Add aria-labels to ActionButtons<commit_after>/*
Copyright 2017 Vector Creations Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import PropTypes from 'prop-types';
import AccessibleButton from './AccessibleButton';
import dis from '../../../dispatcher';
import sdk from '../../../index';
import Analytics from '../../../Analytics';

export default React.createClass({
    displayName: 'RoleButton',

    propTypes: {
        size: PropTypes.string,
        tooltip: PropTypes.bool,
        action: PropTypes.string.isRequired,
        mouseOverAction: PropTypes.string,
        label: PropTypes.string.isRequired,
        iconPath: PropTypes.string.isRequired,
    },

    getDefaultProps: function() {
        return {
            size: "25",
            tooltip: false,
        };
    },

    getInitialState: function() {
        return {
            showTooltip: false,
        };
    },

    _onClick: function(ev) {
        ev.stopPropagation();
        Analytics.trackEvent('Action Button', 'click', this.props.action);
        dis.dispatch({action: this.props.action});
    },

    _onMouseEnter: function() {
        if (this.props.tooltip) this.setState({showTooltip: true});
        if (this.props.mouseOverAction) {
            dis.dispatch({action: this.props.mouseOverAction});
        }
    },

    _onMouseLeave: function() {
        this.setState({showTooltip: false});
    },

    render: function() {
        const TintableSvg = sdk.getComponent("elements.TintableSvg");

        let tooltip;
        if (this.state.showTooltip) {
            const RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
            tooltip = <RoomTooltip className="mx_RoleButton_tooltip" label={this.props.label} />;
        }

        return (
            <AccessibleButton className="mx_RoleButton"
                onClick={this._onClick}
                onMouseEnter={this._onMouseEnter}
                onMouseLeave={this._onMouseLeave}
                aria-label={this.props.label}
            >
                <TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />
                { tooltip }
            </AccessibleButton>
        );
    },
});
<|endoftext|>


<commit_before>/*
Copyright 2019 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';
import React from "react";
import dis from "../../../dispatcher";
import MatrixClientPeg from "../../../MatrixClientPeg";
import AccessibleButton from '../elements/AccessibleButton';
import RoomAvatar from '../avatars/RoomAvatar';
import classNames from 'classnames';
import sdk from "../../../index";
import * as RoomNotifs from '../../../RoomNotifs';
import * as FormattingUtils from "../../../utils/FormattingUtils";
import Analytics from "../../../Analytics";

const MAX_ROOMS = 20;

export default class RoomBreadcrumbs extends React.Component {
    constructor(props) {
        super(props);
        this.state = {rooms: []};
        this.onAction = this.onAction.bind(this);
        this._dispatcherRef = null;
    }

    componentWillMount() {
        this._dispatcherRef = dis.register(this.onAction);

        const roomStr = localStorage.getItem("mx_breadcrumb_rooms");
        if (roomStr) {
            try {
                const roomIds = JSON.parse(roomStr);
                this.setState({
                    rooms: roomIds.map((r) => {
                        return {
                            room: MatrixClientPeg.get().getRoom(r),
                            animated: false,
                        };
                    }).filter((r) => r.room),
                });
            } catch (e) {
                console.error("Failed to parse breadcrumbs:", e);
            }
        }

        MatrixClientPeg.get().on("Room.myMembership", this.onMyMembership);
        MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt);
        MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
        MatrixClientPeg.get().on("Event.decrypted", this.onEventDecrypted);
    }

    componentWillUnmount() {
        dis.unregister(this._dispatcherRef);

        const client = MatrixClientPeg.get();
        if (client) {
            client.removeListener("Room.myMembership", this.onMyMembership);
            client.removeListener("Room.receipt", this.onRoomReceipt);
            client.removeListener("Room.timeline", this.onRoomTimeline);
            client.removeListener("Event.decrypted", this.onEventDecrypted);
        }
    }

    componentDidUpdate() {
        const rooms = this.state.rooms.slice();

        if (rooms.length) {
            const {room, animated} = rooms[0];
            if (!animated) {
                rooms[0] = {room, animated: true};
                setTimeout(() => this.setState({rooms}), 0);
            }
        }

        const roomStr = JSON.stringify(rooms.map((r) => r.room.roomId));
        localStorage.setItem("mx_breadcrumb_rooms", roomStr);
    }

    onAction(payload) {
        switch (payload.action) {
            case 'view_room':
                this._appendRoomId(payload.room_id);
                break;
        }
    }

    onMyMembership = (room, membership) => {
        if (membership === "leave" || membership === "ban") {
            const rooms = this.state.rooms.slice();
            const roomState = rooms.find((r) => r.room.roomId === room.roomId);
            if (roomState) {
                roomState.left = true;
                this.setState({rooms});
            }
        }
    };

    onRoomReceipt = (event, room) => {
        if (this.state.rooms.map(r => r.room.roomId).includes(room.roomId)) {
            this._calculateRoomBadges(room);
        }
    };

    onRoomTimeline = (event, room) => {
        if (this.state.rooms.map(r => r.room.roomId).includes(room.roomId)) {
            this._calculateRoomBadges(room);
        }
    };

    onEventDecrypted = (event) => {
        if (this.state.rooms.map(r => r.room.roomId).includes(event.getRoomId())) {
            this._calculateRoomBadges(MatrixClientPeg.get().getRoom(event.getRoomId()));
        }
    };

    _calculateRoomBadges(room) {
        if (!room) return;

        const rooms = this.state.rooms.slice();
        const roomModel = rooms.find((r) => r.room.roomId === room.roomId);
        if (!roomModel) return; // No applicable room, so don't do math on it

        // Reset the notification variables for simplicity
        roomModel.redBadge = false;
        roomModel.formattedCount = "0";
        roomModel.showCount = false;

        const notifState = RoomNotifs.getRoomNotifsState(room.roomId);
        if (RoomNotifs.MENTION_BADGE_STATES.includes(notifState)) {
            const highlightNotifs = RoomNotifs.getUnreadNotificationCount(room, 'highlight');
            const unreadNotifs = RoomNotifs.getUnreadNotificationCount(room);

            const redBadge = highlightNotifs > 0;
            const greyBadge = redBadge || (unreadNotifs > 0 && RoomNotifs.BADGE_STATES.includes(notifState));

            if (redBadge || greyBadge) {
                const notifCount = redBadge ? highlightNotifs : unreadNotifs;
                const limitedCount = FormattingUtils.formatCount(notifCount);

                roomModel.redBadge = redBadge;
                roomModel.formattedCount = limitedCount;
                roomModel.showCount = true;
            }
        }

        this.setState({rooms});
    }

    _appendRoomId(roomId) {
        const room = MatrixClientPeg.get().getRoom(roomId);
        if (!room) {
            return;
        }
        const rooms = this.state.rooms.slice();
        const existingIdx = rooms.findIndex((r) => r.room.roomId === room.roomId);
        if (existingIdx !== -1) {
            rooms.splice(existingIdx, 1);
        }
        rooms.splice(0, 0, {room, animated: false});
        if (rooms.length > MAX_ROOMS) {
            rooms.splice(MAX_ROOMS, rooms.length - MAX_ROOMS);
        }
        this.setState({rooms});
    }

    _viewRoom(room, index) {
        Analytics.trackEvent("Breadcrumbs", "click_node", index);
        dis.dispatch({action: "view_room", room_id: room.roomId});
    }

    _onMouseEnter(room) {
        this._onHover(room);
    }

    _onMouseLeave(room) {
        this._onHover(null); // clear hover states
    }

    _onHover(room) {
        const rooms = this.state.rooms.slice();
        for (const r of rooms) {
            r.hover = room && r.room.roomId === room.roomId;
        }
        this.setState({rooms});
    }

    render() {
        const Tooltip = sdk.getComponent('elements.Tooltip');
        const IndicatorScrollbar = sdk.getComponent('structures.IndicatorScrollbar');

        // check for collapsed here and not at parent so we keep rooms in our state
        // when collapsing and expanding
        if (this.props.collapsed) {
            return null;
        }

        const rooms = this.state.rooms;
        const avatars = rooms.map((r, i) => {
            const isFirst = i === 0;
            const classes = classNames({
                "mx_RoomBreadcrumbs_crumb": true,
                "mx_RoomBreadcrumbs_preAnimate": isFirst && !r.animated,
                "mx_RoomBreadcrumbs_animate": isFirst,
                "mx_RoomBreadcrumbs_left": r.left,
            });

            let tooltip = null;
            if (r.hover) {
                tooltip = <Tooltip label={r.room.name} />;
            }

            let badge;
            if (r.showCount) {
                const badgeClasses = classNames({
                    'mx_RoomTile_badge': true,
                    'mx_RoomTile_badgeButton': true,
                    'mx_RoomTile_badgeRed': r.redBadge,
                    'mx_RoomTile_badgeUnread': !r.redBadge,
                });

                badge =
{r.formattedCount}
;
            }

            return (
                <AccessibleButton className={classes} key={r.room.roomId} onClick={() => this._viewRoom(r.room, i)}
                    onMouseEnter={() => this._onMouseEnter(r.room)} onMouseLeave={() => this._onMouseLeave(r.room)}>
                    <RoomAvatar room={r.room} width={32} height={32} />
                    {badge}
                    {tooltip}
                </AccessibleButton>
            );
        });
        return (
            <IndicatorScrollbar ref="scroller" className="mx_RoomBreadcrumbs" trackHorizontalOverflow={true}>
                { avatars }
            </IndicatorScrollbar>
        );
    }
}
<commit_msg>Move import to avoid future merge conflicts<commit_after>/*
Copyright 2019 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';
import React from "react";
import dis from "../../../dispatcher";
import MatrixClientPeg from "../../../MatrixClientPeg";
import AccessibleButton from '../elements/AccessibleButton';
import RoomAvatar from '../avatars/RoomAvatar';
import classNames from 'classnames';
import sdk from "../../../index";
import Analytics from "../../../Analytics";
import * as RoomNotifs from '../../../RoomNotifs';
import * as FormattingUtils from "../../../utils/FormattingUtils";

const MAX_ROOMS = 20;

export default class RoomBreadcrumbs extends React.Component {
    constructor(props) {
        super(props);
        this.state = {rooms: []};
        this.onAction = this.onAction.bind(this);
        this._dispatcherRef = null;
    }

    componentWillMount() {
        this._dispatcherRef = dis.register(this.onAction);

        const roomStr = localStorage.getItem("mx_breadcrumb_rooms");
        if (roomStr) {
            try {
                const roomIds = JSON.parse(roomStr);
                this.setState({
                    rooms: roomIds.map((r) => {
                        return {
                            room: MatrixClientPeg.get().getRoom(r),
                            animated: false,
                        };
                    }).filter((r) => r.room),
                });
            } catch (e) {
                console.error("Failed to parse breadcrumbs:", e);
            }
        }

        MatrixClientPeg.get().on("Room.myMembership", this.onMyMembership);
        MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt);
        MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
        MatrixClientPeg.get().on("Event.decrypted", this.onEventDecrypted);
    }

    componentWillUnmount() {
        dis.unregister(this._dispatcherRef);

        const client = MatrixClientPeg.get();
        if (client) {
            client.removeListener("Room.myMembership", this.onMyMembership);
            client.removeListener("Room.receipt", this.onRoomReceipt);
            client.removeListener("Room.timeline", this.onRoomTimeline);
            client.removeListener("Event.decrypted", this.onEventDecrypted);
        }
    }

    componentDidUpdate() {
        const rooms = this.state.rooms.slice();

        if (rooms.length) {
            const {room, animated} = rooms[0];
            if (!animated) {
                rooms[0] = {room, animated: true};
                setTimeout(() => this.setState({rooms}), 0);
            }
        }

        const roomStr = JSON.stringify(rooms.map((r) => r.room.roomId));
        localStorage.setItem("mx_breadcrumb_rooms", roomStr);
    }

    onAction(payload) {
        switch (payload.action) {
            case 'view_room':
                this._appendRoomId(payload.room_id);
                break;
        }
    }

    onMyMembership = (room, membership) => {
        if (membership === "leave" || membership === "ban") {
            const rooms = this.state.rooms.slice();
            const roomState = rooms.find((r) => r.room.roomId === room.roomId);
            if (roomState) {
                roomState.left = true;
                this.setState({rooms});
            }
        }
    };

    onRoomReceipt = (event, room) => {
        if (this.state.rooms.map(r => r.room.roomId).includes(room.roomId)) {
            this._calculateRoomBadges(room);
        }
    };

    onRoomTimeline = (event, room) => {
        if (this.state.rooms.map(r => r.room.roomId).includes(room.roomId)) {
            this._calculateRoomBadges(room);
        }
    };

    onEventDecrypted = (event) => {
        if (this.state.rooms.map(r => r.room.roomId).includes(event.getRoomId())) {
            this._calculateRoomBadges(MatrixClientPeg.get().getRoom(event.getRoomId()));
        }
    };

    _calculateRoomBadges(room) {
        if (!room) return;

        const rooms = this.state.rooms.slice();
        const roomModel = rooms.find((r) => r.room.roomId === room.roomId);
        if (!roomModel) return; // No applicable room, so don't do math on it

        // Reset the notification variables for simplicity
        roomModel.redBadge = false;
        roomModel.formattedCount = "0";
        roomModel.showCount = false;

        const notifState = RoomNotifs.getRoomNotifsState(room.roomId);
        if (RoomNotifs.MENTION_BADGE_STATES.includes(notifState)) {
            const highlightNotifs = RoomNotifs.getUnreadNotificationCount(room, 'highlight');
            const unreadNotifs = RoomNotifs.getUnreadNotificationCount(room);

            const redBadge = highlightNotifs > 0;
            const greyBadge = redBadge || (unreadNotifs > 0 && RoomNotifs.BADGE_STATES.includes(notifState));

            if (redBadge || greyBadge) {
                const notifCount = redBadge ? highlightNotifs : unreadNotifs;
                const limitedCount = FormattingUtils.formatCount(notifCount);

                roomModel.redBadge = redBadge;
                roomModel.formattedCount = limitedCount;
                roomModel.showCount = true;
            }
        }

        this.setState({rooms});
    }

    _appendRoomId(roomId) {
        const room = MatrixClientPeg.get().getRoom(roomId);
        if (!room) {
            return;
        }
        const rooms = this.state.rooms.slice();
        const existingIdx = rooms.findIndex((r) => r.room.roomId === room.roomId);
        if (existingIdx !== -1) {
            rooms.splice(existingIdx, 1);
        }
        rooms.splice(0, 0, {room, animated: false});
        if (rooms.length > MAX_ROOMS) {
            rooms.splice(MAX_ROOMS, rooms.length - MAX_ROOMS);
        }
        this.setState({rooms});
    }

    _viewRoom(room, index) {
        Analytics.trackEvent("Breadcrumbs", "click_node", index);
        dis.dispatch({action: "view_room", room_id: room.roomId});
    }

    _onMouseEnter(room) {
        this._onHover(room);
    }

    _onMouseLeave(room) {
        this._onHover(null); // clear hover states
    }

    _onHover(room) {
        const rooms = this.state.rooms.slice();
        for (const r of rooms) {
            r.hover = room && r.room.roomId === room.roomId;
        }
        this.setState({rooms});
    }

    render() {
        const Tooltip = sdk.getComponent('elements.Tooltip');
        const IndicatorScrollbar = sdk.getComponent('structures.IndicatorScrollbar');

        // check for collapsed here and not at parent so we keep rooms in our state
        // when collapsing and expanding
        if (this.props.collapsed) {
            return null;
        }

        const rooms = this.state.rooms;
        const avatars = rooms.map((r, i) => {
            const isFirst = i === 0;
            const classes = classNames({
                "mx_RoomBreadcrumbs_crumb": true,
                "mx_RoomBreadcrumbs_preAnimate": isFirst && !r.animated,
                "mx_RoomBreadcrumbs_animate": isFirst,
                "mx_RoomBreadcrumbs_left": r.left,
            });

            let tooltip = null;
            if (r.hover) {
                tooltip = <Tooltip label={r.room.name} />;
            }

            let badge;
            if (r.showCount) {
                const badgeClasses = classNames({
                    'mx_RoomTile_badge': true,
                    'mx_RoomTile_badgeButton': true,
                    'mx_RoomTile_badgeRed': r.redBadge,
                    'mx_RoomTile_badgeUnread': !r.redBadge,
                });

                badge =
{r.formattedCount}
;
            }

            return (
                <AccessibleButton className={classes} key={r.room.roomId} onClick={() => this._viewRoom(r.room, i)}
                    onMouseEnter={() => this._onMouseEnter(r.room)} onMouseLeave={() => this._onMouseLeave(r.room)}>
                    <RoomAvatar room={r.room} width={32} height={32} />
                    {badge}
                    {tooltip}
                </AccessibleButton>
            );
        });
        return (
            <IndicatorScrollbar ref="scroller" className="mx_RoomBreadcrumbs" trackHorizontalOverflow={true}>
                { avatars }
            </IndicatorScrollbar>
        );
    }
}
<|endoftext|>


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

/**
 * @fileoverview A table walker.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.TableWalker');

goog.require('sre.Focus');
goog.require('sre.Levels');
goog.require('sre.SyntaxWalker');
goog.require('sre.WalkerUtil');

/**
 * @constructor
 * @extends {sre.SyntaxWalker}
 * @override
 */
sre.TableWalker = function(node, generator, highlighter, xml) {
  sre.TableWalker.base(this, 'constructor', node, generator, highlighter, xml);

  /**
   * @type {boolean}
   */
  this.modifier = false;

};
goog.inherits(sre.TableWalker, sre.SyntaxWalker);

/**
 * @override
 */
sre.TableWalker.prototype.move = function(key) {
  var result = sre.TableWalker.base(this, 'move', key);
  this.modifier = false;
  return result;
};

/**
 * @override
 */
sre.TableWalker.prototype.up = function() {
  return this.eligibleCell_() ?
      this.verticalMove_(false) :
      sre.TableWalker.base(this, 'up');
};

/**
 * @override
 */
sre.TableWalker.prototype.down = function() {
  return this.eligibleCell_() ?
      this.verticalMove_(true) :
      sre.TableWalker.base(this, 'down');
};

/**
 * @return {boolean} True if the focused is an eligible table cell.
 * @private
 */
sre.TableWalker.prototype.eligibleCell_ = function() {
  var primary = this.getFocus().getSemanticPrimary();
  return this.modifier &&
      primary.type === sre.SemanticAttr.Type.CELL &&
      primary.role === sre.SemanticAttr.Role.TABLE;
};

/**
 * Performs a vertical move in a table.
 * @param {boolean} direction If true walk down, o/w up.
 * @return {?sre.Focus} The new focus.
 * @private
 */
sre.TableWalker.prototype.verticalMove_ = function(direction) {
  var parent = this.previousLevel();
  if (!parent) return null;
  var origFocus = this.getFocus();
  var origIndex = /** @type {number} */(
      this.levels.indexOf(this.primaryId()));
  var origLevel = this.levels.pop();
  var parentIndex = /** @type {number} */(
      this.levels.indexOf(parent));
  var row = /** @type {string} */(this.levels.get(
      direction ? parentIndex + 1 : parentIndex - 1));
  if (!row) {
    this.levels.push(origLevel);
    return null;
  }
  this.setFocus(this.singletonFocus(row));
  var children = this.nextLevel();
  var newNode = children[origIndex];
  if (!newNode) {
    this.setFocus(origFocus);
    this.levels.push(origLevel);
    return null;
  }
  this.levels.push(children);
  return this.singletonFocus(children[origIndex]);
};
<commit_msg>Extends table walker to all table-like structures.<commit_after>// Copyright 2015 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview A table walker.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.TableWalker');

goog.require('sre.Focus');
goog.require('sre.Levels');
goog.require('sre.SyntaxWalker');
goog.require('sre.WalkerUtil');

/**
 * @constructor
 * @extends {sre.SyntaxWalker}
 * @override
 */
sre.TableWalker = function(node, generator, highlighter, xml) {
  sre.TableWalker.base(this, 'constructor', node, generator, highlighter, xml);

  /**
   * @type {boolean}
   */
  this.modifier = false;

};
goog.inherits(sre.TableWalker, sre.SyntaxWalker);

/**
 * @override
 */
sre.TableWalker.prototype.move = function(key) {
  var result = sre.TableWalker.base(this, 'move', key);
  this.modifier = false;
  return result;
};

/**
 * @override
 */
sre.TableWalker.prototype.up = function() {
  return this.eligibleCell_() ?
      this.verticalMove_(false) :
      sre.TableWalker.base(this, 'up');
};

/**
 * @override
 */
sre.TableWalker.prototype.down = function() {
  return this.eligibleCell_() ?
      this.verticalMove_(true) :
      sre.TableWalker.base(this, 'down');
};

/**
 * @type {Array.<sre.SemanticAttr.Role>}
 */
sre.TableWalker.ELIGIBLE_CELL_ROLES = [
  sre.SemanticAttr.Role.DETERMINANT,
  sre.SemanticAttr.Role.ROWVECTOR,
  sre.SemanticAttr.Role.BINOMIAL,
  sre.SemanticAttr.Role.SQUAREMATRIX,
  sre.SemanticAttr.Role.MULTILINE,
  sre.SemanticAttr.Role.MATRIX,
  sre.SemanticAttr.Role.VECTOR,
  sre.SemanticAttr.Role.CASES,
  sre.SemanticAttr.Role.TABLE
];

/**
 * @return {boolean} True if the focused is an eligible table cell.
 * @private
 */
sre.TableWalker.prototype.eligibleCell_ = function() {
  var primary = this.getFocus().getSemanticPrimary();
  return this.modifier &&
        primary.type === sre.SemanticAttr.Type.CELL &&
    sre.TableWalker.ELIGIBLE_CELL_ROLES.indexOf(primary.role) !== -1;
};

/**
 * Performs a vertical move in a table.
 * @param {boolean} direction If true walk down, o/w up.
 * @return {?sre.Focus} The new focus.
 * @private
 */
sre.TableWalker.prototype.verticalMove_ = function(direction) {
  var parent = this.previousLevel();
  if (!parent) return null;
  var origFocus = this.getFocus();
  var origIndex = /** @type {number} */(
      this.levels.indexOf(this.primaryId()));
  var origLevel = this.levels.pop();
  var parentIndex = /** @type {number} */(
      this.levels.indexOf(parent));
  var row = /** @type {string} */(this.levels.get(
      direction ? parentIndex + 1 : parentIndex - 1));
  if (!row) {
    this.levels.push(origLevel);
    return null;
  }
  this.setFocus(this.singletonFocus(row));
  var children = this.nextLevel();
  var newNode = children[origIndex];
  if (!newNode) {
    this.setFocus(origFocus);
    this.levels.push(origLevel);
    return null;
  }
  this.levels.push(children);
  return this.singletonFocus(children[origIndex]);
};
<|endoftext|>


<commit_before>/**
 * Base class for input widgets.
 *
 * @abstract
 * @class
 * @extends OO.ui.Widget
 * @mixins OO.ui.FlaggedElement
 * @mixins OO.ui.TabIndexedElement
 *
 * @constructor
 * @param {Object} [config] Configuration options
 * @cfg {string} [name=''] HTML input name
 * @cfg {string} [value=''] Input value
 * @cfg {Function} [inputFilter] Filter function to apply to the input. Takes a string argument and returns a string.
 */
OO.ui.InputWidget = function OoUiInputWidget( config ) {
	// Configuration initialization
	config = config || {};

	// Parent constructor
	OO.ui.InputWidget.super.call( this, config );

	// Properties
	this.$input = this.getInputElement( config );
	this.value = '';
	this.inputFilter = config.inputFilter;

	// Mixin constructors
	OO.ui.FlaggedElement.call( this, config );
	OO.ui.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );

	// Events
	this.$input.on( 'keydown mouseup cut paste change input select', this.onEdit.bind( this ) );

	// Initialization
	this.$input
		.attr( 'name', config.name )
		.prop( 'disabled', this.isDisabled() );
	this.$element.addClass( 'oo-ui-inputWidget' ).append( this.$input, $( '<span>' ) );
	this.setValue( config.value );
};

/* Setup */

OO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );
OO.mixinClass( OO.ui.InputWidget, OO.ui.FlaggedElement );
OO.mixinClass( OO.ui.InputWidget, OO.ui.TabIndexedElement );

/* Events */

/**
 * @event change
 * @param {string} value
 */

/* Methods */

/**
 * Get input element.
 *
 * Subclasses of OO.ui.InputWidget use the `config` parameter to produce different elements in
 * different circumstances. The element must have a `value` property (like form elements).
 *
 * @private
 * @param {Object} config Configuration options
 * @return {jQuery} Input element
 */
OO.ui.InputWidget.prototype.getInputElement = function () {
	return $( '<input>' );
};

/**
 * Handle potentially value-changing events.
 *
 * @param {jQuery.Event} e Key down, mouse up, cut, paste, change, input, or select event
 */
OO.ui.InputWidget.prototype.onEdit = function () {
	var widget = this;
	if ( !this.isDisabled() ) {
		// Allow the stack to clear so the value will be updated
		setTimeout( function () {
			widget.setValue( widget.$input.val() );
		} );
	}
};

/**
 * Get the value of the input.
 *
 * @return {string} Input value
 */
OO.ui.InputWidget.prototype.getValue = function () {
	// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
	// it, and we won't know unless they're kind enough to trigger a 'change' event.
	var value = this.$input.val();
	if ( this.value !== value ) {
		this.setValue( value );
	}
	return this.value;
};

/**
 * Sets the direction of the current input, either RTL or LTR
 *
 * @param {boolean} isRTL
 */
OO.ui.InputWidget.prototype.setRTL = function ( isRTL ) {
	this.$input.prop( 'dir', isRTL ? 'rtl' : 'ltr' );
};

/**
 * Set the value of the input.
 *
 * @param {string} value New value
 * @fires change
 * @chainable
 */
OO.ui.InputWidget.prototype.setValue = function ( value ) {
	value = this.cleanUpValue( value );
	// Update the DOM if it has changed. Note that with cleanUpValue, it
	// is possible for the DOM value to change without this.value changing.
	if ( this.$input.val() !== value ) {
		this.$input.val( value );
	}
	if ( this.value !== value ) {
		this.value = value;
		this.emit( 'change', this.value );
	}
	return this;
};

/**
 * Clean up incoming value.
 *
 * Ensures value is a string, and converts undefined and null to empty string.
 *
 * @private
 * @param {string} value Original value
 * @return {string} Cleaned up value
 */
OO.ui.InputWidget.prototype.cleanUpValue = function ( value ) {
	if ( value === undefined || value === null ) {
		return '';
	} else if ( this.inputFilter ) {
		return this.inputFilter( String( value ) );
	} else {
		return String( value );
	}
};

/**
 * Simulate the behavior of clicking on a label bound to this input.
 */
OO.ui.InputWidget.prototype.simulateLabelClick = function () {
	if ( !this.isDisabled() ) {
		if ( this.$input.is( ':checkbox,:radio' ) ) {
			this.$input.click();
		} else if ( this.$input.is( ':input' ) ) {
			this.$input[ 0 ].focus();
		}
	}
};

/**
 * @inheritdoc
 */
OO.ui.InputWidget.prototype.setDisabled = function ( state ) {
	OO.ui.InputWidget.super.prototype.setDisabled.call( this, state );
	if ( this.$input ) {
		this.$input.prop( 'disabled', this.isDisabled() );
	}
	return this;
};

/**
 * Focus the input.
 *
 * @chainable
 */
OO.ui.InputWidget.prototype.focus = function () {
	this.$input[ 0 ].focus();
	return this;
};

/**
 * Blur the input.
 *
 * @chainable
 */
OO.ui.InputWidget.prototype.blur = function () {
	this.$input[ 0 ].blur();
	return this;
};
<commit_msg>InputWidget: Add description<commit_after>/**
 * InputWidget is the base class for all input widgets, which
 * include {@link OO.ui.TextInputWidget text inputs}, {@link OO.ui.CheckboxInputWidget checkbox inputs},
 * {@link OO.ui.RadioInputWidget radio inputs}, and {@link OO.ui.ButtonInputWidget button inputs}.
 * See the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
 *
 * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
 *
 * @abstract
 * @class
 * @extends OO.ui.Widget
 * @mixins OO.ui.FlaggedElement
 * @mixins OO.ui.TabIndexedElement
 *
 * @constructor
 * @param {Object} [config] Configuration options
 * @cfg {string} [name=''] HTML input name
 * @cfg {string} [value=''] Input value
 * @cfg {Function} [inputFilter] Filter function to apply to the input. Takes a string argument and returns a string.
 */
OO.ui.InputWidget = function OoUiInputWidget( config ) {
	// Configuration initialization
	config = config || {};

	// Parent constructor
	OO.ui.InputWidget.super.call( this, config );

	// Properties
	this.$input = this.getInputElement( config );
	this.value = '';
	this.inputFilter = config.inputFilter;

	// Mixin constructors
	OO.ui.FlaggedElement.call( this, config );
	OO.ui.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );

	// Events
	this.$input.on( 'keydown mouseup cut paste change input select', this.onEdit.bind( this ) );

	// Initialization
	this.$input
		.attr( 'name', config.name )
		.prop( 'disabled', this.isDisabled() );
	this.$element.addClass( 'oo-ui-inputWidget' ).append( this.$input, $( '<span>' ) );
	this.setValue( config.value );
};

/* Setup */

OO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );
OO.mixinClass( OO.ui.InputWidget, OO.ui.FlaggedElement );
OO.mixinClass( OO.ui.InputWidget, OO.ui.TabIndexedElement );

/* Events */

/**
 * @event change
 * @param {string} value
 */

/* Methods */

/**
 * Get input element.
 *
 * Subclasses of OO.ui.InputWidget use the `config` parameter to produce different elements in
 * different circumstances. The element must have a `value` property (like form elements).
 *
 * @private
 * @param {Object} config Configuration options
 * @return {jQuery} Input element
 */
OO.ui.InputWidget.prototype.getInputElement = function () {
	return $( '<input>' );
};

/**
 * Handle potentially value-changing events.
 *
 * @param {jQuery.Event} e Key down, mouse up, cut, paste, change, input, or select event
 */
OO.ui.InputWidget.prototype.onEdit = function () {
	var widget = this;
	if ( !this.isDisabled() ) {
		// Allow the stack to clear so the value will be updated
		setTimeout( function () {
			widget.setValue( widget.$input.val() );
		} );
	}
};

/**
 * Get the value of the input.
 *
 * @return {string} Input value
 */
OO.ui.InputWidget.prototype.getValue = function () {
	// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
	// it, and we won't know unless they're kind enough to trigger a 'change' event.
	var value = this.$input.val();
	if ( this.value !== value ) {
		this.setValue( value );
	}
	return this.value;
};

/**
 * Sets the direction of the current input, either RTL or LTR
 *
 * @param {boolean} isRTL
 */
OO.ui.InputWidget.prototype.setRTL = function ( isRTL ) {
	this.$input.prop( 'dir', isRTL ? 'rtl' : 'ltr' );
};

/**
 * Set the value of the input.
 *
 * @param {string} value New value
 * @fires change
 * @chainable
 */
OO.ui.InputWidget.prototype.setValue = function ( value ) {
	value = this.cleanUpValue( value );
	// Update the DOM if it has changed. Note that with cleanUpValue, it
	// is possible for the DOM value to change without this.value changing.
	if ( this.$input.val() !== value ) {
		this.$input.val( value );
	}
	if ( this.value !== value ) {
		this.value = value;
		this.emit( 'change', this.value );
	}
	return this;
};

/**
 * Clean up incoming value.
 *
 * Ensures value is a string, and converts undefined and null to empty string.
 *
 * @private
 * @param {string} value Original value
 * @return {string} Cleaned up value
 */
OO.ui.InputWidget.prototype.cleanUpValue = function ( value ) {
	if ( value === undefined || value === null ) {
		return '';
	} else if ( this.inputFilter ) {
		return this.inputFilter( String( value ) );
	} else {
		return String( value );
	}
};

/**
 * Simulate the behavior of clicking on a label bound to this input.
 */
OO.ui.InputWidget.prototype.simulateLabelClick = function () {
	if ( !this.isDisabled() ) {
		if ( this.$input.is( ':checkbox,:radio' ) ) {
			this.$input.click();
		} else if ( this.$input.is( ':input' ) ) {
			this.$input[ 0 ].focus();
		}
	}
};

/**
 * @inheritdoc
 */
OO.ui.InputWidget.prototype.setDisabled = function ( state ) {
	OO.ui.InputWidget.super.prototype.setDisabled.call( this, state );
	if ( this.$input ) {
		this.$input.prop( 'disabled', this.isDisabled() );
	}
	return this;
};

/**
 * Focus the input.
 *
 * @chainable
 */
OO.ui.InputWidget.prototype.focus = function () {
	this.$input[ 0 ].focus();
	return this;
};

/**
 * Blur the input.
 *
 * @chainable
 */
OO.ui.InputWidget.prototype.blur = function () {
	this.$input[ 0 ].blur();
	return this;
};
<|endoftext|>


<commit_before>$(document).ready(function () {

	// standard global variables
	var container, scene, camera, renderer, controls, stats;
	var clock = new THREE.Clock();

	var historique, cameras,
	CAMERA_SPEED = 2,
	CAMERA_TARGET = new THREE.Vector3();

	// custom global variables
	var cube;
	var cubeGeo;
	var squareTexture;
	var squareMaterial;

	// grid
	var GRID_SIZE = 5;
	var GRID_X = 160;
	var GRID_Y = 140;

	// maskData
	var MASK_THRESHOLD = 1,
		maskImage,
		maskData = _([]);

	function validMask(x, y) {
		return maskData.find({x: x, y: y}) != undefined;
	}

	function init() {

		var	maskCanvas = $('canvas.mask').get(0),
			maskContext = maskCanvas.getContext('2d');
		maskContext.drawImage(maskImage, 0, 0, maskImage.width, maskImage.height);
		var pixels = maskContext.getImageData(0, 0, maskImage.width, maskImage.height);
		for (var i = 0; i < pixels.data.length; i += 4) {
			// 4 because using only RED channel to test
			var n = i / 4,
				x = n % pixels.width,
				y = Math.floor(n / pixels.width);
			if (pixels.data[i] > MASK_THRESHOLD) {
				maskData.push({
					x: x,
					y: y
				})
			}
		}
		maskCanvas.remove();
		maskImage.remove();

		// SCENE
		scene = new THREE.Scene();
		// CAMERA
		var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
		var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
		camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
		scene.add(camera);
		camera.position.set(0, 150, 400);
		camera.lookAt(scene.position);
		// RENDERER
		if (Detector.webgl)
			renderer = new THREE.WebGLRenderer({antialias: true});
		else
			renderer = new THREE.CanvasRenderer();
		renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
		container = document.getElementById('ThreeJS');
		container.appendChild(renderer.domElement);
		// EVENTS
		THREEx.WindowResize(renderer, camera);
		THREEx.FullScreen.bindKey({charCode: 'm'.charCodeAt(0)});
		// CONTROLS
		controls = new THREE.OrbitControls(camera, renderer.domElement);
		// STATS
		stats = new Stats();
		stats.domElement.style.position = 'absolute';
		stats.domElement.style.bottom = '0px';
		stats.domElement.style.zIndex = 100;
		container.appendChild(stats.domElement);
		// LIGHT
		var light = new THREE.PointLight(0xffffff);
		light.position.set(0, 250, 0);
		scene.add(light);
		// FLOOR
		var floorTexture = new THREE.ImageUtils.loadTexture('checkerboard.jpg');
		floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
		floorTexture.repeat.set(GRID_X, GRID_Y);
		var floorMaterial = new THREE.MeshBasicMaterial({map: floorTexture, side: THREE.DoubleSide});
		var floorGeometry = new THREE.PlaneGeometry(GRID_SIZE * GRID_X, GRID_SIZE * GRID_Y, 10, 10);
		var floor = new THREE.Mesh(floorGeometry, floorMaterial);
		floor.position.y = 0;
		floor.rotation.x = Math.PI / 2;
		scene.add(floor);
		// SKYBOX/FOG
		var skyBoxGeometry = new THREE.CubeGeometry(10000, 10000, 10000);
		var skyBoxMaterial = new THREE.MeshBasicMaterial({color: 0x9999ff, side: THREE.BackSide});
		var skyBox = new THREE.Mesh(skyBoxGeometry, skyBoxMaterial);
		// scene.add(skyBox);
		scene.fog = new THREE.FogExp2(0x9999ff, 0.00025);

		////////////
		// CUSTOM //
		////////////

		cubeGeo = new THREE.CubeGeometry(1, 1, 1);
		squareTexture = new THREE.ImageUtils.loadTexture("square-thick.png");
		squareMaterial = new THREE.MeshBasicMaterial({map: squareTexture, color: 0xffffff});

	}

	function setupCubes(){
		clock = new THREE.Clock();
		//camera.position.x = cameras[0].x;
		//camera.position.z = cameras[0].y;

		for (var x = 0; x < GRID_X; x++) {
			for (var y = 0; y < GRID_Y; y++) {
				if (validMask(x, y)) {
					var h = _(historique).find({x: x, y: y});//Math.ceil(Math.random() * 5);
					if (_.isUndefined(h)) {
						h = 0;
					} else {
						h = h.z;
					}
					if (h > 5) {
						h = 5;
					}
					h = 5-h;
					for (var z = 0; z < h; z++) {
						cube = new THREE.Mesh(cubeGeo);
						cube.material = squareMaterial;
						// TODO
						cube.position.x = x * GRID_SIZE - GRID_SIZE * GRID_X / 2 - GRID_SIZE / 2;
						cube.position.z = y * GRID_SIZE - GRID_SIZE * GRID_Y / 2 - GRID_SIZE / 2;
						cube.position.y = GRID_SIZE * z + GRID_SIZE / 2;
						cube.scale = {x: GRID_SIZE, y: GRID_SIZE, z: GRID_SIZE};
						cube.name = "cube_" + x + "_" + y + "_" + z;
						scene.add(cube);
					}

				}
			}
		}
	}

	function animate() {

		/*
		var d = clock.getElapsedTime()/10,
			d1 = d+1;

		var target = new THREE.Vector3(
			(Math.cos(d*Math.PI)*GRID_X/4)*GRID_SIZE,
			5,
			(Math.sin(d * Math.PI) * GRID_Y / 4) * GRID_SIZE
		);

		var eye = new THREE.Vector3(
			(Math.cos(d1 * Math.PI) * GRID_X / 2) * GRID_SIZE,
			((Math.cos(d * Math.PI)+1) *.5 * 20 + 10 )* GRID_SIZE,
			(Math.sin(d1 * Math.PI) * GRID_Y / 2) * GRID_SIZE
		);
		camera.position.x = eye.x;
		camera.position.z = eye.z;
		camera.position.y = eye.y;
		camera.lookAt(target);
		console.log(target.x);

		/*/

		if(cameras){
		 //*/
			var d = clock.getElapsedTime(),
				//n = ( d* CAMERA_SPEED)% 1,
				n0 = Math.round(d * CAMERA_SPEED) % cameras.length,
				n1 = Math.round((d+1) * CAMERA_SPEED) % cameras.length,
				p0 = cameras[n0],
				p1 = cameras[n1];

			/*
			camera.position.x = p0.x;
			camera.position.z = p0.y;
			camera.position.y = 5.6 * GRID_SIZE;

			CAMERA_TARGET.x = p1.x;
			CAMERA_TARGET.z = p1.y;
			CAMERA_TARGET.y = 5.4 * GRID_SIZE;

			/*/
			camera.position.x = p0.x*.01 + camera.position.x*.99;
			camera.position.z = p0.y * .01 + camera.position.z * .99;
			camera.position.y = 4.3*GRID_SIZE;

			CAMERA_TARGET.x = p1.x * .01 + CAMERA_TARGET.x * .99;
			CAMERA_TARGET.z = p1.y * .01 + CAMERA_TARGET.z * .99;
			CAMERA_TARGET.y = 4*GRID_SIZE;
			//*/

			//camera.lookAt(CAMERA_TARGET);
		//
		}
		requestAnimationFrame(animate);
		render();
		update();
	}

	function update() {
		controls.update();
		stats.update();
	}

	function render() {
		renderer.render(scene, camera);
	}

	maskImage = new Image();
	$(maskImage).on('load',function(){

		console.log("maskImage loaded");
		var historiqueAjax = $.ajax({
			url: 'historique.json',
			datatype: 'json',
			success: function (data) {
				console.log("historique loaded");
				historique = data;
			}
		});
		var camerasAjax = $.ajax({
			url: 'cameras.json',
			datatype: 'json',
			success: function (data) {
				console.log("cameras loaded");
				cameras = data;
			}
		});

		$.when(historiqueAjax, camerasAjax).done(function () {
			setupCubes();
		});

		init();
		animate();
	});
	maskImage.src = "masque.png";

});
<commit_msg>bug ImageMask loading<commit_after>$(document).ready(function () {

	// standard global variables
	var container, scene, camera, renderer, controls, stats;
	var clock = new THREE.Clock();

	var historique, cameras,
	CAMERA_SPEED = 2,
	CAMERA_TARGET = new THREE.Vector3();

	// custom global variables
	var cube;
	var cubeGeo;
	var squareTexture;
	var squareMaterial;

	// grid
	var GRID_SIZE = 5;
	var GRID_X = 160;
	var GRID_Y = 140;

	// maskData
	var MASK_THRESHOLD = 1,
		maskImage,
		maskData = _([]);

	function validMask(x, y) {
		return maskData.find({x: x, y: y}) != undefined;
	}

	function init() {

		var	maskCanvas = $('canvas.mask').get(0),
			maskContext = maskCanvas.getContext('2d');
		maskContext.drawImage(maskImage, 0, 0, maskImage.width, maskImage.height);
		var pixels = maskContext.getImageData(0, 0, maskImage.width, maskImage.height);
		for (var i = 0; i < pixels.data.length; i += 4) {
			// 4 because using only RED channel to test
			var n = i / 4,
				x = n % pixels.width,
				y = Math.floor(n / pixels.width);
			if (pixels.data[i] > MASK_THRESHOLD) {
				maskData.push({
					x: x,
					y: y
				})
			}
		}
		maskCanvas.remove();
		maskImage.remove();

		// SCENE
		scene = new THREE.Scene();
		// CAMERA
		var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
		var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
		camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
		scene.add(camera);
		camera.position.set(0, 150, 400);
		camera.lookAt(scene.position);
		// RENDERER
		if (Detector.webgl)
			renderer = new THREE.WebGLRenderer({antialias: true});
		else
			renderer = new THREE.CanvasRenderer();
		renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
		container = document.getElementById('ThreeJS');
		container.appendChild(renderer.domElement);
		// EVENTS
		THREEx.WindowResize(renderer, camera);
		THREEx.FullScreen.bindKey({charCode: 'm'.charCodeAt(0)});
		// CONTROLS
		controls = new THREE.OrbitControls(camera, renderer.domElement);
		// STATS
		stats = new Stats();
		stats.domElement.style.position = 'absolute';
		stats.domElement.style.bottom = '0px';
		stats.domElement.style.zIndex = 100;
		container.appendChild(stats.domElement);
		// LIGHT
		var light = new THREE.PointLight(0xffffff);
		light.position.set(0, 250, 0);
		scene.add(light);
		// FLOOR
		var floorTexture = new THREE.ImageUtils.loadTexture('checkerboard.jpg');
		floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
		floorTexture.repeat.set(GRID_X, GRID_Y);
		var floorMaterial = new THREE.MeshBasicMaterial({map: floorTexture, side: THREE.DoubleSide});
		var floorGeometry = new THREE.PlaneGeometry(GRID_SIZE * GRID_X, GRID_SIZE * GRID_Y, 10, 10);
		var floor = new THREE.Mesh(floorGeometry, floorMaterial);
		floor.position.y = 0;
		floor.rotation.x = Math.PI / 2;
		scene.add(floor);
		// SKYBOX/FOG
		var skyBoxGeometry = new THREE.CubeGeometry(10000, 10000, 10000);
		var skyBoxMaterial = new THREE.MeshBasicMaterial({color: 0x9999ff, side: THREE.BackSide});
		var skyBox = new THREE.Mesh(skyBoxGeometry, skyBoxMaterial);
		// scene.add(skyBox);
		scene.fog = new THREE.FogExp2(0x9999ff, 0.00025);

		////////////
		// CUSTOM //
		////////////

		cubeGeo = new THREE.CubeGeometry(1, 1, 1);
		squareTexture = new THREE.ImageUtils.loadTexture("square-thick.png");
		squareMaterial = new THREE.MeshBasicMaterial({map: squareTexture, color: 0xffffff});

	}

	function setupCubes(){
		clock = new THREE.Clock();
		//camera.position.x = cameras[0].x;
		//camera.position.z = cameras[0].y;

		for (var x = 0; x < GRID_X; x++) {
			for (var y = 0; y < GRID_Y; y++) {
				if (validMask(x, y)) {
					var h = _(historique).find({x: x, y: y});//Math.ceil(Math.random() * 5);
					if (_.isUndefined(h)) {
						h = 0;
					} else {
						h = h.z;
					}
					if (h > 5) {
						h = 5;
					}
					h = 5-h;
					for (var z = 0; z < h; z++) {
						cube = new THREE.Mesh(cubeGeo);
						cube.material = squareMaterial;
						// TODO
						cube.position.x = x * GRID_SIZE - GRID_SIZE * GRID_X / 2 - GRID_SIZE / 2;
						cube.position.z = y * GRID_SIZE - GRID_SIZE * GRID_Y / 2 - GRID_SIZE / 2;
						cube.position.y = GRID_SIZE * z + GRID_SIZE / 2;
						cube.scale = {x: GRID_SIZE, y: GRID_SIZE, z: GRID_SIZE};
						cube.name = "cube_" + x + "_" + y + "_" + z;
						scene.add(cube);
					}

				}
			}
		}
	}

	function animate() {

		/*
		var d = clock.getElapsedTime()/10,
			d1 = d+1;

		var target = new THREE.Vector3(
			(Math.cos(d*Math.PI)*GRID_X/4)*GRID_SIZE,
			5,
			(Math.sin(d * Math.PI) * GRID_Y / 4) * GRID_SIZE
		);

		var eye = new THREE.Vector3(
			(Math.cos(d1 * Math.PI) * GRID_X / 2) * GRID_SIZE,
			((Math.cos(d * Math.PI)+1) *.5 * 20 + 10 )* GRID_SIZE,
			(Math.sin(d1 * Math.PI) * GRID_Y / 2) * GRID_SIZE
		);
		camera.position.x = eye.x;
		camera.position.z = eye.z;
		camera.position.y = eye.y;
		camera.lookAt(target);
		console.log(target.x);

		/*/

		if(cameras){
		 //*/
			//camera speed
			var d = clock.getElapsedTime()*4,
				//n = ( d* CAMERA_SPEED)% 1,
				n0 = Math.round(d * CAMERA_SPEED) % cameras.length,
				n1 = Math.round((d+1) * CAMERA_SPEED) % cameras.length,
				p0 = cameras[n0],
				p1 = cameras[n1];

			/*
			camera.position.x = p0.x;
			camera.position.z = p0.y;
			camera.position.y = 5.6 * GRID_SIZE;

			CAMERA_TARGET.x = p1.x;
			CAMERA_TARGET.z = p1.y;
			CAMERA_TARGET.y = 5.4 * GRID_SIZE;

			/*/
			camera.position.x = p0.x*.01 + camera.position.x*.99;
			camera.position.z = p0.y * .01 + camera.position.z * .99;
			camera.position.y = 4.3*GRID_SIZE;

			CAMERA_TARGET.x = p1.x * .01 + CAMERA_TARGET.x * .99;
			CAMERA_TARGET.z = p1.y * .01 + CAMERA_TARGET.z * .99;
			CAMERA_TARGET.y = 4*GRID_SIZE;
			//*/

			//camera.lookAt(CAMERA_TARGET);
		//
		}
		requestAnimationFrame(animate);
		render();
		update();
	}

	function update() {
		controls.update();
		stats.update();
	}

	function render() {
		renderer.render(scene, camera);
	}

	maskImage = new Image();
	$(maskImage).on('load',function(){

		console.log("maskImage loaded");
		var historiqueAjax = $.ajax({
			url: 'historique.json',
			datatype: 'json',
			success: function (data) {
				console.log("historique loaded");
				historique = data;
			}
		});
		var camerasAjax = $.ajax({
			url: 'cameras.json',
			datatype: 'json',
			success: function (data) {
				console.log("cameras loaded");
				cameras = data;
			}
		});

		$.when(historiqueAjax, camerasAjax).done(function () {
			setupCubes();
		});

		init();
		animate();
	});
	maskImage.src = "masque.png";

});
<|endoftext|>


<commit_before>var {defineSupportCode} = require('cucumber');

defineSupportCode(function({Given, When, Then, setWorldConstructor}) {
  setWorldConstructor(require('../support/World').World);

  Given('I am ready to test all this (covered by ready.spec.js)', function (callback) {
    // Write code here that turns the phrase above into concrete actions
    callback(null, 'pending');
  });

  //this.Given(/^I (?:am on|go to) the "([^"]*)" page$/, function(pageName) {
  //  if (this.pageObjectMap[pageName] == null) {
  //    throw new Error("Could not find page with name '" + pageName + "' in the PageObjectMap, did you remember to add it?");
  //  }
  //  this.currentPage = new this.pageObjectMap[pageName];
  //  this.currentPage.get();
  //  return this.currentPage.waitForLoaded();
  //});
  //this.Given(/^I (?:have|change to|resize to|rotate to) a (\d+)x(\d+) screen size$/, function(width, height) {
  //  return browser.manage().window().setSize(parseInt(width, 10), parseInt(height, 10));
  //});
  //this.When(/^I (?:navigate|click) (?:backwards|back) in my browser$/, function() {
  //  return browser.navigate().back();
  //});
  //this.When(/^I type "([^"]*)" in(?:to)? the "([^"]*)" field$/, function(text, fieldName) {
  //  var field;
  //  field = this.transform.stringToVariableName(fieldName + 'Field');
  //  this.currentPage[field].clear();
  //  return this.currentPage[field].sendKeys(text);
  //});
  //this.When(/^I click the "([^"]*)"(?: )?(link|button|drop down list|tab|)$/, function(elementName, elementType) {
  //  var element;
  //  elementType = this.transform.elementTypeToVariableName(elementType);
  //  element = this.transform.stringToVariableName(elementName + elementType);
  //  return this.currentPage[element].click();
  //});
  //this.When(/^I refresh the page$/, function() {
  //  return browser.refresh();
  //});
  //this.When(/^I select "([^"]*)" in the "([^"]*)" drop down list$/, function(optionText, list) {
  //  return this.currentPage[this.transform.stringToVariableName(list + 'Select')].element(protractor.By.cssContainingText('option', optionText)).click();
  //});
  //this.Then(/^the title should equal "([^"]*)"$/, function(text) {
  //  return this.expect(browser.getTitle()).to.eventually.equal(text);
  //});
  //this.Then(/^the "([^"]*)" (should|should not) be active$/, function(tabName, expectation) {
  //  this.tabName = this.transform.stringToVariableName(tabName);
  //  this.expectation = this.transform.shouldToBoolean(expectation);
  //  return this.expect(this.elementHelper.hasClass(this.currentPage[this.tabName], 'active')).to.eventually.equal(this.expectation);
  //});
  //this.Then(/^the "([^"]*)" should be present$/, function(el) {
  //  this.el = this.transform.stringToVariableName(el);
  //  return this.expect(this.currentPage[this.el].isPresent()).to.eventually.equal(true);
  //});
  //this.Then(/^I (?:should be on|reach|am taken to) the "([^"]*)" page$/, function(pageName) {
  //  this.currentPage = new this.pageObjectMap[pageName];
  //  return this.currentPage.waitForLoaded();
  //});
  //this.Then(/^(?:the )?"([^"]*)" should (?:have|contain) the text "([^"]*)"$/, function(el, text) {
  //  var elText;
  //  this.el = this.currentPage[this.transform.stringToVariableName(el)];
  //  elText = this.el.getTagName().then((function(_this) {
  //    return function(tagName) {
  //      var isInput;
  //      isInput = tagName === "input";
  //      if (isInput) {
  //        return _this.el.getAttribute('value');
  //      } else {
  //        return _this.el.getText();
  //      }
  //    };
  //  })(this));
  //  return this.expect(elText).to.eventually.contain(text);
  //});
  //this.Then(/^"([^"]*)" should appear in the "([^"]*)" drop down list$/, function(option, list) {
  //  var optionsText;
  //  this.list = this.currentPage[this.transform.stringToVariableName(list + 'Select')];
  //  optionsText = this.list.all(By.tagName('option')).map(function(element, index) {
  //    return element.getText();
  //  });
  //  return this.expect(optionsText).to.eventually.contain(option);
  //});
  //this.Then(/^the "([^"]*)" (should|should not) be displayed$/, function(el, shouldBeDisplayed) {
  //  var isDisplayed;
  //  this.shouldBeDisplayed = this.transform.shouldToBoolean(shouldBeDisplayed);
  //  this.el = this.transform.stringToVariableName(el);
  //  return isDisplayed = this.currentPage[this.el].isDisplayed().then((function(_this) {
  //    return function(isDisplayed) {
  //      return _this.expect(isDisplayed).to.equal(_this.shouldBeDisplayed);
  //    };
  //  })(this), (function(_this) {
  //    return function(err) {
  //      if (err.name === 'NoSuchElementError') {
  //        return _this.expect(false).to.equal(_this.shouldBeDisplayed);
  //      }
  //      throw err;
  //    };
  //  })(this));
  //});
  //this.Then(/^(?:the )?"([^"]*)" should (?:have|contain) the placeholder text "([^"]*)"$/, function(el, text) {
  //  this.el = this.currentPage[this.transform.stringToVariableName(el)];
  //  return this.expect(this.el.getAttribute('placeholder')).to.eventually.contain(text);
  //});
  //this.Then(/^the "([^"]*)"(?: )?(button|field|drop down list|) (should|should not) be enabled$/, function(el, elType, expectation) {
  //  var elementType;
  //  elementType = this.transform.elementTypeToVariableName(elType);
  //  this.el = this.transform.stringToVariableName(el + elementType);
  //  this.expectation = this.transform.shouldToBoolean(expectation);
  //  return this.expect(this.currentPage[this.el].isEnabled()).to.eventually.equal(this.expectation);
  //});
  //this.Then(/^"([^"]*)" should be (?:selected|displayed) in the "([^"]*)" drop down list$/, function(optionText, list) {
  //  var option;
  //  this.list = this.currentPage[this.transform.stringToVariableName(list + 'Select')];
  //  option = this.list.element(By.cssContainingText('option', optionText));
  //  return this.expect(option.isSelected()).to.eventually.be["true"];
  //});
  //return this.Then(/^the "([^"]*)"(?: )?(checkbox|) (should|should not) be checked$/, function(el, elType, expectation) {
  //  var elementType;
  //  elementType = this.transform.elementTypeToVariableName(elType);
  //  this.el = this.transform.stringToVariableName(el + elementType);
  //  this.expectation = this.transform.shouldToBoolean(expectation);
  //  return this.expect(this.currentPage[this.el].isSelected()).to.eventually.equal(this.expectation);
  //});
});
<commit_msg>Uncomment step defs<commit_after>var {defineSupportCode} = require('cucumber');

defineSupportCode(function({Given, When, Then, setWorldConstructor}) {
  setWorldConstructor(require('../support/World').World);

  Given('I am ready to test all this (covered by ready.spec.js)', function (callback) {
    // Write code here that turns the phrase above into concrete actions
    callback(null, 'pending');
  });

  this.Given(/^I (?:am on|go to) the "([^"]*)" page$/, function(pageName) {
    if (this.pageObjectMap[pageName] == null) {
      throw new Error("Could not find page with name '" + pageName + "' in the PageObjectMap, did you remember to add it?");
    }
    this.currentPage = new this.pageObjectMap[pageName];
    this.currentPage.get();
    return this.currentPage.waitForLoaded();
  });
  this.Given(/^I (?:have|change to|resize to|rotate to) a (\d+)x(\d+) screen size$/, function(width, height) {
    return browser.manage().window().setSize(parseInt(width, 10), parseInt(height, 10));
  });
  this.When(/^I (?:navigate|click) (?:backwards|back) in my browser$/, function() {
    return browser.navigate().back();
  });
  this.When(/^I type "([^"]*)" in(?:to)? the "([^"]*)" field$/, function(text, fieldName) {
    var field;
    field = this.transform.stringToVariableName(fieldName + 'Field');
    this.currentPage[field].clear();
    return this.currentPage[field].sendKeys(text);
  });
  this.When(/^I click the "([^"]*)"(?: )?(link|button|drop down list|tab|)$/, function(elementName, elementType) {
    var element;
    elementType = this.transform.elementTypeToVariableName(elementType);
    element = this.transform.stringToVariableName(elementName + elementType);
    return this.currentPage[element].click();
  });
  this.When(/^I refresh the page$/, function() {
    return browser.refresh();
  });
  this.When(/^I select "([^"]*)" in the "([^"]*)" drop down list$/, function(optionText, list) {
    return this.currentPage[this.transform.stringToVariableName(list + 'Select')].element(protractor.By.cssContainingText('option', optionText)).click();
  });
  this.Then(/^the title should equal "([^"]*)"$/, function(text) {
    return this.expect(browser.getTitle()).to.eventually.equal(text);
  });
  this.Then(/^the "([^"]*)" (should|should not) be active$/, function(tabName, expectation) {
    this.tabName = this.transform.stringToVariableName(tabName);
    this.expectation = this.transform.shouldToBoolean(expectation);
    return this.expect(this.elementHelper.hasClass(this.currentPage[this.tabName], 'active')).to.eventually.equal(this.expectation);
  });
  this.Then(/^the "([^"]*)" should be present$/, function(el) {
    this.el = this.transform.stringToVariableName(el);
    return this.expect(this.currentPage[this.el].isPresent()).to.eventually.equal(true);
  });
  this.Then(/^I (?:should be on|reach|am taken to) the "([^"]*)" page$/, function(pageName) {
    this.currentPage = new this.pageObjectMap[pageName];
    return this.currentPage.waitForLoaded();
  });
  this.Then(/^(?:the )?"([^"]*)" should (?:have|contain) the text "([^"]*)"$/, function(el, text) {
    var elText;
    this.el = this.currentPage[this.transform.stringToVariableName(el)];
    elText = this.el.getTagName().then((function(_this) {
      return function(tagName) {
        var isInput;
        isInput = tagName === "input";
        if (isInput) {
          return _this.el.getAttribute('value');
        } else {
          return _this.el.getText();
        }
      };
    })(this));
    return this.expect(elText).to.eventually.contain(text);
  });
  this.Then(/^"([^"]*)" should appear in the "([^"]*)" drop down list$/, function(option, list) {
    var optionsText;
    this.list = this.currentPage[this.transform.stringToVariableName(list + 'Select')];
    optionsText = this.list.all(By.tagName('option')).map(function(element, index) {
      return element.getText();
    });
    return this.expect(optionsText).to.eventually.contain(option);
  });
  this.Then(/^the "([^"]*)" (should|should not) be displayed$/, function(el, shouldBeDisplayed) {
    var isDisplayed;
    this.shouldBeDisplayed = this.transform.shouldToBoolean(shouldBeDisplayed);
    this.el = this.transform.stringToVariableName(el);
    return isDisplayed = this.currentPage[this.el].isDisplayed().then((function(_this) {
      return function(isDisplayed) {
        return _this.expect(isDisplayed).to.equal(_this.shouldBeDisplayed);
      };
    })(this), (function(_this) {
      return function(err) {
        if (err.name === 'NoSuchElementError') {
          return _this.expect(false).to.equal(_this.shouldBeDisplayed);
        }
        throw err;
      };
    })(this));
  });
  this.Then(/^(?:the )?"([^"]*)" should (?:have|contain) the placeholder text "([^"]*)"$/, function(el, text) {
    this.el = this.currentPage[this.transform.stringToVariableName(el)];
    return this.expect(this.el.getAttribute('placeholder')).to.eventually.contain(text);
  });
  this.Then(/^the "([^"]*)"(?: )?(button|field|drop down list|) (should|should not) be enabled$/, function(el, elType, expectation) {
    var elementType;
    elementType = this.transform.elementTypeToVariableName(elType);
    this.el = this.transform.stringToVariableName(el + elementType);
    this.expectation = this.transform.shouldToBoolean(expectation);
    return this.expect(this.currentPage[this.el].isEnabled()).to.eventually.equal(this.expectation);
  });
  this.Then(/^"([^"]*)" should be (?:selected|displayed) in the "([^"]*)" drop down list$/, function(optionText, list) {
    var option;
    this.list = this.currentPage[this.transform.stringToVariableName(list + 'Select')];
    option = this.list.element(By.cssContainingText('option', optionText));
    return this.expect(option.isSelected()).to.eventually.be["true"];
  });
  return this.Then(/^the "([^"]*)"(?: )?(checkbox|) (should|should not) be checked$/, function(el, elType, expectation) {
    var elementType;
    elementType = this.transform.elementTypeToVariableName(elType);
    this.el = this.transform.stringToVariableName(el + elementType);
    this.expectation = this.transform.shouldToBoolean(expectation);
    return this.expect(this.currentPage[this.el].isSelected()).to.eventually.equal(this.expectation);
  });
});
<|endoftext|>


<commit_before>/*! jquery.blurr 01-08-2014 - Copyright 2014 Tom Hallam - MIT Licenced  >*/
!function(a,b,c,d){function e(e,h,i){this.$el=a(e),this.settings=a.extend({},g,h),this._defaults=g,this._name=f,this.cssPrefix=null,this.tpl='<svg><defs><filter id="blrIMG{{i}}"><feGaussianBlur id="filter_1" stdDeviation="{{sharpness}}" data-filterid="1"></feGaussianBlur><feComponentTransfer><feFuncR type="linear" slope="0.8"></feFuncR><feFuncG type="linear" slope="0.8"></feFuncG><feFuncB type="linear" slope="0.8"></feFuncB></feComponentTransfer></filter></defs><image x="{{offsetX}}" y="{{offsetY}}" width="100%" height="100%" xlink:href="{{href}}" filter="url(#blrIMG{{i}})" preserveAspectRatio="xMidYMid slice"></image></svg>',this.elementCount=i,this.supportsFilter=typeof SVGFEColorMatrixElement!==d&&2===SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE,this.supportsFilter=b.location.hash.length>0,_browserPrefixes=" -webkit- -moz- -o- -ms- ".split(" "),_cssPrefixString={},_cssPrefix=function(a){if(_cssPrefixString[a]||""===_cssPrefixString[a])return _cssPrefixString[a]+a;var b=c.createElement("div"),d=["","Moz","Webkit","O","ms","Khtml"];for(var e in d)if("undefined"!=typeof b.style[d[e]+a])return _cssPrefixString[a]=d[e],d[e]+a;return a.toLowerCase()},this.support={cssfilters:function(){var a=c.createElement("div");return a.style.cssText=_browserPrefixes.join("filter:blur(2px); "),!!a.style.length&&(c.documentMode===d||c.documentMode>9)}(),svgfilters:function(){var a=!1;try{a=typeof SVGFEColorMatrixElement!==d&&2==SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE}catch(b){}return a}()},this.cssPrefix=_cssPrefix("filter"),this.init()}var f="blurr",g={offsetX:0,offsetY:0,sharpness:40,height:300,callback:function(){}};a.extend(e.prototype,{init:function(){var a,b,c,d,e,f;return a=this.settings.href,b=this.settings.offsetX,c=this.settings.offsetY,d=this.settings.sharpness,e=this.settings.callback,f=this.settings.height,this.$el.data("image")&&(a=this.$el.data("image")),this.$el.data("href")&&(a=this.$el.data("href")),this.$el.data("offsetx")&&(b=this.$el.data("offsetx")),this.$el.data("offsety")&&(c=this.$el.data("offsety")),this.$el.data("sharpness")&&(d=this.$el.data("sharpness")),"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),d="undefined"==typeof d||0===d.length||0>d||d>100?d>100?100:40:100-d,("undefined"==typeof f||0===d.length||0>d)&&(f=300),this.$el.addClass("has-blurr"),this.support.svgfilters&&!this.support.cssfilters?this.renderSVG(a,b,c,d,f,e):this.renderCSSFilter(a,b,c,d,f,e)},renderSVG:function(b,c,d,e,f,g){var h=this.tpl;h=h.replace("{{href}}",b),h=h.replace("{{offsetX}}",c),h=h.replace("{{offsetY}}",d),h=h.replace("{{sharpness}}",e),h=h.replace(/{{i}}/g,this.elementCount),a(h).appendTo(this.$el),this.$el.css({height:f,overflow:"hidden",background:"#000"}),this.$el.find("svg").css({"min-width":"110%","min-height":"110%","-webkit-transform":"translate3d(-50px, 0px, 75px) scale(1.25)",transform:"translate3d(-50px, 0px, 75px) scale(1.25)",position:"relative",right:0,left:0}),this.$el.find("div:first").css({position:"absolute",left:0,right:0,"z-index":100}),"function"==typeof g&&g.call(this,b,c,d,e)},renderCSSFilter:function(b,c,d,e,f){this.$el.css({height:f,overflow:"hidden",position:"relative",background:"#000"});var g;g=c&&d?c+"px "+d+"px":c&&!d?c+"px center":!c&&d?"center "+d+"px":"center center";{var h=a('

').css({background:"url("+b+")",left:0,right:0,top:-50,bottom:-50,width:this.$el.width(),"background-size":"150% auto","background-position":g,"-webkit-filter":"blur("+e+"px)","z-index":50,position:"absolute"}).prependTo(this.$el);this.cssPrefix}h.css(this.support.cssfilters?{prefix:"blur("+e+"px)"}:{prefix:'progid:DXImageTransform.Microsoft.Blur(PixelRadius="'+e+'")'}),this.$el.find("div").not(".blurr-bg").css({position:"absolute",left:0,right:0,"z-index":100})}}),a.fn[f]=function(b){return this.each(function(c){a.data(this,"plugin_"+f)||a.data(this,"plugin_"+f,new e(this,b,c))}),this}}(jQuery,window,document);<commit_msg>Updated grunt<commit_after>/*! jquery.blurr @ 01-08-2014 12:08 - Copyright 2014 Tom Hallam - MIT Licenced  >*/
!function(a,b,c,d){function e(e,h,i){this.$el=a(e),this.settings=a.extend({},g,h),this._defaults=g,this._name=f,this.cssPrefix=null,this.tpl='<svg><defs><filter id="blrIMG{{i}}"><feGaussianBlur id="filter_1" stdDeviation="{{sharpness}}" data-filterid="1"></feGaussianBlur><feComponentTransfer><feFuncR type="linear" slope="0.8"></feFuncR><feFuncG type="linear" slope="0.8"></feFuncG><feFuncB type="linear" slope="0.8"></feFuncB></feComponentTransfer></filter></defs><image x="{{offsetX}}" y="{{offsetY}}" width="100%" height="100%" xlink:href="{{href}}" filter="url(#blrIMG{{i}})" preserveAspectRatio="xMidYMid slice"></image></svg>',this.elementCount=i,this.supportsFilter=typeof SVGFEColorMatrixElement!==d&&2===SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE,this.supportsFilter=b.location.hash.length>0,_browserPrefixes=" -webkit- -moz- -o- -ms- ".split(" "),_cssPrefixString={},_cssPrefix=function(a){if(_cssPrefixString[a]||""===_cssPrefixString[a])return _cssPrefixString[a]+a;var b=c.createElement("div"),d=["","Moz","Webkit","O","ms","Khtml"];for(var e in d)if("undefined"!=typeof b.style[d[e]+a])return _cssPrefixString[a]=d[e],d[e]+a;return a.toLowerCase()},this.support={cssfilters:function(){var a=c.createElement("div");return a.style.cssText=_browserPrefixes.join("filter:blur(2px); "),!!a.style.length&&(c.documentMode===d||c.documentMode>9)}(),svgfilters:function(){var a=!1;try{a=typeof SVGFEColorMatrixElement!==d&&2==SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE}catch(b){}return a}()},this.cssPrefix=_cssPrefix("filter"),this.init()}var f="blurr",g={offsetX:0,offsetY:0,sharpness:40,height:300,callback:function(){}};a.extend(e.prototype,{init:function(){var a,b,c,d,e,f;return a=this.settings.href,b=this.settings.offsetX,c=this.settings.offsetY,d=this.settings.sharpness,e=this.settings.callback,f=this.settings.height,this.$el.data("image")&&(a=this.$el.data("image")),this.$el.data("href")&&(a=this.$el.data("href")),this.$el.data("offsetx")&&(b=this.$el.data("offsetx")),this.$el.data("offsety")&&(c=this.$el.data("offsety")),this.$el.data("sharpness")&&(d=this.$el.data("sharpness")),"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),d="undefined"==typeof d||0===d.length||0>d||d>100?d>100?100:40:100-d,("undefined"==typeof f||0===d.length||0>d)&&(f=300),this.$el.addClass("has-blurr"),this.support.svgfilters&&!this.support.cssfilters?this.renderSVG(a,b,c,d,f,e):this.renderCSSFilter(a,b,c,d,f,e)},renderSVG:function(b,c,d,e,f,g){var h=this.tpl;h=h.replace("{{href}}",b),h=h.replace("{{offsetX}}",c),h=h.replace("{{offsetY}}",d),h=h.replace("{{sharpness}}",e),h=h.replace(/{{i}}/g,this.elementCount),a(h).appendTo(this.$el),this.$el.css({height:f,overflow:"hidden",background:"#000"}),this.$el.find("svg").css({"min-width":"110%","min-height":"110%","-webkit-transform":"translate3d(-50px, 0px, 75px) scale(1.25)",transform:"translate3d(-50px, 0px, 75px) scale(1.25)",position:"relative",right:0,left:0}),this.$el.find("div:first").css({position:"absolute",left:0,right:0,"z-index":100}),"function"==typeof g&&g.call(this,b,c,d,e)},renderCSSFilter:function(b,c,d,e,f){this.$el.css({height:f,overflow:"hidden",position:"relative",background:"#000"});var g;g=c&&d?c+"px "+d+"px":c&&!d?c+"px center":!c&&d?"center "+d+"px":"center center";{var h=a('

').css({background:"url("+b+")",left:0,right:0,top:-50,bottom:-50,width:this.$el.width(),"background-size":"150% auto","background-position":g,"-webkit-filter":"blur("+e+"px)","z-index":50,position:"absolute"}).prependTo(this.$el);this.cssPrefix}h.css(this.support.cssfilters?{prefix:"blur("+e+"px)"}:{prefix:'progid:DXImageTransform.Microsoft.Blur(PixelRadius="'+e+'")'}),this.$el.find("div").not(".blurr-bg").css({position:"absolute",left:0,right:0,"z-index":100})}}),a.fn[f]=function(b){return this.each(function(c){a.data(this,"plugin_"+f)||a.data(this,"plugin_"+f,new e(this,b,c))}),this}}(jQuery,window,document);<|endoftext|>


<commit_before>const settings = require('./../../settings.json');
const influx = require('./../../influx');
const knex = require('./../../knex');
/**
 * This method should return the response directly to the channel
 * @param {*string array} params
 * @param {*message} message
 */
async function command(params, message) {
    if (settings.owners.includes(message.author.id)) {
        let type = params.shift().toLowerCase();
        if(type === 'influx')
        {
          let res = await influx.query(params.join(' '));
          return await message.channel.send(res,{code:'js'});
        }
        else if(type === 'sql')
        {
          let res = await knex.raw(params.join(' '));
          return await message.channel.send(JSON.stringify(res),{code:'js'});
        }
        else
          return await message.reply("INVALID TYPE OF QUERY");
    }
    else
        return await message.reply('Not worthy');
}
/**
 * description of the command
 */
const description = "Execute a query (owners only)";
/**
 * Define Exports
 */
module.exports = {
    execute: command,
    description: description
};
<commit_msg>JSON.stringify res from influx<commit_after>const settings = require('./../../settings.json');
const influx = require('./../../influx');
const knex = require('./../../knex');
/**
 * This method should return the response directly to the channel
 * @param {*string array} params
 * @param {*message} message
 */
async function command(params, message) {
    if (settings.owners.includes(message.author.id)) {
        let type = params.shift().toLowerCase();
        if(type === 'influx')
        {
          let res = await influx.query(params.join(' '));
          return await message.channel.send(JSON.stringify(res),{code:'js'});
        }
        else if(type === 'sql')
        {
          let res = await knex.raw(params.join(' '));
          return await message.channel.send(JSON.stringify(res),{code:'js'});
        }
        else
          return await message.reply("INVALID TYPE OF QUERY");
    }
    else
        return await message.reply('Not worthy');
}
/**
 * description of the command
 */
const description = "Execute a query (owners only)";
/**
 * Define Exports
 */
module.exports = {
    execute: command,
    description: description
};
<|endoftext|>