<commit_before>/* @flow */
import React, {Children, PropTypes} from 'react';
import {Listeners} from '../../utils';
import type Urls from '../../urls';
import type {LinkProps, LinkMiddleware, Match, History, Location, ServerResult, Navigate} from '../../types';

export type RouterContextType = {|
    serverResult?: ServerResult,
    history: History,
    urls: Urls,
    match: Match | null,
    location: Location,
    listen: (callback: () => void) => () => void,
    linkMiddleware: LinkMiddleware[],
    navigate: Navigate
|};

export const RouterContextPropType = PropTypes.shape({
    serverResult: PropTypes.object,
    history: PropTypes.object.isRequired,
    urls: PropTypes.object.isRequired,
    match: PropTypes.object,
    location: PropTypes.object.isRequired,
    listen: PropTypes.func.isRequired,
    linkMiddleware: PropTypes.arrayOf(PropTypes.func).isRequired,
    navigate: PropTypes.func.isRequired
}).isRequired;

type RouterProps = {
    history: History,
    urls: Urls,
    serverResult?: ServerResult,
    linkMiddleware: LinkMiddleware[],
    children?: ?any
};

export default class Router extends React.Component {
    static displayName = 'Router';
    props: RouterProps;
    static defaultProps = {
        linkMiddleware: []
    };

    _listeners = new Listeners();
    _unlisten: ?() => void;

    static childContextTypes = {router: RouterContextPropType};
    getChildContext = (): {router: RouterContextType} => ({router: this.routerContext});
    routerContext = {
        serverResult: this.props.serverResult,
        history: this.props.history,
        urls: this.props.urls,
        location: this.props.history.location,
        match: null,
        listen: this._listeners.listen,
        linkMiddleware: this.props.linkMiddleware,
        navigate: (props: LinkProps, replace: ?boolean = false) => {
            const location = this.routerContext.urls.makeLocation(props);
            if (replace) {
                this.routerContext.history.replace(location);
            } else {
                this.routerContext.history.push(location);
            }
        }
    };

    _updateLocation = location => {
        this.routerContext.location = location;
        this._listeners.notify();
    };

    componentDidMount() {
        const {history} = this.props;
        this._unlisten = history.listen(this._updateLocation);

        // To catch early redirects
        if (history.location !== this.routerContext.location) {
            this._updateLocation(history.location);
        }
    }

    componentWillUnmount() {
        if (this._unlisten) {
            this._unlisten();
        }
    }

    render() {
        return Children.only(this.props.children);
    }
}
<commit_msg>addSlashes and replace if found<commit_after>/* @flow */
import React, {Children, PropTypes} from 'react';
import {Listeners} from '../../utils';
import type Urls from '../../urls';
import type {LinkProps, LinkMiddleware, Match, History, Location, ServerResult, Navigate} from '../../types';

export type RouterContextType = {|
    serverResult?: ServerResult,
    history: History,
    urls: Urls,
    match: Match | null,
    location: Location,
    listen: (callback: () => void) => () => void,
    linkMiddleware: LinkMiddleware[],
    navigate: Navigate
|};

export const RouterContextPropType = PropTypes.shape({
    serverResult: PropTypes.object,
    history: PropTypes.object.isRequired,
    urls: PropTypes.object.isRequired,
    match: PropTypes.object,
    location: PropTypes.object.isRequired,
    listen: PropTypes.func.isRequired,
    linkMiddleware: PropTypes.arrayOf(PropTypes.func).isRequired,
    navigate: PropTypes.func.isRequired
}).isRequired;

type RouterProps = {
    history: History,
    addSlashes: boolean,
    urls: Urls,
    serverResult?: ServerResult,
    linkMiddleware: LinkMiddleware[],
    children?: ?any
};

const SLASH_RE = /\/$/;

export default class Router extends React.Component {
    static displayName = 'Router';
    props: RouterProps;
    static defaultProps = {
        linkMiddleware: [],
        addSlashes: false
    };

    _listeners = new Listeners();
    _unlisten: ?() => void;

    static childContextTypes = {router: RouterContextPropType};
    getChildContext = (): {router: RouterContextType} => ({router: this.routerContext});
    routerContext = {
        serverResult: this.props.serverResult,
        history: this.props.history,
        urls: this.props.urls,
        location: this.props.history.location,
        match: null,
        listen: this._listeners.listen,
        linkMiddleware: this.props.linkMiddleware,
        navigate: (props: LinkProps, replace: ?boolean = false) => {
            const location = this.routerContext.urls.makeLocation(props);

            if (replace) {
                this.routerContext.history.replace(location);
            } else {
                this.routerContext.history.push(location);
            }
        }
    };

    _updateLocation = location => {
        let finalLocation = location;

        if (this.props.addSlashes) {
            const redirectPath = this._slashUrlPath(location);
            if (redirectPath) {
                finalLocation = this.routerContext.urls.makeLocation({to: redirectPath});

                this.routerContext.history.replace(finalLocation);
            }
        }

        this.routerContext.location = finalLocation;
        this._listeners.notify();
    };

    _slashUrlPath = location => {
        // See if there is a url with slashes that we can redirect to
        const {pathname, search} = location;
        if (!pathname.match(SLASH_RE)) {
            const pathNameWithSlash = `${pathname}/`;
            for (const urlName of this.routerContext.urls.getAllUrlNames()) {
                if (this.routerContext.urls.match(pathNameWithSlash, urlName, {strict: true, exact: true})) {
                    return `${pathNameWithSlash}${search ? `?${search}` : ''}`;
                }
            }
        }
        return null;  // no redirect needed
    }

    componentDidMount() {
        const {history} = this.props;
        this._unlisten = history.listen(this._updateLocation);

        // To catch early redirects
        this._updateLocation(history.location, true);
    }

    componentWillUnmount() {
        if (this._unlisten) {
            this._unlisten();
        }
    }

    render() {
        return Children.only(this.props.children);
    }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import presentations from '../../data/presentations';
import './index.css';
import Diagram from '../Diagram';
import Controls from './components/Controls';
import Loading from '../Loading';
import ErrorMessage from '../ErrorMessage';
import PropTypes from 'prop-types';
import 'roboto-fontface/css/roboto/roboto-fontface.css';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Title from '../Title';
import TitleSlide from './components/TitleSlide';
import * as screenfull from 'screenfull';
import { cloneDeep } from 'lodash';

class Viewer extends Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: true,
            isFullScreen: false,
        };
    }

    componentDidMount() {
        const { presId } = this.props;
        presentations.get(presId)
            .then(presentation => {
                this.addEventListeners();

                const copy = cloneDeep(presentation);
                if (copy.title) {
                    copy.slides = [{
                        isTitleSlide: true,
                        title: copy.title,
                        authorName: copy.authorName,
                    }].concat(copy.slides);
                }
                this.setState({
                    presentation: copy,
                    loading: false,
                    activeSlideIndex: 0
                });
            })
            .catch(err => {
                this.setState({
                    error: {
                        message: err.message
                    },
                    loading: false
                })
            });
    }

    addEventListeners() {
        window.addEventListener('keydown', (e) => {
            switch(e.keyCode) {
                case 39:
                    // right arrow
                    this.nextSlide();
                    break;
                case 37:
                    // Left arrow
                    this.prevSlide()
            }
        })
    }

    nextSlide = () =>  {
        const { activeSlideIndex, presentation } = this.state;
        if (activeSlideIndex === presentation.slides.length - 1) return;
        this.setState({
            activeSlideIndex: activeSlideIndex + 1,
        })
    };

    prevSlide = () => {
        const { activeSlideIndex } = this.state;
        if (activeSlideIndex === 0) return;
        this.setState({
            activeSlideIndex: activeSlideIndex - 1,
        })
    };

    onReady = () => {
        this.setState({loading: false})
    };

    handleToggleFullScreen = () => {
        if(screenfull.enabled) {
            screenfull.toggle();
            screenfull.onchange(() => {
                this.setState({
                    isFullScreen: screenfull.isFullscreen,
                })
            })
        }
    };

    render() {
        const { loading, presentation, activeSlideIndex, error, isFullScreen } = this.state;

        if (error)  {
            return <ErrorMessage message={error.message} />
        }

        if ( loading ) return  <Loading />;
        if (! presentation) return null;

        const activeSlide = presentation.slides[activeSlideIndex];
        const diagramSlide = activeSlide.isTitleSlide ? presentation.slides[activeSlideIndex + 1] : activeSlide;

        const isHidden = activeSlide.isTitleSlide;

        return (
            <MuiThemeProvider>

                    { activeSlide.isTitleSlide ? <TitleSlide
                        title={activeSlide.title}
                        authorName={activeSlide.authorName} />
                        : null }

                    { !activeSlide.isTitleSlide && activeSlide.title ? <Title title={activeSlide.title} /> : null }

                    <Diagram
                        wpId={presentation.wpId}
                        version={presentation.version}
                        slide={diagramSlide}
                        showPanZoomControls={false}
                        isHidden={isHidden}
                        onReady={this.onReady}  />

                    <Controls
                        onBackward={this.prevSlide}
                        onForward={this.nextSlide}
                        handleToggleFullScreen={this.handleToggleFullScreen}
                        isFullScreen={isFullScreen}
                    />

            </MuiThemeProvider>
        );
    }
}

Viewer.propTypes = {
    presId: PropTypes.string.isRequired
};

export default Viewer;<commit_msg>Disable detail panel in viewer<commit_after>import React, { Component } from 'react';
import presentations from '../../data/presentations';
import './index.css';
import Diagram from '../Diagram';
import Controls from './components/Controls';
import Loading from '../Loading';
import ErrorMessage from '../ErrorMessage';
import PropTypes from 'prop-types';
import 'roboto-fontface/css/roboto/roboto-fontface.css';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Title from '../Title';
import TitleSlide from './components/TitleSlide';
import * as screenfull from 'screenfull';
import { cloneDeep } from 'lodash';

class Viewer extends Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: true,
            isFullScreen: false,
        };
    }

    componentDidMount() {
        const { presId } = this.props;
        presentations.get(presId)
            .then(presentation => {
                this.addEventListeners();

                const copy = cloneDeep(presentation);
                if (copy.title) {
                    copy.slides = [{
                        isTitleSlide: true,
                        title: copy.title,
                        authorName: copy.authorName,
                    }].concat(copy.slides);
                }
                this.setState({
                    presentation: copy,
                    loading: false,
                    activeSlideIndex: 0
                });
            })
            .catch(err => {
                this.setState({
                    error: {
                        message: err.message
                    },
                    loading: false
                })
            });
    }

    addEventListeners() {
        window.addEventListener('keydown', (e) => {
            switch(e.keyCode) {
                case 39:
                    // right arrow
                    this.nextSlide();
                    break;
                case 37:
                    // Left arrow
                    this.prevSlide()
            }
        })
    }

    nextSlide = () =>  {
        const { activeSlideIndex, presentation } = this.state;
        if (activeSlideIndex === presentation.slides.length - 1) return;
        this.setState({
            activeSlideIndex: activeSlideIndex + 1,
        })
    };

    prevSlide = () => {
        const { activeSlideIndex } = this.state;
        if (activeSlideIndex === 0) return;
        this.setState({
            activeSlideIndex: activeSlideIndex - 1,
        })
    };

    onReady = () => {
        this.setState({loading: false})
    };

    handleToggleFullScreen = () => {
        if(screenfull.enabled) {
            screenfull.toggle();
            screenfull.onchange(() => {
                this.setState({
                    isFullScreen: screenfull.isFullscreen,
                })
            })
        }
    };

    render() {
        const { loading, presentation, activeSlideIndex, error, isFullScreen } = this.state;

        if (error)  {
            return <ErrorMessage message={error.message} />
        }

        if ( loading ) return  <Loading />;
        if (! presentation) return null;

        const activeSlide = presentation.slides[activeSlideIndex];
        const diagramSlide = activeSlide.isTitleSlide ? presentation.slides[activeSlideIndex + 1] : activeSlide;

        const isHidden = activeSlide.isTitleSlide;

        return (
            <MuiThemeProvider>

                    { activeSlide.isTitleSlide ? <TitleSlide
                        title={activeSlide.title}
                        authorName={activeSlide.authorName} />
                        : null }

                    { !activeSlide.isTitleSlide && activeSlide.title ? <Title title={activeSlide.title} /> : null }

                    <Diagram
                        wpId={presentation.wpId}
                        detailPanelEnabled={false}
                        version={presentation.version}
                        slide={diagramSlide}
                        showPanZoomControls={false}
                        isHidden={isHidden}
                        onReady={this.onReady}  />

                    <Controls
                        onBackward={this.prevSlide}
                        onForward={this.nextSlide}
                        handleToggleFullScreen={this.handleToggleFullScreen}
                        isFullScreen={isFullScreen}
                    />

            </MuiThemeProvider>
        );
    }
}

Viewer.propTypes = {
    presId: PropTypes.string.isRequired
};

export default Viewer;<|endoftext|>


<commit_before>import InputField from "material-ui/lib/text-field";
import React from "react";
import { connect } from "react-redux";
import { doSignin, doFacebookSignin } from "../../actions";
import { browserHistory } from "react-router";
import Radium from "radium";
import Awesome from "react-fontawesome";
import Flex from "../framework/flex";
import Button from "../framework/generic-button";
import StaticContentContainer from "../framework/static-content-container";
import Press from "./press";
import Benefit from "./benefit";

// import { Tweet } from 'react-twitter-widgets';

@connect()
@Radium
class Plus extends React.Component {
  styles() {
    return {
      container: {
        minWidth: "100vw",
        zIndex: 10
      },
      sectionColor: {
        minWidth: "100vw",
        backgroundColor: "#03a9f4",
        color: "white",
      },
      hero: {
        fontSize: 48,
        lineHeight: 1.4,
        textTransform: 'uppercase',
        maxWidth: 900,
        padding: "0px 40px",
        zIndex: 10,
        textAlign: 'center',
      },
      heroSub: {
        fontSize: 24,
        lineHeight: 1.6,
        textAlign: 'center',
        fontWeight: 300,
        margin: 0,
        padding: "0px 40px",
        maxWidth: 700,
        zIndex: 10,
      },
      callToAction: {
        width: "100vw",
        padding: "50px 0px 70px 0px",
        backgroundColor: "#03a9f4",
      },
      getStartedButton: {
        backgroundColor: "rgb(255,191,31)",
        color: "white"
      },
      body: {
        padding: 40
      },
      section: {
        padding: 0,
      },
      bandSection: {
        backgroundColor: "#03a9f4",
        color: "white",
        width: "100vw",
        padding: "30px 0px"
      },
      sectionHeader: {
        fontSize: 24,
        marginBottom: 0,
      },
      sectionBody: {
        maxWidth: 500,
        fontWeight: 300,
        lineHeight: 1.5
      },
      button: {
        backgroundColor: "white",
        color: "rgb(100,100,100)"
      },
      flexTestContainer: {
        minHeight: "100%"
      },
      flexTestDiv: {
        backgroundColor: "red",
        color: "white",
        minHeight: 50,
        width: "100%",
      }
    }
  }
  handleGetStartedClicked(r) {
    return () => {
      browserHistory.push(r);
    };
  }
  render() {
    return (
      <StaticContentContainer
        backgroundColor={"#03a9f4"}
        headerBackgroundColor={"#03a9f4"}
        footerBackgroundColor={"#03a9f4"}
        image={false}
        stars={{visible: true, color: "darkgrey"}}>
        {/* hero */}
        <Flex
          direction="column"
          alignItems="center"
          grow="1"
          styleOverrides={this.styles().sectionColor}>

              { "Crowd Intelligence" }

              Meet pol.is: an AI powered sentiment gathering platform.
              More organic than surveys, less effort than focus groups.

        </Flex>
        {/* upper cta */}
        <Flex styleOverrides={this.styles().callToAction}>
          <Button
            onClick={this.handleGetStartedClicked("createuser")}
            style={this.styles().getStartedButton}> Get started </Button>
        </Flex>
        <Press/>

 polis leverages techniques from both quantitative and qualitative research, combined with powerful analytics, to gather feedback that is simultaneously authentic to the population being surveyed and data rich.

      <Flex
        styleOverrides={{padding: "20px 40px"}}
        justifyContent="space-around"
        wrap="wrap"
        alignItems="baseline">
        <Benefit
          heading={"Scalable feedback"}
          body={`
            Whether you have hundreds of people or hundreds of thousands, pol.is can help you figure out what they think with little to no burden on you.
            `}/>
        <Benefit
          heading={"Unbiased"}
          body={`
            Respondents are scoring themselves on statements created by other respondents, not what was already in the survey creator's head
            `}/>
        <Benefit
          heading={"Effortless"}
          body={`
            Ask a question and let pol.is produce insights automatically
            `}/>
        <Benefit
          heading={"Organic"}
          body={`
            The results from pol.is are emergent - they are a better reflection of the state of mind of participants than surveys are - and frequently surprising
            `}/>
        <Benefit
          heading={"Usable data"}
          body={`
            Pol.is layers quantitative data onto qualitative data - it's both rich and usable. Your data is yours: run a data export at any time to get the raw data in csv form. Cross reference your data with opinion groups pol.is produces.
            `}/>
        <Benefit
          heading={"API"}
          body={`
            The pol.is api allows you to automate and script conversations
            `}/>
      </Flex>

      </StaticContentContainer>
    );
  }
}

export default Plus;

// <Benefit
//   heading={"Auto-correlation tool (coming soon)"}
//   body={`
//     Upload your data, let pol.is automatically surface correlations with opinion groups
//     `}/>
<commit_msg>plus copy<commit_after>import InputField from "material-ui/lib/text-field";
import React from "react";
import { connect } from "react-redux";
import { doSignin, doFacebookSignin } from "../../actions";
import { browserHistory } from "react-router";
import Radium from "radium";
import Awesome from "react-fontawesome";
import Flex from "../framework/flex";
import Button from "../framework/generic-button";
import StaticContentContainer from "../framework/static-content-container";
import Press from "./press";
import Benefit from "./benefit";
import BackgroundStars from "../framework/background-stars";

// import { Tweet } from 'react-twitter-widgets';

/*

 polis leverages techniques from both quantitative and qualitative research, combined with powerful analytics, to gather feedback that is simultaneously authentic to the population being surveyed and data rich.

*/

@connect()
@Radium
class Plus extends React.Component {
  styles() {
    return {
      container: {
        minWidth: "100vw",
        zIndex: 10
      },
      sectionColor: {
        minWidth: "100vw",
        backgroundColor: "#03a9f4",
        color: "white",
      },
      hero: {
        fontSize: 48,
        lineHeight: 1.4,
        maxWidth: 900,
        padding: "0px 40px",
        zIndex: 10,
        textAlign: 'center',
      },
      heroSub: {
        fontSize: 24,
        lineHeight: 1.6,
        textAlign: 'center',
        fontWeight: 300,
        margin: 0,
        padding: "0px 40px",
        maxWidth: 700,
        zIndex: 10,
      },
      callToAction: {
        width: "100vw",
        padding: "50px 0px 70px 0px",
        // backgroundColor: "#03a9f4",
      },
      getStartedButton: {
        backgroundColor: "#03a9f4",
        color: "white"
      },
      body: {
        padding: 40
      },
      section: {
        padding: 0,
      },
      bandSection: {
        backgroundColor: "#03a9f4",
        color: "white",
        width: "100vw",
        padding: "30px 0px"
      },
      sectionHeader: {
        fontSize: 24,
        marginBottom: 0,
      },
      sectionBody: {
        maxWidth: 500,
        fontWeight: 300,
        lineHeight: 1.5
      },
      button: {
        backgroundColor: "white",
        color: "rgb(100,100,100)"
      },
      flexTestContainer: {
        minHeight: "100%"
      },
      flexTestDiv: {
        backgroundColor: "red",
        color: "white",
        minHeight: 50,
        width: "100%",
      }
    }
  }
  handleGetStartedClicked(r) {
    return () => {
      browserHistory.push(r);
    };
  }
  render() {
    return (
      <StaticContentContainer
        backgroundColor={"#03a9f4"}
        headerBackgroundColor={"#03a9f4"}
        footerBackgroundColor={"#03a9f4"}
        image={false}
        stars={{visible: true, color: "darkgrey"}}>
        {/* hero */}
        <Flex
          direction="column"
          alignItems="center"
          grow="1"
          >

              { "Crowd Intelligence Made Effortless" }

              Meet pol.is: an AI powered sentiment gathering platform.
              More organic than surveys, less effort than focus groups.

        </Flex>
        {/* upper cta */}
        <Flex styleOverrides={this.styles().callToAction}>
          <Button
            onClick={this.handleGetStartedClicked("createuser")}
            style={this.styles().getStartedButton}> Get started </Button>
        </Flex>
        <Press/>

      <Flex
        styleOverrides={{padding: "20px 40px"}}
        justifyContent="space-around"
        wrap="wrap"
        alignItems="baseline">
        <Benefit
          heading={"Effortless"}
          body={`
            No survey to create - simply ask a question in plain english, share a link, and let pol.is produce insights automatically
            `}/>
        <Benefit
          heading={"Scalable"}
          body={`
            Whether you have hundreds of people or hundreds of thousands, pol.is can help you figure out what they think
            `}/>
        <Benefit
          heading={"Organic"}
          body={`
            The results from pol.is are emergent - they are a better reflection of the state of mind of participants than surveys are - and frequently surprising
            `}/>
        <Benefit
          heading={"Unbiased"}
          body={`
            Respondents are scoring themselves on statements created by other respondents, not the ideas already in the mind of the survey creator
            `}/>
        <Benefit
          heading={"Data Rich"}
          body={`
            Pol.is layers quantitative data onto qualitative data - it's both rich and usable. Your data is yours: run a data export at any time to get the raw data in csv form
            `}/>
        <Benefit
          heading={"JSON API"}
          body={`
            The pol.is API allows you to automate and script conversations, ship insights to those who need them and export data to analysis pipelines
            `}/>
      </Flex>

      </StaticContentContainer>
    );
  }
}

export default Plus;

// <Benefit
//   heading={"Auto-correlation tool (coming soon)"}
//   body={`
//     Upload your data, let pol.is automatically surface correlations with opinion groups
//     `}/>
<|endoftext|>


<commit_before>import {
  noView, inject, customElement, bindable
} from 'aurelia-framework';
import React from 'react';
import ReactDOM from 'react-dom';
import ReactPlayer from 'react-player';

@noView()
@inject(Element)
@bindable('data')
@bindable('copy')
@customElement('music-player')
export class MusicPlayer {
  constructor(element) {
    this.element = element;
    this.play = this.play.bind(this);
    this.index = 0;
    this.playing = false;
    this.playEnd = this.playEnd.bind(this);
    this.pause = this.pause.bind(this);
    this.shuffle = this.shuffle.bind(this);
    this.share = this.share.bind(this);
    this.copyShare = this.copyShare.bind(this);
    this.next = this.next.bind(this);
    this.prev = this.prev.bind(this);
    this.playUrl = `${document.location.href}?oneplayer=true`;
    this.shown = false;
    this.navigator = navigator;
    this.isShuffleOn = false;
  }

  get html() {
    return (

            <ReactPlayer
              style={{ backgroundColor: '#eee', textAlign: 'center' }}
              url={this.url[0]}
              playing={this.playing}
              controls
              onEnded={this.playEnd}
              width="100%"
              id="mainPlayer"
              config={{ file: { attributes: { controlsList: 'nodownload' } } }}
            />

              <input id="copyUrl" disabled value={this.playUrl} style={{ backgroundColor: '#fff' }} className="form-control" />

Copy URL

Url copied Url to clipboard

            {this.url[1]}

            <button id="play-pause" role="menu" onClick={this.play}>
Play/Pause
            </button>

            <button role="menu" onClick={this.next}>
Next
            </button>

            <button role="menu" onClick={this.prev}>
Prev
            </button>

            <button id="shuffle" role="menu" onClick={this.shuffle}>
Shuffle
            </button>

            <button role="menu" onClick={this.share}>
Share
            </button>

    );
  }

  pressKey() {}

  /**
   * Shuffles array in place. ES6 version
   */
  shuffle() {
    if (this.isShuffleOn) {
      this.urls = this._urls;
      this.isShuffleOn = false;
      document.getElementById('shuffle').classList.remove('on');
    } else {
      this.urls = this.urls.slice();
      for (let i = this.urls.length - 1; i > 0; i -= 1) {
        const j = Math.floor(Math.random() * (i + 1));
        [this.urls[i], this.urls[j]] = [this.urls[j], this.urls[i]];
      }
      document.getElementById('shuffle').classList.add('on');
      this.isShuffleOn = true;
    }
    this.index = 0;
    this.url = this.urls[this.index];
    this.bind();
  }

  playEnd() {
    this.next();
  }

  playTrue() {
    this.bind();
  }

  prev() {
    this.index -= 1;
    if (this.index < 0) {
      this.index = this.urls.length - 1;
      this.url = this.urls[this.index];
    } else {
      this.url = this.urls[this.index];
    }
    this.playTrue();
  }

  play() {
    this.playing = !this.playing;
    if (this.playing) {
      document.getElementById('play-pause').classList.remove('off');
      document.getElementById('play-pause').classList.add('on');
    } else {
      document.getElementById('play-pause').classList.remove('on');
      document.getElementById('play-pause').classList.add('off');
    }
    this.bind();
  }

  pause() {
    this.playing = false;
    this.bind();
  }

  next() {
    this.index += 1;
    if (this.index >= this.urls.length) {
      this.index = 0;
      this.url = this.urls[this.index];
    } else {
      this.url = this.urls[this.index];
    }
    this.playTrue();
  }

  render() {
    ReactDOM.render(this.html, this.element);
  }

  share() {
    const el = document.getElementById('copier');
    if (this.shown) {
      el.classList.add('d-none');
      this.shown = false;
    } else {
      el.classList.remove('d-none');
      this.shown = true;
    }
  }

  copyShare() {
    this.navigator.clipboard.writeText(this.playUrl).then(() => {
      this.share();

      const el = document.getElementById('copyMessage');

      el.classList.remove('d-none');

      setTimeout(() => {
        el.classList.add('d-none');
      }, 1500);
    });
  }

  bind() {
    if (!this.urls || !this._urls) {
      this.urls = this.data;
      this._urls = this.copy;
      this.url = this.urls[this.index];
    }

    this.render();
  }
}
<commit_msg>lint errors fixed<commit_after>import {
  noView, inject, customElement, bindable
} from 'aurelia-framework';
import React from 'react';
import ReactDOM from 'react-dom';
import ReactPlayer from 'react-player';

@noView()
@inject(Element)
@bindable('data')
@bindable('copy')
@customElement('music-player')
export class MusicPlayer {
  constructor(element) {
    this.element = element;
    this.play = this.play.bind(this);
    this.index = 0;
    this.playing = false;
    this.playEnd = this.playEnd.bind(this);
    this.pause = this.pause.bind(this);
    this.shuffle = this.shuffle.bind(this);
    this.share = this.share.bind(this);
    this.copyShare = this.copyShare.bind(this);
    this.next = this.next.bind(this);
    this.prev = this.prev.bind(this);
    this.playUrl = `${document.location.href}?oneplayer=true`;
    this.shown = false;
    this.navigator = navigator;
    this.isShuffleOn = false;
  }

  get html() {
    return (

            <ReactPlayer
              style={{ backgroundColor: '#eee', textAlign: 'center' }}
              url={this.url[0]}
              playing={this.playing}
              controls
              onEnded={this.playEnd}
              width="100%"
              id="mainPlayer"
              config={{ file: { attributes: { controlsList: 'nodownload' } } }}
            />

              <input id="copyUrl" disabled value={this.playUrl} style={{ backgroundColor: '#fff' }} className="form-control" />

Copy URL

Url copied Url to clipboard

            {this.url[1]}

            <button id="play-pause" role="menu" onClick={this.play}>
Play/Pause
            </button>

            <button role="menu" onClick={this.next}>
Next
            </button>

            <button role="menu" onClick={this.prev}>
Prev
            </button>

            <button id="shuffle" role="menu" onClick={this.shuffle}>
Shuffle
            </button>

            <button role="menu" onClick={this.share}>
Share
            </button>

    );
  }

  pressKey() {}

  /**
   * Shuffles array in place. ES6 version
   */
  shuffle() {
    if (this.isShuffleOn) {
      this.urls = this._urls;
      this.isShuffleOn = false;
      document.getElementById('shuffle').classList.remove('on');
    } else {
      this.urls = this.urls.slice();
      for (let i = this.urls.length - 1; i > 0; i -= 1) {
        const j = Math.floor(Math.random() * (i + 1));
        [this.urls[i], this.urls[j]] = [this.urls[j], this.urls[i]];
      }
      document.getElementById('shuffle').classList.add('on');
      this.isShuffleOn = true;
    }
    this.index = 0;
    this.url = this.urls[this.index];
    this.bind();
  }

  playEnd() {
    this.next();
  }

  playTrue() {
    this.bind();
  }

  prev() {
    this.index -= 1;
    if (this.index < 0) {
      this.index = this.urls.length - 1;
      this.url = this.urls[this.index];
    } else {
      this.url = this.urls[this.index];
    }
    this.playTrue();
  }

  play() {
    this.playing = !this.playing;
    if (this.playing) {
      document.getElementById('play-pause').classList.remove('off');
      document.getElementById('play-pause').classList.add('on');
    } else {
      document.getElementById('play-pause').classList.remove('on');
      document.getElementById('play-pause').classList.add('off');
    }
    this.bind();
  }

  pause() {
    this.playing = false;
    this.bind();
  }

  next() {
    this.index += 1;
    if (this.index >= this.urls.length) {
      this.index = 0;
      this.url = this.urls[this.index];
    } else {
      this.url = this.urls[this.index];
    }
    this.playTrue();
  }

  render() {
    ReactDOM.render(this.html, this.element);
  }

  share() {
    const el = document.getElementById('copier');
    if (this.shown) {
      el.classList.add('d-none');
      this.shown = false;
    } else {
      el.classList.remove('d-none');
      this.shown = true;
    }
  }

  copyShare() {
    this.navigator.clipboard.writeText(this.playUrl).then(() => {
      this.share();

      const el = document.getElementById('copyMessage');

      el.classList.remove('d-none');

      setTimeout(() => {
        el.classList.add('d-none');
      }, 1500);
    });
  }

  bind() {
    if (!this.urls || !this._urls) {
      this.urls = this.data;
      this._urls = this.copy;
      this.url = this.urls[this.index];
    }

    this.render();
  }
}
<|endoftext|>


<commit_before>/*
 This file is a part of libertysoil.org website
 Copyright (C) 2015  Loki Education (Social Enterprise)

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

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

import Tag from '../tag';
import { TAG_HASHTAG, TAG_SCHOOL } from '../../utils/tags';

export default class TagLine extends React.Component {
  static displayName = "TagLine"

  static propTypes = {
    tags: React.PropTypes.arrayOf(React.PropTypes.shape({
      id: React.PropTypes.string,
      name: React.PropTypes.string
    })),
    schools: React.PropTypes.arrayOf(React.PropTypes.shape({
      id: React.PropTypes.string,
      name: React.PropTypes.string,
      url_name: React.PropTypes.string
    }))
  };

  render () {
    let {
        tags,
        schools
      } = this.props;

    if ((!tags || !schools) || (tags.length == 0 && schools.length == 0)) {
      return


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';
import classNames from 'classnames';
import { updateProfileAssetFileIndex } from '../../actions/profile';
import { isConflicts } from '../../utils/conflicts';
import { getIndexByOffset, getFiles } from '../../utils/files';

const getImg = (files, fileIndex, offset, style, onClick) => {
  const file = files[getIndexByOffset(files.length, fileIndex, offset)];
  const img = {
    src: file.src,
    style: file.computedStyle
  };
  return file ?  : null;
};

const Wheel = (
  ({ dispatch, assets, profile, type }) => {

    if ( ! assets.items) return
;

    const conflict = isConflicts(assets, profile);

    const classeName = classNames('wheel', {
      left:  type === 'left',
      right: type === 'right',
      disabled: conflict
    });

    const files = getFiles(assets);
    const fileIndex = profile[assets.current.asset].fileIndex;
    const offsets = type === 'left' ? [-2, -1] : [1, 2];

    const assetItem = assets.items[assets.current.asset];

    return (

        {offsets.map((offset, index) => (

              {getImg(files, fileIndex, offset, assetItem.style, () => conflict || dispatch(updateProfileAssetFileIndex(offset)))}

        ))}

    )
  }
);

const mapStateToProps = state => ({
  assets: state.assets,
  profile: state.profile
});

export default connect(mapStateToProps)(Wheel);
<commit_msg>Fix key<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';
import classNames from 'classnames';
import { updateProfileAssetFileIndex } from '../../actions/profile';
import { isConflicts } from '../../utils/conflicts';
import { getIndexByOffset, getFiles } from '../../utils/files';

const getImg = (files, fileIndex, offset, style, onClick) => {
  const file = files[getIndexByOffset(files.length, fileIndex, offset)];
  const img = {
    src: file.src,
    style: file.computedStyle
  };
  return file ?  : null;
};

const Wheel = (
  ({ dispatch, assets, profile, type }) => {

    if ( ! assets.items) return
;

    const conflict = isConflicts(assets, profile);

    const classeName = classNames('wheel', {
      left:  type === 'left',
      right: type === 'right',
      disabled: conflict
    });

    const files = getFiles(assets);
    const fileIndex = profile[assets.current.asset].fileIndex;
    const offsets = type === 'left' ? [-2, -1] : [1, 2];

    const assetItem = assets.items[assets.current.asset];

    return (

        {offsets.map((offset, index) => (

              {getImg(files, fileIndex, offset, assetItem.style, () => conflict || dispatch(updateProfileAssetFileIndex(offset)))}

        ))}

    )
  }
);

const mapStateToProps = state => ({
  assets: state.assets,
  profile: state.profile
});

export default connect(mapStateToProps)(Wheel);
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Box from '../box';
import cx from 'classnames';
import theme from './theme.css';

class TabGroup extends PureComponent {
  render() {
    const { children, className, inverted, size, ...others } = this.props;

    const classNames = cx(theme['tab-group'], className);

    return (
      <Box data-teamleader-ui="tab-group" className={classNames} {...others}>
        {React.Children.map(children, (child) => React.cloneElement(child, { size }))}
      </Box>
    );
  }
}

TabGroup.propTypes = {
  children: PropTypes.node.isRequired,
  className: PropTypes.string,
  size: PropTypes.oneOf(['small', 'medium']),
};

export default TabGroup;
<commit_msg>Adjust markup and add a scrollable container with ref<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Box from '../box';
import cx from 'classnames';
import theme from './theme.css';

class TabGroup extends PureComponent {
  scrollContainerRef = createRef();

  render() {
    const { children, className, inverted, size, ...others } = this.props;

    const classNames = cx(theme['tab-group'], className);

    return (
      <Box
        backgroundColor="neutral"
        backgroundTint="lightest"
        data-teamleader-ui="tab-group"
        className={classNames}
        {...others}
        display="flex"
        paddingHorizontal={1}
      >
        <Box className={theme['scroll-container']} display="flex" overflowX="scroll" ref={this.scrollContainerRef}>
          {React.Children.map(children, (child) => React.cloneElement(child, { size, marginHorizontal: 1 }))}
        </Box>
      </Box>
    );
  }
}

TabGroup.propTypes = {
  children: PropTypes.node.isRequired,
  className: PropTypes.string,
  size: PropTypes.oneOf(['small', 'medium']),
};

export default TabGroup;
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////
/**
 * @module geo.gl
 */
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
/**
 * Create a new instance of pointFeature
 *
 * @class
 * @returns {ggl.pointFeature}
 */
//////////////////////////////////////////////////////////////////////////////
ggl.pointFeature = function (arg) {
  "use strict";
  if (!(this instanceof ggl.pointFeature)) {
    return new ggl.pointFeature(arg);
  }
  arg = arg || {};
  geo.pointFeature.call(this, arg);

  ////////////////////////////////////////////////////////////////////////////
  /**
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  var m_this = this,
      m_actor = null,
      s_init = this._init,
      s_update = this._update;

  function createVertexShader() {
    var vertexShaderSource = " \n\
          attribute vec3 pos; \n\
          attribute vec2 unit; \n\
          attribute float rad; \n\
          attribute vec3 fillColor; \n\
          attribute vec3 strokeColor; \n\
          attribute float alpha; \n\
          attribute float strokeWidth; \n\
          attribute float fill; \n\
          attribute float stroke; \n\
          uniform float pixelWidth; \n\
          uniform float aspect; \n\
          uniform mat4 modelViewMatrix; \n\
          uniform mat4 projectionMatrix; \n\
          varying vec3 unitVar; \n\
          varying vec4 fillColorVar; \n\
          varying vec4 strokeColorVar; \n\
          varying float radiusVar; \n\
          varying float strokeWidthVar; \n\
          varying float fillVar; \n\
          varying float strokeVar; \n\
          void main(void) \n\
          { \n\
            unitVar = vec3 (unit, 1.0); \n\
            fillColorVar = vec4 (fillColor, alpha); \n\
            strokeColorVar = vec4 (strokeColor, alpha); \n\
            strokeWidthVar = strokeWidth; \n\
            fillVar = fill; \n\
            strokeVar = stroke; \n\
            radiusVar = rad; \n\
            vec4 p = (projectionMatrix * modelViewMatrix * vec4(pos, 1.0)).xyzw; \n\
            if (p.w != 0.0) { \n\
              p = p/p.w; \n\
            } \n\
            p += (rad + strokeWidth) * vec4 (unit.x * pixelWidth, unit.y * pixelWidth * aspect, 0.0, 1.0); \n\
            gl_Position = vec4(p.xyz, 1.0); \n\
          }",
        shader = new vgl.shader(gl.VERTEX_SHADER);

    shader.setShaderSource(vertexShaderSource);
    return shader;
  }

  function createFragmentShader () {
    var fragmentShaderSource = " \n\n\
          #ifdef GL_ES \n\n\
            precision highp float; \n\n\
          #endif \n\n\
          uniform float aspect; \n\
          varying vec3 unitVar; \n\
          varying vec4 fillColorVar; \n\
          varying vec4 strokeColorVar; \n\
          varying float radiusVar; \n\
          varying float strokeWidthVar; \n\
          varying float fillVar; \n\
          varying float strokeVar; \n\
          bool to_bool (in float value) { \n\
            if (value < 0.0) \n\
              return false; \n\
            else \n\
              return true; \n\
          } \n\
          void main () { \n\
            bool fill = to_bool (fillVar); \n\
            bool stroke = to_bool (strokeVar); \n\
            vec4 strokeColor, fillColor; \n\
            // No stroke or fill implies nothing to draw \n\
            if (!fill && !stroke) \n\
              discard; \n\
            // Get normalized texture coordinates and polar r coordinate \n\
            vec2 tex = (unitVar.xy + 1.0) / 2.0; \n\
            float rad = length (unitVar.xy); \n\
            // If there is no stroke, the fill region should transition to nothing \n\
            if (!stroke) \n\
              strokeColor = vec4 (fillColorVar.rgb, 0.0); \n\
            else \n\
              strokeColor = strokeColorVar; \n\
            // Likewise, if there is no fill, the stroke should transition to nothing \n\
            if (!fill) \n\
              fillColor = vec4 (strokeColor.rgb, 0.0); \n\
            else \n\
              fillColor = fillColorVar; \n\
            float radiusWidth = radiusVar; \n\
            // Distance to antialias over \n\
            float antialiasDist = 3.0 / (2.0 * radiusVar); \n\
            if (rad < (radiusWidth / (radiusWidth + strokeWidthVar))) { \n\
              float endStep = radiusWidth / (radiusWidth + strokeWidthVar); \n\
              float step = smoothstep (endStep - antialiasDist, endStep, rad); \n\
              gl_FragColor = mix (fillColorVar, strokeColorVar, step); \n\
            } \n\
            else { \n\
              float step = smoothstep (1.0 - antialiasDist, 1.0, rad); \n\
              gl_FragColor = mix (strokeColor, vec4 (strokeColor.rgb, 0.0), step); \n\
            } \n\
            //float step = smoothstep (1.0 - antialiasDist, 1.0, rad); \n\
            //gl_FragColor = mix (color, vec4 (color.rgb, 0.0), step); \n\
          }",
        shader = new vgl.shader(gl.FRAGMENT_SHADER);
    shader.setShaderSource(fragmentShaderSource);
    return shader;
  }

  var rect = function (x, y, w, h) {
    var verts = [
        x - w, y + h,
        x - w, y - h,
        x + w, y + h,
        x - w, y - h,
        x + w, y - h,
        x + w, y + h
    ];
    return verts;
  };

// point_shader.data ('aspect', engine.canvas.width () / engine.canvas.height ());
//         point_shader.data ('pix_w', 2.0 / engine.canvas.width ());

  function createGLPoints () {
    var i, numPts = 2 * m_this.positions().length,
        alpha = 1.0, start, unit = rect(0, 0, 1, 1),
        positions = geo.transform.transformCoordinates(
                      m_this.gcs(), m_this.layer().map().gcs(),
                      m_this.positions(), 3),
        buffers = vgl.DataBuffers(1024),
        sourcePositions = vgl.sourceDataP3fv(),
        sourceUnits = vgl.sourceDataAnyfv(2,
          vgl.vertexAttributeKeys.CountAttributeIndex + 1),
        sourceRadius = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 2),
        sourceStokeWidth = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 3),
        sourceFillColor = vgl.sourceDataAnyfv(3,
          vgl.vertexAttributeKeys.CountAttributeIndex + 4),
        sourceFill = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 5),
        sourceStrokeColor = vgl.sourceDataAnyfv(3,
          vgl.vertexAttributeKeys.CountAttributeIndex + 6),
        sourceStroke = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 7),
        sourceAlpha = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 8),
        trianglesPrimitive = vgl.triangles(),
        mat = vgl.material(),
        blend = vgl.blend(),
        prog = vgl.shaderProgram(),
        vertexShader = createVertexShader(),
        fragmentShader = createFragmentShader(),
        posAttr = vgl.vertexAttribute("pos"),
        unitAttr = vgl.vertexAttribute("unit"),
        radAttr = vgl.vertexAttribute("rad"),
        stokeWidthAttr = vgl.vertexAttribute("strokeWidth"),
        fillColorAttr = vgl.vertexAttribute("fillColor"),
        fillAttr = vgl.vertexAttribute("fill"),
        strokeColorAttr = vgl.vertexAttribute("strokeColor"),
        strokeAttr = vgl.vertexAttribute("stroke"),
        alphaAttr = vgl.vertexAttribute("alpha"),
        pixelWidthUniform = new vgl.floatUniform("pixelWidth", 2.0 / m_this.renderer().width()),
        aspectUniform = new vgl.floatUniform("aspect", m_this.renderer().width() / m_this.renderer().height()),
        modelViewUniform = new vgl.modelViewUniform("modelViewMatrix"),
        projectionUniform = new vgl.projectionUniform("projectionMatrix"),
        geom = vgl.geometryData(),
        mapper = vgl.mapper();

    buffers.create ('pos', 3);
    buffers.create ('indices', 1);
    buffers.create ('unit', 2);
    buffers.create ('rad', 1);
    buffers.create ('strokeWidth', 1);
    buffers.create ('fillColor', 3);
    buffers.create ('fill', 1);
    buffers.create ('strokeColor', 3);
    buffers.create ('stroke', 1);
    buffers.create ('alpha', 1);

    // TODO: Right now this is ugly but we will fix it.
    prog.addVertexAttribute(posAttr, vgl.vertexAttributeKeys.Position);
    prog.addVertexAttribute(unitAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 1);
    prog.addVertexAttribute(radAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 2);
    prog.addVertexAttribute(stokeWidthAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 3);
    prog.addVertexAttribute(fillColorAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 4);
    prog.addVertexAttribute(fillAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 5);
    prog.addVertexAttribute(strokeColorAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 6);
    prog.addVertexAttribute(strokeAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 7);
    prog.addVertexAttribute(alphaAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 8);

    prog.addUniform(pixelWidthUniform);
    prog.addUniform(aspectUniform);
    prog.addUniform(modelViewUniform);
    prog.addUniform(projectionUniform);

    prog.addShader(fragmentShader);
    prog.addShader(vertexShader);

    mat.addAttribute(prog);
    mat.addAttribute(blend);

    m_actor = vgl.actor();
    m_actor.setMaterial(mat);

    start = buffers.alloc (3 * numPts);

    // Instructions on how to write to the buffers for specific styles
    m_this.styleMap = {
      'fill': function (color) {
        if (!color || color == 'none') {
          buffers.repeat ('fill', [-.75], start, numPts);
        }
        else {
          buffers.repeat ('fill', [.75], start, numPts);
          buffers.repeat ('fillColor', color, start, numPts);                                }
      },
      'opacity': function (opacity) {
        if (!opacity || opacity == 'none') {
          opacity = [1.0];
        }
        buffers.repeat ('alpha', opacity, start, numPts);
      },
      'radius': function (rad) {
        if (!rad || rad == 'none') {
          rad = [10.0];
        }
        buffers.repeat ('rad', rad, start, numPts);
      },
      'stroke': function (color) {
          if (!color || color == 'none') {
            buffers.repeat ('stroke', [-.75], start, numPts);
          }
          else {
            buffers.repeat ('stroke', [.75], start, numPts);
            buffers.repeat ('strokeColor', color, start, numPts);
          }
      },
      'strokeWidth': function (width) {
        if (!width || width == 'none') {
          width = [0.0];
        }
        buffers.repeat ('strokeWidth', width, start, numPts);
      }
    };

    for (i = 0; i < numPts; ++i) {
      buffers.repeat ('pos', [positions[i * 3],
                      positions[i * 3 + 1], positions[i * 3 + 2]],
                      start + i * 6, 6);
      buffers.write ('unit', unit, start + i * 6, 6);
      buffers.write("indices", [i], start + i, 1);
    }

    m_this.styleMap.fill([1.0, 0.0, 0.0]);
    m_this.styleMap.opacity();
    m_this.styleMap.radius();
    m_this.styleMap.stroke([1.0, 0.0, 0.0]);
    m_this.styleMap.strokeWidth();

    sourcePositions.pushBack(buffers.get("pos"));
    geom.addSource(sourcePositions);

    sourceUnits.pushBack(buffers.get("unit"));
    geom.addSource(sourceUnits);

    sourceRadius.pushBack(buffers.get("rad"));
    geom.addSource(sourceRadius);

    sourceStokeWidth.pushBack(buffers.get("strokeWidth"));
    geom.addSource(sourceStokeWidth);

    sourceFillColor.pushBack(buffers.get("fillColor"));
    geom.addSource(sourceFillColor);

    console.log(buffers.get("fill"));

    sourceFill.pushBack(buffers.get("fill"));
    geom.addSource(sourceFill);

    sourceStrokeColor.pushBack(buffers.get("strokeColor"));
    geom.addSource(sourceStrokeColor);

    sourceStroke.pushBack(buffers.get("stroke"));
    geom.addSource(sourceStroke);

    sourceAlpha.pushBack(buffers.get("alpha"));
    geom.addSource(sourceAlpha);

    trianglesPrimitive.setIndices(buffers.get("indices"));
    geom.addPrimitive(trianglesPrimitive);

    mapper.setGeometryData(geom);

    m_actor.setMapper(mapper);
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Initialize
   */
  ////////////////////////////////////////////////////////////////////////////
  this._init = function (arg) {
    s_init.call(m_this, arg);
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Build
   *
   * @override
   */
  ////////////////////////////////////////////////////////////////////////////
  this._build = function () {
    var style = m_this.style(),
        positions = geo.transform.transformFeature(
          m_this.renderer().map().gcs(),
          m_this,
          false
    );

    if (m_actor) {
      m_this.renderer().contextRenderer().removeActor(m_actor);
    }

    createGLPoints();

    m_this.renderer().contextRenderer().addActor(m_actor);
    m_this.renderer().contextRenderer().render();
    m_this.buildTime().modified();
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Update
   *
   * @override
   */
  ////////////////////////////////////////////////////////////////////////////
  this._update = function () {
    var style =  m_this.style();

    s_update.call(m_this);

    if (m_this.dataTime().getMTime() >= m_this.buildTime().getMTime()) {
      m_this._build();
    }

    // if (m_this.updateTime().getMTime() <= m_this.getMTime()) {
    //   if (m_this.style.color instanceof vgl.lookupTable) {
    //     vgl.utils.updateColorMappedMaterial(m_this.material(),
    //       m_this.style.color);
    //   }

    //   if (style.point_sprites === true) {
    //     if (style.point_sprites_image === null) {
    //       throw "[error] Invalid image for point sprites";
    //     }

    //     if (style.width && style.height) {
    //       m_actor.material().shaderProgram().uniform("pointSize").set(
    //         [style.width, style.height]);
    //     }
    //     else if (style.size) {
    //       m_actor.material().shaderProgram().uniform("pointSize").set(
    //         [style.size, style.size]);
    //     }
    //   } else {
    //     /// Points only has support for size
    //     if (style.size) {
    //       m_actor.material().shaderProgram().uniform("pointSize").set(
    //         style.size);
    //     }
    //   }
    // }
    m_this.updateTime().modified();
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Destroy
   */
  ////////////////////////////////////////////////////////////////////////////
  this._exit = function () {
    m_this.renderer().contextRenderer().removeActor(m_actor);
  };

  this._init(arg);
  return this;
};

inherit(ggl.pointFeature, geo.pointFeature);

// Now register it
geo.registerFeature("vgl", "point", ggl.pointFeature);
<commit_msg>Fixed anti-aliasing<commit_after>//////////////////////////////////////////////////////////////////////////////
/**
 * @module geo.gl
 */
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
/**
 * Create a new instance of pointFeature
 *
 * @class
 * @returns {ggl.pointFeature}
 */
//////////////////////////////////////////////////////////////////////////////
ggl.pointFeature = function (arg) {
  "use strict";
  if (!(this instanceof ggl.pointFeature)) {
    return new ggl.pointFeature(arg);
  }
  arg = arg || {};
  geo.pointFeature.call(this, arg);

  ////////////////////////////////////////////////////////////////////////////
  /**
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  var m_this = this,
      m_actor = null,
      s_init = this._init,
      s_update = this._update;

  function createVertexShader() {
    var vertexShaderSource = " \n\
          attribute vec3 pos; \n\
          attribute vec2 unit; \n\
          attribute float rad; \n\
          attribute vec3 fillColor; \n\
          attribute vec3 strokeColor; \n\
          attribute float alpha; \n\
          attribute float strokeWidth; \n\
          attribute float fill; \n\
          attribute float stroke; \n\
          uniform float pixelWidth; \n\
          uniform float aspect; \n\
          uniform mat4 modelViewMatrix; \n\
          uniform mat4 projectionMatrix; \n\
          varying vec3 unitVar; \n\
          varying vec4 fillColorVar; \n\
          varying vec4 strokeColorVar; \n\
          varying float radiusVar; \n\
          varying float strokeWidthVar; \n\
          varying float fillVar; \n\
          varying float strokeVar; \n\
          void main(void) \n\
          { \n\
            unitVar = vec3 (unit, 1.0); \n\
            fillColorVar = vec4 (fillColor, alpha); \n\
            strokeColorVar = vec4 (strokeColor, alpha); \n\
            strokeWidthVar = strokeWidth; \n\
            fillVar = fill; \n\
            strokeVar = stroke; \n\
            radiusVar = rad; \n\
            vec4 p = (projectionMatrix * modelViewMatrix * vec4(pos, 1.0)).xyzw; \n\
            if (p.w != 0.0) { \n\
              p = p/p.w; \n\
            } \n\
            p += (rad + strokeWidth) * vec4 (unit.x * pixelWidth, unit.y * pixelWidth * aspect, 0.0, 1.0); \n\
            gl_Position = vec4(p.xyz, 1.0); \n\
          }",
        shader = new vgl.shader(gl.VERTEX_SHADER);

    shader.setShaderSource(vertexShaderSource);
    return shader;
  }

  function createFragmentShader () {
    var fragmentShaderSource = " \n\n\
          #ifdef GL_ES \n\n\
            precision highp float; \n\n\
          #endif \n\n\
          uniform float aspect; \n\
          varying vec3 unitVar; \n\
          varying vec4 fillColorVar; \n\
          varying vec4 strokeColorVar; \n\
          varying float radiusVar; \n\
          varying float strokeWidthVar; \n\
          varying float fillVar; \n\
          varying float strokeVar; \n\
          bool to_bool (in float value) { \n\
            if (value < 0.0) \n\
              return false; \n\
            else \n\
              return true; \n\
          } \n\
          void main () { \n\
            bool fill = to_bool (fillVar); \n\
            bool stroke = to_bool (strokeVar); \n\
            vec4 strokeColor, fillColor; \n\
            // No stroke or fill implies nothing to draw \n\
            if (!fill && !stroke) \n\
              discard; \n\
            // Get normalized texture coordinates and polar r coordinate \n\
            vec2 tex = (unitVar.xy + 1.0) / 2.0; \n\
            float rad = length (unitVar.xy); \n\
            // If there is no stroke, the fill region should transition to nothing \n\
            if (!stroke) \n\
              strokeColor = vec4 (fillColorVar.rgb, 0.0); \n\
            else \n\
              strokeColor = strokeColorVar; \n\
            // Likewise, if there is no fill, the stroke should transition to nothing \n\
            if (!fill) \n\
              fillColor = vec4 (strokeColor.rgb, 0.0); \n\
            else \n\
              fillColor = fillColorVar; \n\
            float radiusWidth = radiusVar; \n\
            // Distance to antialias over \n\
            float antialiasDist = 3.0 / (2.0 * radiusVar); \n\
            if (rad < (radiusWidth / (radiusWidth + strokeWidthVar))) { \n\
              float endStep = radiusWidth / (radiusWidth + strokeWidthVar); \n\
              float step = smoothstep (endStep - antialiasDist, endStep, rad); \n\
              gl_FragColor = mix (fillColorVar, strokeColorVar, step); \n\
            } \n\
            else { \n\
              float step = smoothstep (1.0 - antialiasDist, 1.0, rad); \n\
              gl_FragColor = mix (strokeColor, vec4 (strokeColor.rgb, 0.0), step); \n\
            } \n\
            //float step = smoothstep (1.0 - antialiasDist, 1.0, rad); \n\
            //gl_FragColor = mix (color, vec4 (color.rgb, 0.0), step); \n\
          }",
        shader = new vgl.shader(gl.FRAGMENT_SHADER);
    shader.setShaderSource(fragmentShaderSource);
    return shader;
  }

  var rect = function (x, y, w, h) {
    var verts = [
        x - w, y + h,
        x - w, y - h,
        x + w, y + h,
        x - w, y - h,
        x + w, y - h,
        x + w, y + h
    ];
    return verts;
  };

// point_shader.data ('aspect', engine.canvas.width () / engine.canvas.height ());
//         point_shader.data ('pix_w', 2.0 / engine.canvas.width ());

  function createGLPoints () {
    var i, numPts = 2 * m_this.positions().length,
        alpha = 1.0, start, unit = rect(0, 0, 1, 1),
        positions = geo.transform.transformCoordinates(
                      m_this.gcs(), m_this.layer().map().gcs(),
                      m_this.positions(), 3),
        buffers = vgl.DataBuffers(1024),
        sourcePositions = vgl.sourceDataP3fv(),
        sourceUnits = vgl.sourceDataAnyfv(2,
          vgl.vertexAttributeKeys.CountAttributeIndex + 1),
        sourceRadius = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 2),
        sourceStokeWidth = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 3),
        sourceFillColor = vgl.sourceDataAnyfv(3,
          vgl.vertexAttributeKeys.CountAttributeIndex + 4),
        sourceFill = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 5),
        sourceStrokeColor = vgl.sourceDataAnyfv(3,
          vgl.vertexAttributeKeys.CountAttributeIndex + 6),
        sourceStroke = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 7),
        sourceAlpha = vgl.sourceDataAnyfv(1,
          vgl.vertexAttributeKeys.CountAttributeIndex + 8),
        trianglesPrimitive = vgl.triangles(),
        mat = vgl.material(),
        blend = vgl.blend(),
        prog = vgl.shaderProgram(),
        vertexShader = createVertexShader(),
        fragmentShader = createFragmentShader(),
        posAttr = vgl.vertexAttribute("pos"),
        unitAttr = vgl.vertexAttribute("unit"),
        radAttr = vgl.vertexAttribute("rad"),
        stokeWidthAttr = vgl.vertexAttribute("strokeWidth"),
        fillColorAttr = vgl.vertexAttribute("fillColor"),
        fillAttr = vgl.vertexAttribute("fill"),
        strokeColorAttr = vgl.vertexAttribute("strokeColor"),
        strokeAttr = vgl.vertexAttribute("stroke"),
        alphaAttr = vgl.vertexAttribute("alpha"),
        pixelWidthUniform = new vgl.floatUniform("pixelWidth", 2.0 / m_this.renderer().width()),
        aspectUniform = new vgl.floatUniform("aspect", m_this.renderer().width() / m_this.renderer().height()),
        modelViewUniform = new vgl.modelViewUniform("modelViewMatrix"),
        projectionUniform = new vgl.projectionUniform("projectionMatrix"),
        geom = vgl.geometryData(),
        mapper = vgl.mapper();

    buffers.create ('pos', 3);
    buffers.create ('indices', 1);
    buffers.create ('unit', 2);
    buffers.create ('rad', 1);
    buffers.create ('strokeWidth', 1);
    buffers.create ('fillColor', 3);
    buffers.create ('fill', 1);
    buffers.create ('strokeColor', 3);
    buffers.create ('stroke', 1);
    buffers.create ('alpha', 1);

    // TODO: Right now this is ugly but we will fix it.
    prog.addVertexAttribute(posAttr, vgl.vertexAttributeKeys.Position);
    prog.addVertexAttribute(unitAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 1);
    prog.addVertexAttribute(radAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 2);
    prog.addVertexAttribute(stokeWidthAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 3);
    prog.addVertexAttribute(fillColorAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 4);
    prog.addVertexAttribute(fillAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 5);
    prog.addVertexAttribute(strokeColorAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 6);
    prog.addVertexAttribute(strokeAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 7);
    prog.addVertexAttribute(alphaAttr, vgl.vertexAttributeKeys.CountAttributeIndex + 8);

    prog.addUniform(pixelWidthUniform);
    prog.addUniform(aspectUniform);
    prog.addUniform(modelViewUniform);
    prog.addUniform(projectionUniform);

    prog.addShader(fragmentShader);
    prog.addShader(vertexShader);

    mat.addAttribute(prog);
    mat.addAttribute(blend);

    m_actor = vgl.actor();
    m_actor.setMaterial(mat);

    start = buffers.alloc (3 * numPts);

    // Instructions on how to write to the buffers for specific styles
    m_this.styleMap = {
      'fill': function (color) {
        if (!color || color == 'none') {
          buffers.repeat ('fill', [-.75], start, numPts);
        }
        else {
          buffers.repeat ('fill', [.75], start, numPts);
          buffers.repeat ('fillColor', color, start, numPts);                                }
      },
      'opacity': function (opacity) {
        if (!opacity || opacity == 'none') {
          opacity = [1.0];
        }
        buffers.repeat ('alpha', opacity, start, numPts);
      },
      'radius': function (rad) {
        if (!rad || rad == 'none') {
          rad = [4.0];
        }
        buffers.repeat ('rad', rad, start, numPts);
      },
      'stroke': function (color) {
          if (!color || color == 'none') {
            buffers.repeat ('stroke', [-.75], start, numPts);
          }
          else {
            buffers.repeat ('stroke', [.75], start, numPts);
            buffers.repeat ('strokeColor', color, start, numPts);
          }
      },
      'strokeWidth': function (width) {
        if (!width || width == 'none') {
          width = [10.0];
        }
        buffers.repeat ('strokeWidth', width, start, numPts);
      }
    };

    for (i = 0; i < numPts; ++i) {
      buffers.repeat ('pos', [positions[i * 3],
                      positions[i * 3 + 1], positions[i * 3 + 2]],
                      start + i * 6, 6);
      buffers.write ('unit', unit, start + i * 6, 6);
      buffers.write("indices", [i], start + i, 1);
    }

    m_this.styleMap.fill([1.0, 0.0, 0.0]);
    m_this.styleMap.opacity();
    m_this.styleMap.radius();
    m_this.styleMap.stroke([0.0, 1.0, 0.0]);
    m_this.styleMap.strokeWidth();

    sourcePositions.pushBack(buffers.get("pos"));
    geom.addSource(sourcePositions);

    sourceUnits.pushBack(buffers.get("unit"));
    geom.addSource(sourceUnits);

    sourceRadius.pushBack(buffers.get("rad"));
    geom.addSource(sourceRadius);

    sourceStokeWidth.pushBack(buffers.get("strokeWidth"));
    geom.addSource(sourceStokeWidth);

    sourceFillColor.pushBack(buffers.get("fillColor"));
    geom.addSource(sourceFillColor);

    sourceFill.pushBack(buffers.get("fill"));
    geom.addSource(sourceFill);

    sourceStrokeColor.pushBack(buffers.get("strokeColor"));
    geom.addSource(sourceStrokeColor);

    sourceStroke.pushBack(buffers.get("stroke"));
    geom.addSource(sourceStroke);

    sourceAlpha.pushBack(buffers.get("alpha"));
    geom.addSource(sourceAlpha);

    trianglesPrimitive.setIndices(buffers.get("indices"));
    geom.addPrimitive(trianglesPrimitive);

    mapper.setGeometryData(geom);

    m_actor.setMapper(mapper);
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Initialize
   */
  ////////////////////////////////////////////////////////////////////////////
  this._init = function (arg) {
    s_init.call(m_this, arg);
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Build
   *
   * @override
   */
  ////////////////////////////////////////////////////////////////////////////
  this._build = function () {
    var style = m_this.style(),
        positions = geo.transform.transformFeature(
          m_this.renderer().map().gcs(),
          m_this,
          false
    );

    if (m_actor) {
      m_this.renderer().contextRenderer().removeActor(m_actor);
    }

    createGLPoints();

    m_this.renderer().contextRenderer().addActor(m_actor);
    m_this.renderer().contextRenderer().render();
    m_this.buildTime().modified();
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Update
   *
   * @override
   */
  ////////////////////////////////////////////////////////////////////////////
  this._update = function () {
    var style =  m_this.style();

    s_update.call(m_this);

    if (m_this.dataTime().getMTime() >= m_this.buildTime().getMTime()) {
      m_this._build();
    }

    if (m_this.updateTime().getMTime() < m_this.getMTime()) {
      m_this._build();
    }
    m_this.updateTime().modified();
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Destroy
   */
  ////////////////////////////////////////////////////////////////////////////
  this._exit = function () {
    m_this.renderer().contextRenderer().removeActor(m_actor);
  };

  this._init(arg);
  return this;
};

inherit(ggl.pointFeature, geo.pointFeature);

// Now register it
geo.registerFeature("vgl", "point", ggl.pointFeature);
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import Promotion from '../assets/Promotion'
import SearchControl from '../forms/SearchControl'
import StreamContainer from '../../containers/StreamContainer'
import { TabListButtons } from '../tabs/TabList'
import { MainView } from '../views/MainView'

export const Search = ({
  coverDPI,
  isLoggedIn,
  onChange,
  onClickTrackCredits,
  onSubmit,
  promotion,
  streamAction,
  streamKey,
  tabs,
  terms,
  type,
  }) =>
  <MainView className="Search">
    <Promotion
      coverDPI={coverDPI}
      isLoggedIn={isLoggedIn}
      onClickTrackCredits={onClickTrackCredits}
      promotion={promotion}
    />
    <form className="SearchBar" onSubmit={onSubmit}>
      <SearchControl onChange={onChange} text={terms} />
      <TabListButtons
        activeType={type}
        className="SearchTabList"
        onTabClick={onChange}
        tabClasses="LabelTab SearchLabelTab"
        tabs={tabs}
      />
    </form>
    <StreamContainer key={streamKey} action={streamAction} />
  </MainView>

Search.propTypes = {
  coverDPI: PropTypes.string.isRequired,
  isLoggedIn: PropTypes.bool.isRequired,
  onChange: PropTypes.func.isRequired,
  onClickTrackCredits: PropTypes.func.isRequired,
  onSubmit: PropTypes.func.isRequired,
  promotion: PropTypes.object,
  streamAction: PropTypes.object,
  streamKey: PropTypes.string.isRequired,
  tabs: PropTypes.array.isRequired,
  terms: PropTypes.string.isRequired,
  type: PropTypes.string.isRequired,
}

export default Search

<commit_msg>Update the search container when terms change.<commit_after>import React, { PropTypes } from 'react'
import Promotion from '../assets/Promotion'
import SearchControl from '../forms/SearchControl'
import StreamContainer from '../../containers/StreamContainer'
import { TabListButtons } from '../tabs/TabList'
import { MainView } from '../views/MainView'

export const Search = ({
  coverDPI,
  isLoggedIn,
  onChange,
  onClickTrackCredits,
  onSubmit,
  promotion,
  streamAction,
  streamKey,
  tabs,
  terms,
  type,
  }) =>
  <MainView className="Search">
    <Promotion
      coverDPI={coverDPI}
      isLoggedIn={isLoggedIn}
      onClickTrackCredits={onClickTrackCredits}
      promotion={promotion}
    />
    <form className="SearchBar" onSubmit={onSubmit}>
      <SearchControl key={terms} onChange={onChange} text={terms} />
      <TabListButtons
        activeType={type}
        className="SearchTabList"
        onTabClick={onChange}
        tabClasses="LabelTab SearchLabelTab"
        tabs={tabs}
      />
    </form>
    <StreamContainer key={streamKey} action={streamAction} />
  </MainView>

Search.propTypes = {
  coverDPI: PropTypes.string.isRequired,
  isLoggedIn: PropTypes.bool.isRequired,
  onChange: PropTypes.func.isRequired,
  onClickTrackCredits: PropTypes.func.isRequired,
  onSubmit: PropTypes.func.isRequired,
  promotion: PropTypes.object,
  streamAction: PropTypes.object,
  streamKey: PropTypes.string.isRequired,
  tabs: PropTypes.array.isRequired,
  terms: PropTypes.string.isRequired,
  type: PropTypes.string.isRequired,
}

export default Search

<|endoftext|>


<commit_before>var Conversation = function(speciesList) {
	this.lastAnswer = null;
	this.lastAction = Date.now();
	this.firstmessage = true;
	this.inFindingProcess = false;

	this.speciesList = speciesList;

	let commonNames = speciesList.map((obj)=>obj.triname);
	let scientificNames = speciesList.map((obj)=>obj.sciname);
  this.speciesNames = commonNames.concat(scientificNames);

	this.location = null;
	this.species = null;

	this.isActive = function(){
			let diff = this.lastAction - Date.now();
			let fiveMinInMs = 1000 * 60 * 5;
			return diff <= fiveMinInMs;

	};
	this.setLocation = function(location){
		this.location = location
	};
	this.processMessage = function(message) {
		console.log("Input> " + message);
    this.lastAction = Date.now();
		var splitedMessage = message.split(/[ ,]+/);

		if(this.firstmessage || match(splitedMessage,["hey", "moin", "hallo", "hi", "servus"])) {
			this.firstmessage = false;
			var startText = 'Hey du, ich bin BioDiv und kann weiterhelfen, wenn du seltene Muscheln / Säugetiere oder Fische in deiner Umgebung gesichtet hast. ';

			var answerOptions = ["Hilfe", "Fund melden"];

			return { answer: startText, answerOptions: answerOptions };
		}
		let yes = ["ja", "ok", "jo", "jup"];
		let no = ["nein", "nö", "ne", "auf gar keinen fall", "halt die fresse"];

    if(match(splitedMessage, yes.concat(no))) {
			var userAnswer = message;
			var answerOptions = [];

			this.lastAnswer = null;
			if(match(splitedMessage, yes)) {
				var jaText = "Ich halte Dich auf dem Laufenden. 👍";
				return { answer: jaText, answerOptions: answerOptions };
			} else {
				var neinText = "Ok, frag' einfach, wenn du wissen willst, wie der Status ist. 😁 Ich bin bis auf weiteres stumm. 🙈🙊🙉";
				return { answer: neinText, answerOptions: answerOptions };
			}

		}

		if(match([message], ["Fund melden"])) {
			var answerOptions = [];

			var helpText = 'ℹ Alles klar du, dann lass uns loslegen und deinen Fund zusammen aufnehmen! Was für eine Spezies hast du denn gesehen?';

      this.inFindingProcess = true;

			return { answer: helpText, answerOptions: answerOptions };
		}

		if(this.inFindingProcess){

    	console.log(splitedMessage);
    	console.log(this.speciesCommonNames);
    	console.log(this.speciesSientificNames);

    	if(match([message],["Location set"])){
        return {
          answer: "Nun weiß ich schon wo du dich befindest, Vielleicht möchtest du noch mehr angeben?",
          answerOptions: ["Nachweisquallität", "Nachweismethode", "Fund speichern"]
        };
			}
			else if(match(splitedMessage,["Nachweismethode"])){
        return {
          answer: "Okay welche der folgenden Nachweismethoden wurde verwendet?",
          answerOptions: [""]
        };
			}
			else if(match(splitedMessage,["Nachweisquallität"])){
        return {
          answer: "Wie war die genaue Nachweisquallität?",
          answerOptions: ["Nachweisquallität", "Nachweismethode"]
        };
			}
    	else if(match([message],this.speciesNames)){

				let potentialSpecies = this.speciesList.filter((species)=> {

					let nameSplits = species.triname.split(" ");
					nameSplits = nameSplits.concat(species.sciname.split(" "));

					console.log("nameSplits",nameSplits);
					return match(splitedMessage,nameSplits )
        });

				console.log("potentialSpecies", potentialSpecies);

				if(potentialSpecies.length == 0 ){
          return {
            answer: "Irgendwas ist hier schief gelaufen :( Ich konnte irgendwie keine Spezies finden ... "
          };
				}
				else if (potentialSpecies.length == 1 ){
          return {
            answer: "Sehr schön, hab ich verstanden du hast " + message + " bei dir gesehen. " +
            "\n Es wäre super wenn du mir noch deinen Standort zeigen könntest?"
          };
				}else {
          return {
            answer: "Huch da brauch ich noch ein wenig mehr Infos.\nEs gibt mehrere Spezies, bitte wähle die richtige aus: ",
            answerOptions: potentialSpecies.map((species)=>species.triname)
          };
				}

			}

    	else if(this.speciesName == null){

        console.log("Choose species text ", this.speciesCommonNames);
        return {
          answer: "Leider habe ich dich nicht so recht verstanden, hier einige Vorschläge was für Spezies ich so im Angebot hätte",
          answerOptions: this.species.map((species)=>species.triname)
        }

			}

		}

		return {
      answer: "Ich konnte dich leider nicht verstehen... 😰",
      answerOptions: ["Hilfe"]
    }

	};

	return this;
};

function match(splitedMessage, keyWords) {

	for(var word in splitedMessage) {
		for(var keyWord in keyWords) {
			var lowerCaseWord = splitedMessage[word].toLowerCase();
			var lowerCaseKeyword = keyWords[keyWord].toLowerCase();

			if(lowerCaseWord == lowerCaseKeyword) {
				return true;
			}
		}
	}

	return false;
}

module.exports = Conversation;
<commit_msg>- fix typo<commit_after>var Conversation = function(speciesList) {
	this.lastAnswer = null;
	this.lastAction = Date.now();
	this.firstmessage = true;
	this.inFindingProcess = false;

	this.speciesList = speciesList;

	let commonNames = speciesList.map((obj)=>obj.triname);
	let scientificNames = speciesList.map((obj)=>obj.sciname);
  this.speciesNames = commonNames.concat(scientificNames);

	this.location = null;
	this.species = null;

	this.isActive = function(){
			let diff = this.lastAction - Date.now();
			let fiveMinInMs = 1000 * 60 * 5;
			return diff <= fiveMinInMs;

	};
	this.setLocation = function(location){
		this.location = location
	};
	this.processMessage = function(message) {
		console.log("Input> " + message);
    this.lastAction = Date.now();
		var splitedMessage = message.split(/[ ,]+/);

		if(this.firstmessage || match(splitedMessage,["hey", "moin", "hallo", "hi", "servus"])) {
			this.firstmessage = false;
			var startText = 'Hey du, ich bin BioDiv und kann weiterhelfen, wenn du seltene Muscheln / Säugetiere oder Fische in deiner Umgebung gesichtet hast. ';

			var answerOptions = ["Hilfe", "Fund melden"];

			return { answer: startText, answerOptions: answerOptions };
		}
		let yes = ["ja", "ok", "jo", "jup"];
		let no = ["nein", "nö", "ne", "auf gar keinen fall", "halt die fresse"];

    if(match(splitedMessage, yes.concat(no))) {
			var userAnswer = message;
			var answerOptions = [];

			this.lastAnswer = null;
			if(match(splitedMessage, yes)) {
				var jaText = "Ich halte Dich auf dem Laufenden. 👍";
				return { answer: jaText, answerOptions: answerOptions };
			} else {
				var neinText = "Ok, frag' einfach, wenn du wissen willst, wie der Status ist. 😁 Ich bin bis auf weiteres stumm. 🙈🙊🙉";
				return { answer: neinText, answerOptions: answerOptions };
			}

		}

		if(match([message], ["Fund melden"])) {
			var answerOptions = [];

			var helpText = 'ℹ Alles klar du, dann lass uns loslegen und deinen Fund zusammen aufnehmen! Was für eine Spezies hast du denn gesehen?';

      this.inFindingProcess = true;

			return { answer: helpText, answerOptions: answerOptions };
		}

		if(this.inFindingProcess){

    	console.log(splitedMessage);
    	console.log(this.speciesCommonNames);
    	console.log(this.speciesSientificNames);

    	if(match([message],["Location set"])){
        return {
          answer: "Nun weiß ich schon wo du dich befindest, Vielleicht möchtest du noch mehr angeben?",
          answerOptions: ["Nachweisquallität", "Nachweismethode", "Fund speichern"]
        };
			}
			else if(match(splitedMessage,["Nachweismethode"])){
        return {
          answer: "Okay welche der folgenden Nachweismethoden wurde verwendet?",
          answerOptions: [""]
        };
			}
			else if(match(splitedMessage,["Nachweisquallität"])){
        return {
          answer: "Wie war die genaue Nachweisquallität?",
          answerOptions: ["Nachweisquallität", "Nachweismethode"]
        };
			}
    	else if(match([message],this.speciesNames)){

				let potentialSpecies = this.speciesList.filter((species)=> {

					let nameSplits = species.triname.split(" ");
					nameSplits = nameSplits.concat(species.sciname.split(" "));

					console.log("nameSplits",nameSplits);
					return match(splitedMessage,nameSplits )
        });

				console.log("potentialSpecies", potentialSpecies);

				if(potentialSpecies.length == 0 ){
          return {
            answer: "Irgendwas ist hier schief gelaufen :( Ich konnte irgendwie keine Spezies finden ... "
          };
				}
				else if (potentialSpecies.length == 1 ){
          return {
            answer: "Sehr schön, hab ich verstanden du hast " + message + " bei dir gesehen. " +
            "\n Es wäre super wenn du mir noch deinen Standort zeigen könntest?"
          };
				}else {
          return {
            answer: "Huch da brauch ich noch ein wenig mehr Infos.\nEs gibt mehrere Spezies, bitte wähle die richtige aus: ",
            answerOptions: potentialSpecies.map((species)=>species.triname)
          };
				}

			}

    	else if(this.speciesName == null){

        console.log("Choose species text ", this.speciesCommonNames);
        return {
          answer: "Leider habe ich dich nicht so recht verstanden, hier einige Vorschläge was für Spezies ich so im Angebot hätte",
          answerOptions: this.speciesList.map((species)=>species.triname)
        }

			}

		}

		return {
      answer: "Ich konnte dich leider nicht verstehen... 😰",
      answerOptions: ["Hilfe"]
    }

	};

	return this;
};

function match(splitedMessage, keyWords) {

	for(var word in splitedMessage) {
		for(var keyWord in keyWords) {
			var lowerCaseWord = splitedMessage[word].toLowerCase();
			var lowerCaseKeyword = keyWords[keyWord].toLowerCase();

			if(lowerCaseWord == lowerCaseKeyword) {
				return true;
			}
		}
	}

	return false;
}

module.exports = Conversation;
<|endoftext|>


<commit_before>/*global window:false*/

(function(context) {
    'use strict';

    var win = context, doc = win.document;

    var global_instance_name = 'cbinstance';

    /*!
     * contentloaded.js
     *
     * Author: Diego Perini (diego.perini at gmail.com)
     * Summary: cross-browser wrapper for DOMContentLoaded
     * Updated: 20101020
     * License: MIT
     * Version: 1.2
     *
     * URL:
     * http://javascript.nwbox.com/ContentLoaded/
     * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
     *
     */
    // @win window reference
    // @fn function reference
    function contentLoaded(win, fn) {
        var done = false, top = true,
        doc = win.document, root = doc.documentElement,

        add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
        rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
        pre = doc.addEventListener ? '' : 'on',

        init = function(e) {
            if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
            (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
            if (!done && (done = true)) fn.call(win, e.type || e);
        },

        poll = function() {
            try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }
            init('poll');
        };

        if (doc.readyState == 'complete') fn.call(win, 'lazy');
        else {
            if (doc.createEventObject && root.doScroll) {
                try { top = !win.frameElement; } catch(e) { }
                if (top) poll();
            }
            doc[add](pre + 'DOMContentLoaded', init, false);
            doc[add](pre + 'readystatechange', init, false);
            win[add](pre + 'load', init, false);
        }
    }

    var Cookies = {
        get: function (key) {
            return decodeURIComponent(doc.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + encodeURIComponent(key).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1')) || null;
        },
        set: function (key, val, end, path, domain, secure) {
            if (!key || /^(?:expires|max\-age|path|domain|secure)$/i.test(key)) {
                return false;
            }
            var expires = '';
            if (end) {
                switch (end.constructor) {
                    case Number:
                        expires = end === Infinity ? '; expires=Fri, 31 Dec 9999 23:59:59 GMT' : '; max-age=' + end;
                        break;
                    case String:
                        expires = '; expires=' + end;
                    break;
                    case Date:
                        expires = '; expires=' + end.toUTCString();
                    break;
                }
            }
            doc.cookie = encodeURIComponent(key) + '=' + encodeURIComponent(val) + expires + (domain ? '; domain=' + domain : '') + (path ? '; path=' + path : '') + (secure ? '; secure' : '');
            return true;
        },
        has: function (key) {
            return (new RegExp('(?:^|;\\s*)' + encodeURIComponent(key).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=')).test(doc.cookie);
        },
        remove: function (key, path, domain) {
            if (!key || !this.has(key)) { return false; }
            doc.cookie = encodeURIComponent(key) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + ( domain ? '; domain=' + domain : '') + ( path ? '; path=' + path : '');
            return true;
        }
    };

    var Utils = {

        // merge objects and whatnot
        merge: function(){
            var obj = {},
                i = 0,
                al = arguments.length,
                key;
            if (0 === al) {
                return obj;
            }
            for (; i < al; i++) {
                for (key in arguments[i]) {
                    if (arguments[i].hasOwnProperty(key)) {
                        obj[key] = arguments[i][key];
                    }
                }
            }
            return obj;
        },

        str2bool: function(str) {
            str = '' + str;
            switch (str.toLowerCase()) {
                case 'false':
                case 'no':
                case '0':
                case '':
                    return false;
                default:
                    return true;
                }
        },

        fade_in: function(el) {
            if (el.style.opacity < 1) {
                el.style.opacity = (parseFloat(el.style.opacity) + 0.05).toFixed(2);
                win.setTimeout(function(){
                    Utils.fade_in(el);
                }, 50);
            }
        },

        get_data_attribs: function(script) {
            var data = {};
            if (script.hasOwnProperty('dataset')) {
                data = script.dataset;
            } else {
                var attribs = script.attributes;
                var key;
                for (key in attribs) {
                    if (attribs.hasOwnProperty(key)) {
                        var attr = attribs[key];
                        if (/^data-/.test(attr.name)) {
                            /*
                            var camel_case = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
                                return $1.toUpperCase();
                            });
                            */
                            var name = attr.name.substr(5);
                            data[name] = attr.value;
                        }
                    }
                }
            }
            return data;
        },

        find_script_by_id: function(id) {
            var scripts = doc.getElementsByTagName('script');
            for (var i = 0, l = scripts.length; i < l; i++) {
                if (id === scripts[i].id) {
                    return scripts[i];
                }
            }
            return null;
        }

    };

    var Cookiebanner = context.Cookiebanner = function(opts) {
        this.init(opts);
    };

    Cookiebanner.prototype = {

        // for testing stuff from the outside mostly
        cookiejar: Cookies,

        init: function(opts) {

            this.inserted = false;
            this.closed = false;
            this.test_mode = false; // TODO: implement

            var default_text = 'We use cookies to enhance your experience. ' +
                'By continuing to visit this site you agree to our use of cookies.';
            var default_link = 'Learn more';

            this.default_options = {
                // autorun: true,
                cookie: 'cookiebanner-accepted',
                debug: false,
                'cookie-path': '/',
                expires: Infinity,
                zindex: 255,
                mask: false,
                'mask-opacity': 0.5,
                'mask-background': '#000',
                height: 'auto',
                'min-height': '21px',
                bg: '#000',
                fg: '#ddd',
                link: '#aaa',
                position: 'bottom',
                message: default_text,
                linkmsg: default_link,
                moreinfo: 'http://aboucookies.org',
                effect: null,
                instance: global_instance_name
            };

            this.options = this.default_options;
            this.script_el = Utils.find_script_by_id('cookiebanner');

            if (this.script_el) {
                var data_options = Utils.get_data_attribs(this.script_el);
                this.options = Utils.merge(this.options, data_options);
            }

            // allowing opts passed to the ctor to override everything
            if (opts) {
                this.options = Utils.merge(this.options, opts);
            }

            // allows customizing the global instance name via options too
            global_instance_name = this.options.instance;

            // TODO: parse/validate other options that can benefit
            this.options.zindex = parseInt(this.options.zindex, 10);
            this.options.mask = Utils.str2bool(this.options.mask);

            // check for a possible global callback specified as a string
            if ('string' === typeof this.options.expires) {
                if ('function' === typeof context[this.options.expires]) {
                    this.options.expires = context[this.options.expires];
                }
            }

            // check if expires is a callback
            if ('function' === typeof this.options.expires) {
                // TODO: this might not always be as simple as this
                this.options.expires = this.options.expires();
            }

            // Proceed with our plans only if we're invoked via a


<commit_before>import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/dialog/dialog.css'
import 'codemirror/addon/search/matchesonscrollbar.css'

import CodeMirror from 'codemirror'
import 'codemirror/mode/markdown/markdown.js'
import 'codemirror/addon/scroll/scrollpastend.js'
import 'codemirror/keymap/vim.js'
import 'codemirror/keymap/emacs.js'
import 'codemirror/keymap/sublime.js'
import 'codemirror/addon/search/search.js'
import 'codemirror/addon/search/searchcursor.js'
import 'codemirror/addon/search/jump-to-line.js'
import 'codemirror/addon/dialog/dialog.js'
import 'codemirror/addon/search/match-highlighter.js'
import 'codemirror/addon/search/matchesonscrollbar.js'
import 'codemirror/addon/selection/active-line.js'

import { syncPreview } from './sync_scroll'

// load all the themes
export const themes = ['3024-day', '3024-night', 'abcdef', 'ambiance-mobile', 'ambiance', 'base16-dark', 'base16-light', 'bespin', 'blackboard', 'cobalt', 'colorforth', 'dracula', 'duotone-dark', 'duotone-light', 'eclipse', 'elegant', 'erlang-dark', 'hopscotch', 'icecoder', 'isotope', 'lesser-dark', 'liquibyte', 'material', 'mbo', 'mdn-like', 'midnight', 'monokai', 'neat', 'neo', 'night', 'panda-syntax', 'paraiso-dark', 'paraiso-light', 'pastel-on-dark', 'railscasts', 'rubyblue', 'seti', 'solarized', 'the-matrix', 'tomorrow-night-bright', 'tomorrow-night-eighties', 'ttcn', 'twilight', 'vibrant-ink', 'xq-dark', 'xq-light', 'yeti', 'zenburn']
themes.forEach((theme) => {
  require(`codemirror/theme/${theme}.css`)
})

const mac = CodeMirror.keyMap['default'] === CodeMirror.keyMap.macDefault
const ctrl = mac ? 'Cmd' : 'Ctrl'

const editor = CodeMirror.fromTextArea(document.getElementById('editor'), {
  lineNumbers: true,
  mode: 'markdown',
  theme: 'blackboard',
  lineWrapping: true,
  scrollPastEnd: true,
  autofocus: true,
  styleActiveLine: { nonEmpty: true }
})

editor.on('scroll', (instance) => {
  syncPreview()
})

// custom keyboard shortcuts
const extraKeys = { 'Alt-F': 'findPersistent' }
extraKeys[`${ctrl}-B`] = (cm) => {
  document.querySelector('i.fa-bold').click()
}
extraKeys[`${ctrl}-I`] = (cm) => {
  document.querySelector('i.fa-italic').click()
}
extraKeys[`${ctrl}-U`] = (cm) => {
  document.querySelector('i.fa-underline').click()
}
extraKeys[`${ctrl}-,`] = (cm) => {
  document.querySelector('i.fa-cog').click()
}
editor.setOption('extraKeys', extraKeys)

// default implementation of vim commands
CodeMirror.Vim.defineEx('w', 'w', (cm, input) => {
  console.log('write')
})
CodeMirror.Vim.defineEx('q', 'q', (cm, input) => {
  if (input.input === 'q') {
    console.log('quit')
  } else if (input.input === 'q!') {
    console.log('force quit')
  }
})
CodeMirror.Vim.defineEx('wq', 'wq', (cm, input) => {
  console.log('write then quit')
})

// custom commands
CodeMirror.commands.toUpperCase = (cm) => {
  cm.replaceSelection(cm.getSelection().toUpperCase())
}
CodeMirror.commands.toLowerCase = (cm) => {
  cm.replaceSelection(cm.getSelection().toLowerCase())
}

export default editor
<commit_msg>Set editor tabSize to 8<commit_after>import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/dialog/dialog.css'
import 'codemirror/addon/search/matchesonscrollbar.css'

import CodeMirror from 'codemirror'
import 'codemirror/mode/markdown/markdown.js'
import 'codemirror/addon/scroll/scrollpastend.js'
import 'codemirror/keymap/vim.js'
import 'codemirror/keymap/emacs.js'
import 'codemirror/keymap/sublime.js'
import 'codemirror/addon/search/search.js'
import 'codemirror/addon/search/searchcursor.js'
import 'codemirror/addon/search/jump-to-line.js'
import 'codemirror/addon/dialog/dialog.js'
import 'codemirror/addon/search/match-highlighter.js'
import 'codemirror/addon/search/matchesonscrollbar.js'
import 'codemirror/addon/selection/active-line.js'

import { syncPreview } from './sync_scroll'

// load all the themes
export const themes = ['3024-day', '3024-night', 'abcdef', 'ambiance-mobile', 'ambiance', 'base16-dark', 'base16-light', 'bespin', 'blackboard', 'cobalt', 'colorforth', 'dracula', 'duotone-dark', 'duotone-light', 'eclipse', 'elegant', 'erlang-dark', 'hopscotch', 'icecoder', 'isotope', 'lesser-dark', 'liquibyte', 'material', 'mbo', 'mdn-like', 'midnight', 'monokai', 'neat', 'neo', 'night', 'panda-syntax', 'paraiso-dark', 'paraiso-light', 'pastel-on-dark', 'railscasts', 'rubyblue', 'seti', 'solarized', 'the-matrix', 'tomorrow-night-bright', 'tomorrow-night-eighties', 'ttcn', 'twilight', 'vibrant-ink', 'xq-dark', 'xq-light', 'yeti', 'zenburn']
themes.forEach((theme) => {
  require(`codemirror/theme/${theme}.css`)
})

const mac = CodeMirror.keyMap['default'] === CodeMirror.keyMap.macDefault
const ctrl = mac ? 'Cmd' : 'Ctrl'

const editor = CodeMirror.fromTextArea(document.getElementById('editor'), {
  lineNumbers: true,
  mode: 'markdown',
  theme: 'blackboard',
  lineWrapping: true,
  scrollPastEnd: true,
  autofocus: true,
  styleActiveLine: { nonEmpty: true },
  tabSize: 8
})

editor.on('scroll', (instance) => {
  syncPreview()
})

// custom keyboard shortcuts
const extraKeys = { 'Alt-F': 'findPersistent' }
extraKeys[`${ctrl}-B`] = (cm) => {
  document.querySelector('i.fa-bold').click()
}
extraKeys[`${ctrl}-I`] = (cm) => {
  document.querySelector('i.fa-italic').click()
}
extraKeys[`${ctrl}-U`] = (cm) => {
  document.querySelector('i.fa-underline').click()
}
extraKeys[`${ctrl}-,`] = (cm) => {
  document.querySelector('i.fa-cog').click()
}
editor.setOption('extraKeys', extraKeys)

// default implementation of vim commands
CodeMirror.Vim.defineEx('w', 'w', (cm, input) => {
  console.log('write')
})
CodeMirror.Vim.defineEx('q', 'q', (cm, input) => {
  if (input.input === 'q') {
    console.log('quit')
  } else if (input.input === 'q!') {
    console.log('force quit')
  }
})
CodeMirror.Vim.defineEx('wq', 'wq', (cm, input) => {
  console.log('write then quit')
})

// custom commands
CodeMirror.commands.toUpperCase = (cm) => {
  cm.replaceSelection(cm.getSelection().toUpperCase())
}
CodeMirror.commands.toLowerCase = (cm) => {
  cm.replaceSelection(cm.getSelection().toLowerCase())
}

export default editor
<|endoftext|>