<commit_before>module.exports = [
"# The Homebrewery",
"Welcome traveler from an antique land. Please sit and tell us of what you have seen. The unheard of monsters, who slither and bite.",
"",
"Tell us of the wondrous items and and artifacts you have found, their mysteries yet to be unlocked. Of the vexing vocations and surprising skills you have seen.",
"",
"### Homebrew made easy",
"The Homebrewery allows for the creation and sharing of authentic looking Fifth-Edition homebrews, with just text editing. It accomplishes this by using [Markdown](https://help.github.com/articles/markdown-basics/) along with some custom CSS-stlying.",
"",
"Stop worrying about learning photoshop, fiddling with spacing, or tracking down the PHB assets. Just focus on making your homebrew **great**.",
"",
"**Try it! **Simply edit the text on the left and watch it *update live* on the right.",
"",
"#### Features",
"* Monster Stat Blocks",
"* Full class tables",
"* Notes and Tables",
"* Images",
"* Vertical spacing, column breaks, and mutliple Pages",
"",
"",
"#### Snippets",
"If you aren't used the Markdown-style syntax, don't worry! I've provided several **snippets** at the top of the editor. When clicked, these will *inject* text wherever your text cursor was.",
"",
"Each snippet is a common format from the Player's Handbook or is a feature of The Homebrewery. You'll never have to memorize exactly how a Monster Stat Block is suppose to be formatted.",
"",
"### Editing and Sharing",
"When you create your own homebrew you will be given a *edit url* and a *share url*.  Any changes you make will be automatically saved to the database within a few seconds. Anyone with the edit url will be able to make edits to your homebrew. So be careful about who you share it with.",
"",
"Anyone with the *share url* will be able to access a read-only version of your homebrew.",
"",
"",
"> ##### Words of Caution",
"> ___",
"> * **Concurrent Editing** The Homebrewery does not support concurrent user editing. It's best one user at a time makes edits to avoid overwriting eachother.",
"> * **Back-up your brews** I can not guarantee that I will support this project indefinitely. So if you'd like to hang on to your creation be sure to back up it up.",
"",
"",
"```",
"```",
"",
"### Images",
"Images can be included 'inline' with the text using Markdown-style images. However for background images more control is needed.",
"",
"Background images should be included as HTML-style img tags. Using inline CSS you can precisely position your image where you'd like it to be. The image **snippet** provides an example of doing this.",
"",
"",
"### Not quite Markdown",
"Although the Homebrewery uses Markdown, to get all the styling features from the PHB, we had to get a little creative. Some base HTML elements are not used as expected and I've had to include a few new keywords.",
"",
"___",
"* **Horizontal Rules** are generally used to *modify* existing elements into a different style. For example, a horizontal rule before a blockquote will give it the style of a Monster Stat Block instead of a note.",
"* **New Pages** are controlled by the author. It's impossible for the site to detect when the end of a page is reached, so indicate you'd like to start a new page with **`/page`** on it's own line .",
"* **Code Blocks** are used only to indicate column breaks. Since they don't allow for styling within them, they weren't that useful to use.",
"* **HTML** can be used to get *just* the right look for your homebrew. I've included some examples in the snippet icons above the editor.",
"",
"",
"## Bugs, Issues, Suggestions?",
"Have an idea of how to make The Homebrewery better? Or did you find something that wasn't quite right? Head [here](https://github.com/stolksdorf/NaturalCrit/issues/new) and let me know!.",
"",
"### Planned Features",
"Here are a few features I'm planning next",
"* Convert to PDF",
"* Switch between DMG-style and Monster Manual-Style",
"* Download as images",
"",
"",
"",
"",
].join('\n');

<commit_msg>Fixing the welcome image<commit_after>module.exports = [
"# The Homebrewery",
"Welcome traveler from an antique land. Please sit and tell us of what you have seen. The unheard of monsters, who slither and bite.",
"",
"Tell us of the wondrous items and and artifacts you have found, their mysteries yet to be unlocked. Of the vexing vocations and surprising skills you have seen.",
"",
"### Homebrew made easy",
"The Homebrewery allows for the creation and sharing of authentic looking Fifth-Edition homebrews, with just text editing. It accomplishes this by using [Markdown](https://help.github.com/articles/markdown-basics/) along with some custom CSS-stlying.",
"",
"Stop worrying about learning photoshop, fiddling with spacing, or tracking down the PHB assets. Just focus on making your homebrew **great**.",
"",
"**Try it! **Simply edit the text on the left and watch it *update live* on the right.",
"",
"#### Features",
"* Monster Stat Blocks",
"* Full class tables",
"* Notes and Tables",
"* Images",
"* Vertical spacing, column breaks, and mutliple Pages",
"",
"",
"#### Snippets",
"If you aren't used the Markdown-style syntax, don't worry! I've provided several **snippets** at the top of the editor. When clicked, these will *inject* text wherever your text cursor was.",
"",
"Each snippet is a common format from the Player's Handbook or is a feature of The Homebrewery. You'll never have to memorize exactly how a Monster Stat Block is suppose to be formatted.",
"",
"### Editing and Sharing",
"When you create your own homebrew you will be given a *edit url* and a *share url*.  Any changes you make will be automatically saved to the database within a few seconds. Anyone with the edit url will be able to make edits to your homebrew. So be careful about who you share it with.",
"",
"Anyone with the *share url* will be able to access a read-only version of your homebrew.",
"",
"",
"> ##### Words of Caution",
"> ___",
"> * **Concurrent Editing** The Homebrewery does not support concurrent user editing. It's best one user at a time makes edits to avoid overwriting eachother.",
"> * **Back-up your brews** I can not guarantee that I will support this project indefinitely. So if you'd like to hang on to your creation be sure to back up it up.",
"",
"",
"```",
"```",
"",
"### Images",
"Images can be included 'inline' with the text using Markdown-style images. However for background images more control is needed.",
"",
"Background images should be included as HTML-style img tags. Using inline CSS you can precisely position your image where you'd like it to be. The image **snippet** provides an example of doing this.",
"",
"",
"### Not quite Markdown",
"Although the Homebrewery uses Markdown, to get all the styling features from the PHB, we had to get a little creative. Some base HTML elements are not used as expected and I've had to include a few new keywords.",
"",
"___",
"* **Horizontal Rules** are generally used to *modify* existing elements into a different style. For example, a horizontal rule before a blockquote will give it the style of a Monster Stat Block instead of a note.",
"* **New Pages** are controlled by the author. It's impossible for the site to detect when the end of a page is reached, so indicate you'd like to start a new page with **`/page`** on it's own line .",
"* **Code Blocks** are used only to indicate column breaks. Since they don't allow for styling within them, they weren't that useful to use.",
"* **HTML** can be used to get *just* the right look for your homebrew. I've included some examples in the snippet icons above the editor.",
"",
"",
"## Bugs, Issues, Suggestions?",
"Have an idea of how to make The Homebrewery better? Or did you find something that wasn't quite right? Head [here](https://github.com/stolksdorf/NaturalCrit/issues/new) and let me know!.",
"",
"### Planned Features",
"Here are a few features I'm planning next",
"* Convert to PDF",
"* Switch between DMG-style and Monster Manual-Style",
"* Download as images",
"",
"",
"",
"",
].join('\n');

<|endoftext|>


<commit_before>// @flow
import React from 'react'
import {reduxForm} from 'redux-form'
import Scroll from 'react-scroll'
import Helmet from 'react-helmet'
import _ from 'lodash'

import style from './index.css'
import Action from '../../actions'

const titles = [
  {
    key: 'school',
    title: 'プログラミング教室への入会お申し込み',
    placeholder: '参加可能日、特に勉強したい内容等がありましたらご記入ください。'
  }, {
    key: 'event',
    title: 'スクラッチJr.体験会への参加お申し込み',
    placeholder: 'ご希望の日程と参加人数をご記入ください。'
  }, {
    key: 'about',
    title: '教室・体験会についてのご質問',
    placeholder: 'ご質問内容を詳しくご記入ください。'
  }, {
    key: 'advise',
    title: 'IT導入支援についてのご相談',
    placeholder: 'ご相談内容を詳しくご記入ください。'
  }, {
    key: 'contact',
    title: 'その他のご相談・お問い合わせ',
    placeholder: 'お問い合わせ内容を詳しくご記入ください。'
  }
]

class ContactForm extends React.Component {
  componentWillMount () {
    let hash = this.props.location.hash ? this.props.location.hash.replace(/#/, '') : null
    if (this.props.location.pathname.match(/\/entry\/?/)) hash = 'event'
    if (this.props.location.pathname.match(/\/regist\/?/)) hash = 'school'
    const data = hash ? {title: titles[_.findIndex(titles, {key: hash})].title} : {}
    this.props.dispatch(Action.contactOpen(data))
  }
  componentDidMount () {
    Scroll.animateScroll.scrollToTop({duration: 0})
  }
  handleCancel () {
    this.props.dispatch(Action.contactCancel())
  }
  handleConfirm (data, dispatch) {
    dispatch(Action.contactConfirm(data))
  }
  handleSubmit (data, dispatch) {
    dispatch(Action.contactSubmit(data))
  }
  render () {
    const {fields: {
      email,
      title,
      message
    }, handleSubmit} = this.props
    const {errorMsg, isConfirm, isSending, isSuccess} = this.props.contact
    return (

        <Helmet title="Contact" />

          お申し込み・お問い合わせ

          {isSuccess ? (

ありがとうございます

内容を確認次第、ご連絡させていただきます。

          ) : isConfirm ? (
            <form onSubmit={handleSubmit(this.handleSubmit)}>
              <input type="hidden" {...email} />
              <input type="hidden" {...title} />
              <input type="hidden" {...message} />

以下の内容で送信いたします。よろしいですか？

                    お問い合わせ
                    {title.value}

                    Eメール
                    {email.value}

                    メッセージ
                    {message.value}

              {errorMsg ?
{errorMsg}
 : ''}

                <button className={style.button} type="button" onClick={() => this.handleCancel()}> いいえ、戻ります </button>
                <button className={style.buttonSubmit} data-sending={isSending} type="submit" disabled={isSending}> はい、送信します </button>

            </form>
          ) : (
            <form onSubmit={handleSubmit(this.handleConfirm)}>

                  <select {...title}>
                    <option value="">お問い合わせ内容をお選びください</option>
                    {titles.map(val => {
                      return (
                        <option key={val.key}>{val.title}</option>
                      )
                    })}
                  </select>

                {title.touched && title.error && {title.error}}

                <input
                  className={(email.touched && email.error) ? style.inputError : style.input}
                  placeholder="Eメール"
                  {...email}
                />
                {email.touched && email.error && {email.error}}

                <textarea
                  className={(message.touched && message.error) ? style.textareaError : style.textarea}
                  placeholder={title.value ? titles[_.findIndex(titles, {title: title.value})].placeholder : 'お問い合わせ内容をご記入ください。'}
                  {...message}
                />
                {message.touched && message.error && {message.error}}

                <button className={style.buttonSubmit} type="submit"> 送信内容の確認 </button>

            </form>
          )}

    )
  }
}

export default reduxForm(
  {
    form: 'ContactForm',
    fields: [
      'email',
      'title',
      'date',
      'message'
    ],
    validate: values => {
      const errors = {}
      if (!values.email) {
        errors.email = '入力が必要です'
      } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
        errors.email = '正しいメールアドレスを入力してください'
      }
      if (!values.title) {
        errors.title = '入力が必要です'
      }
      if (!values.message) {
        errors.message = '入力が必要です'
      }
      return errors
    }
  },
  state => ({
    app: state.app,
    contact: state.contact,
    email: state.contact.savedEmail,
    initialValues: state.contact.initialValues
  })
)(ContactForm)
<commit_msg>Add new event to contact<commit_after>// @flow
import React from 'react'
import {reduxForm} from 'redux-form'
import Scroll from 'react-scroll'
import Helmet from 'react-helmet'
import _ from 'lodash'

import style from './index.css'
import Action from '../../actions'

const titles = [
  {
    key: 'school',
    title: 'プログラミング教室への入会お申し込み',
    placeholder: '参加可能日、特に勉強したい内容等がありましたらご記入ください。'
  }, {
    key: 'event',
    title: 'イベントへの参加お申し込み',
    placeholder: 'ご希望の日程とお名前をご記入ください。'
  }, {
    key: 'scratch',
    title: 'スクラッチJr.体験会への参加お申し込み',
    placeholder: 'ご希望の日程とお名前をご記入ください。'
  }, {
    key: 'about',
    title: '教室・体験会についてのご質問',
    placeholder: 'ご質問内容を詳しくご記入ください。'
  }, {
    key: 'advise',
    title: 'IT導入支援についてのご相談',
    placeholder: 'ご相談内容を詳しくご記入ください。'
  }, {
    key: 'contact',
    title: 'その他のご相談・お問い合わせ',
    placeholder: 'お問い合わせ内容を詳しくご記入ください。'
  }
]

class ContactForm extends React.Component {
  componentWillMount () {
    let hash = this.props.location.hash ? this.props.location.hash.replace(/#/, '') : null
    if (this.props.location.pathname.match(/\/entry\/?/)) hash = 'event'
    if (this.props.location.pathname.match(/\/regist\/?/)) hash = 'school'
    const data = hash ? {title: titles[_.findIndex(titles, {key: hash})].title} : {}
    this.props.dispatch(Action.contactOpen(data))
  }
  componentDidMount () {
    Scroll.animateScroll.scrollToTop({duration: 0})
  }
  handleCancel () {
    this.props.dispatch(Action.contactCancel())
  }
  handleConfirm (data, dispatch) {
    dispatch(Action.contactConfirm(data))
  }
  handleSubmit (data, dispatch) {
    dispatch(Action.contactSubmit(data))
  }
  render () {
    const {fields: {
      email,
      title,
      message
    }, handleSubmit} = this.props
    const {errorMsg, isConfirm, isSending, isSuccess} = this.props.contact
    return (

        <Helmet title="Contact" />

          お申し込み・お問い合わせ

          {isSuccess ? (

ありがとうございます

お申し込み・お問い合わせを承りました。
内容を確認次第、ご連絡させていただきます。

          ) : isConfirm ? (
            <form onSubmit={handleSubmit(this.handleSubmit)}>
              <input type="hidden" {...email} />
              <input type="hidden" {...title} />
              <input type="hidden" {...message} />

以下の内容で送信いたします。よろしいですか？

                    お問い合わせ
                    {title.value}

                    Eメール
                    {email.value}

                    メッセージ
                    {message.value}

              {errorMsg ?
{errorMsg}
 : ''}

                <button className={style.button} type="button" onClick={() => this.handleCancel()}> いいえ、戻ります </button>
                <button className={style.buttonSubmit} data-sending={isSending} type="submit" disabled={isSending}> はい、送信します </button>

            </form>
          ) : (
            <form onSubmit={handleSubmit(this.handleConfirm)}>

                  <select {...title}>
                    <option value="">お問い合わせ内容をお選びください</option>
                    {titles.map(val => {
                      return (
                        <option key={val.key}>{val.title}</option>
                      )
                    })}
                  </select>

                {title.touched && title.error && {title.error}}

                <input
                  className={(email.touched && email.error) ? style.inputError : style.input}
                  placeholder="Eメール"
                  {...email}
                />
                {email.touched && email.error && {email.error}}

                <textarea
                  className={(message.touched && message.error) ? style.textareaError : style.textarea}
                  placeholder={title.value ? titles[_.findIndex(titles, {title: title.value})].placeholder : 'お問い合わせ内容をご記入ください。'}
                  {...message}
                />
                {message.touched && message.error && {message.error}}

                <button className={style.buttonSubmit} type="submit"> 送信内容の確認 </button>

            </form>
          )}

    )
  }
}

export default reduxForm(
  {
    form: 'ContactForm',
    fields: [
      'email',
      'title',
      'date',
      'message'
    ],
    validate: values => {
      const errors = {}
      if (!values.email) {
        errors.email = '入力が必要です'
      } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
        errors.email = '正しいメールアドレスを入力してください'
      }
      if (!values.title) {
        errors.title = '入力が必要です'
      }
      if (!values.message) {
        errors.message = '入力が必要です'
      }
      return errors
    }
  },
  state => ({
    app: state.app,
    contact: state.contact,
    email: state.contact.savedEmail,
    initialValues: state.contact.initialValues
  })
)(ContactForm)
<|endoftext|>


<commit_before>const cookie = require('react-cookie')
const axios = require('axios');
const React = require('react');
const EditInfo = require('./profile/edit-info');
const UserInfo = require('./profile/user-info');

const Profile = React.createClass({
    componentWillMount() {
        // Fetch user data prior to component mounting
        const user = cookie.load('user');
        console.log(user);
        if (user == undefined) {
            window.location.href = 'http://localhost:3000/login';
        } else {
            const userId = user._id;

            this.setState({
                firstName: user.firstName,
                lastInitial: user.lastInitial,
                age: user.age,
                age_pref_min: user.age_pref_min,
                age_pref_max: user.age_pref_max,
                is_male: user.is_male,
                seeking_male: user.seeking_male,
            })
        }
        // // console.log("userID", userId);
        // function fetchMyProfile(uid) {

        //     axios.get(`${API_URL}/user/${uid}`, {
        //         headers: { Authorization: cookie.load('token') },
        //     })
        //         .then((response) => {
        //             console.log("response:", response)
        //         })
        //         .catch((err) => {
        //             console.log("error", err)
        //         });

        // }
    },

    // check() {

    //     if (window.location.href.indexOf("edit-info") > -1) {
    //         return (
    //             <EditInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     } else {
    //         return (
    //             <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     }
    // },

    render: function () {
        return (

                <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} is_male={this.state.is_male} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />

        );
    }
})

module.exports = Profile;<commit_msg>profile info works - need to fix register and edit-info<commit_after>const cookie = require('react-cookie')
const axios = require('axios');
const React = require('react');
const EditInfo = require('./profile/edit-info');
const UserInfo = require('./profile/user-info');

const Profile = React.createClass({
    componentWillMount() {
        // Fetch user data prior to component mounting
        const user = cookie.load('user');
        console.log(user);
        if (user == undefined) {
            window.location.href = 'http://localhost:3000/login';
        } else {
            let gender = user.is_male;
            if (gender === false) {
                gender = "girl";
            } else {
                gender = "guy";
            }
            this.setState({
                firstName: user.firstName,
                lastInitial: user.lastInitial,
                age: user.age,
                age_pref_min: user.age_pref_min,
                age_pref_max: user.age_pref_max,
                is_male: gender,
                seeking_male: user.seeking_male,
            })
        }
        // // console.log("userID", userId);
        // function fetchMyProfile(uid) {

        //     axios.get(`${API_URL}/user/${uid}`, {
        //         headers: { Authorization: cookie.load('token') },
        //     })
        //         .then((response) => {
        //             console.log("response:", response)
        //         })
        //         .catch((err) => {
        //             console.log("error", err)
        //         });

        // }
    },

    // check() {

    //     if (window.location.href.indexOf("edit-info") > -1) {
    //         return (
    //             <EditInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     } else {
    //         return (
    //             <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} email={this.state.email} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />
    //         );
    //     }
    // },

    render: function () {
        return (

                <UserInfo firstName={this.state.firstName} lastInitial={this.state.lastInitial} is_male={this.state.is_male} age={this.state.age} age_pref_min={this.state.age_pref_min} age_pref_max={this.state.age_pref_max} profile_look={this.state.profile_look} />

        );
    }
})

module.exports = Profile;<|endoftext|>


<commit_before>angular.module("protonet.platform")
  .factory("AppTutorial", function() {

    var appTutorials = {
      "node.js": {
        setup: [{
          label: "Get the node.js \"hello world\" example:",
          code: [
            "git clone https://github.com/heroku/node-js-sample.git",
            "cd node-js-sample"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "python": {
        setup: [{
          label: "Get the Python \"hello world\" example:",
          code: [
            "git clone https://github.com/guaq/heroku-in-a-bottle.git python-sample",
            "cd python-sample"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "php": {
        setup: [{
          label: "Get the PHP \"hello world\" example:",
          code: [
            "git clone https://github.com/heroku/php-getting-started.git",
            "cd php-getting-started"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "rails": {
        setup: [{
          label: "Get the Rails \"hello world\" example:",
          code: [
            "git clone git@github.com:experimental-platform/rails-hello-world.git",
            "cd rails-hello-world"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "docker": {
        setup: [{
          label: "Create a Dockerfile:",
          code: [
            "mkdir my-docker-app",
            "cd my-docker-app",
            "echo \"echo hello world\" > helloworld.sh",
            "touch Dockerfile"
          ]
        }, {
          label: "Then open the Dockerfile and add instructions:",
          code: [
            "FROM experimentalplatform/ubuntu:latest",
            "ADD /helloworld.sh /helloworld.sh",
            "CMD sh helloworld.sh"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add  ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      }
    };

    return {
      get: function(appType) {
        return appTutorials[appType.toLowerCase()];
      }
    };

  });<commit_msg>New dockerfile tutorial<commit_after>angular.module("protonet.platform")
  .factory("AppTutorial", function() {

    var appTutorials = {
      "node.js": {
        setup: [{
          label: "Get the node.js \"hello world\" example:",
          code: [
            "git clone https://github.com/heroku/node-js-sample.git",
            "cd node-js-sample"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "python": {
        setup: [{
          label: "Get the Python \"hello world\" example:",
          code: [
            "git clone https://github.com/guaq/heroku-in-a-bottle.git python-sample",
            "cd python-sample"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "php": {
        setup: [{
          label: "Get the PHP \"hello world\" example:",
          code: [
            "git clone https://github.com/heroku/php-getting-started.git",
            "cd php-getting-started"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "rails": {
        setup: [{
          label: "Get the Rails \"hello world\" example:",
          code: [
            "git clone git@github.com:experimental-platform/rails-hello-world.git",
            "cd rails-hello-world"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      },

      "docker": {
        setup: [{
          label: "Get the Dockerfile \"hello world\" example:",
          code: [
            "git clone git@github.com:experimental-platform/dockerfile-hello-world.git",
            "cd dockerfile-hello-world"
          ]
        }, {
          label: "Set a name and add git remote:",
          code: [
            "APP_NAME=my-app-name",
            "git remote add platform ssh://dokku@{{host}}:8022/$APP_NAME"
          ]
        }],
        deploy: [{
          label: "Deploy the app on this server:",
          code: ["git push platform master"]
        }]
      }
    };

    return {
      get: function(appType) {
        return appTutorials[appType.toLowerCase()];
      }
    };

  });<|endoftext|>


<commit_before>import React from "react";
import { connect } from "react-redux";
import { capitalize, includes, map } from "lodash-es";
import { Panel } from "react-bootstrap";

import { Alert, Input, LoadingPlaceholder } from "../../base";
import { listGroups } from "../../groups/actions";
import { updateSampleRights } from "../actions";

class SampleRights extends React.Component {

    componentDidMount () {
        this.props.onListGroups();
    }

    isOwnerOrAdministrator = () => (
        includes(this.props.groups, this.props.group) || this.props.accountId === this.props.ownerId
    );

    handleChangeGroup = (e) => {
        this.props.onChangeGroup(this.props.sampleId, e.target.value);
    };

    handleChangeRights = (e, scope) => {
        this.props.onChangeRights(this.props.sampleId, scope, e.target.value);
    };

    render () {
        if (this.props.groups === null) {
            return <LoadingPlaceholder />;
        }

        if (!this.isOwnerOrAdministrator()) {
            return (
                <Panel>
                    <Panel.Body>
                        Not allowed
                    </Panel.Body>
                </Panel>
            );
        }

        const groupRights = (this.props.group_read ? "r" : "") + (this.props.group_write ? "w" : "");
        const allRights = (this.props.all_read ? "r" : "") + (this.props.all_write ? "w" : "");

        const nameOptionComponents = map(this.props.groups, group =>
            <option key={group.id} value={group.id}>
                {capitalize(group.id)}
            </option>
        );

        return (

                <Alert bsStyle="info" icon="info-circle">
                    Restrict who can read and write this sample and which user group owns the sample.
                </Alert>

                <Panel>
                    <Panel.Body>
                        <Input
                            type="select"
                            label="Group"
                            value={this.props.group}
                            onChange={this.handleChangeGroup}
                        >
                            <option value="none">None</option>
                            {nameOptionComponents}
                        </Input>

                        <Input
                            type="select"
                            name="groupRights"
                            label="Group Rights"
                            value={groupRights}
                            onChange={(e) => this.handleChangeRights(e, "group")}
                        >
                            <option value="">None</option>
                            <option value="r">Read</option>
                            <option value="rw">Read & write</option>
                        </Input>

                        <Input
                            type="select"
                            name="allUsers"
                            label="All Users' Rights"
                            value={allRights}
                            onChange={(e) => this.handleChangeRights(e, "all")}
                        >
                            <option value="">None</option>
                            <option value="r">Read</option>
                            <option value="rw">Read & write</option>
                        </Input>
                    </Panel.Body>
                </Panel>

        );
    }
}

const mapStateToProps = state => {

    const { all_read, all_write, group, group_read, group_write, id, user } = state.samples.detail;

    return {
        accountId: state.account.id,
        groups: state.groups.list,
        ownerId: user.id,
        sampleId: id,
        group,
        group_read,
        group_write,
        all_read,
        all_write
    };
};

const mapDispatchToProps = dispatch => ({

    onListGroups: () => {
        dispatch(listGroups());
    },

    onChangeGroup: (sampleId, groupId) => {
        dispatch(updateSampleRights(sampleId, {group: groupId}));
    },

    onChangeRights: (sampleId, scope, value) => {
        const update = {
            [`${scope}_read`]: includes(value, "r"),
            [`${scope}_write`]: includes(value, "w")
        };

        dispatch(updateSampleRights(sampleId, update));
    }

});

export default connect(mapStateToProps, mapDispatchToProps)(SampleRights);
<commit_msg>Fix admin sample rights edit issue #1036<commit_after>import React from "react";
import { connect } from "react-redux";
import { capitalize, includes, map } from "lodash-es";
import { Panel } from "react-bootstrap";

import { Alert, Input, LoadingPlaceholder } from "../../base";
import { listGroups } from "../../groups/actions";
import { updateSampleRights } from "../actions";

class SampleRights extends React.Component {

    componentDidMount () {
        this.props.onListGroups();
    }

    isOwnerOrAdministrator = () => (
        includes(this.props.groups, this.props.group)
        || this.props.accountId === this.props.ownerId
        || this.props.isAdmin
    );

    handleChangeGroup = (e) => {
        this.props.onChangeGroup(this.props.sampleId, e.target.value);
    };

    handleChangeRights = (e, scope) => {
        this.props.onChangeRights(this.props.sampleId, scope, e.target.value);
    };

    render () {
        if (this.props.groups === null) {
            return <LoadingPlaceholder />;
        }

        if (!this.isOwnerOrAdministrator()) {
            return (
                <Panel>
                    <Panel.Body>
                        Not allowed
                    </Panel.Body>
                </Panel>
            );
        }

        const groupRights = (this.props.group_read ? "r" : "") + (this.props.group_write ? "w" : "");
        const allRights = (this.props.all_read ? "r" : "") + (this.props.all_write ? "w" : "");

        const nameOptionComponents = map(this.props.groups, group =>
            <option key={group.id} value={group.id}>
                {capitalize(group.id)}
            </option>
        );

        return (

                <Alert bsStyle="info" icon="info-circle">
                    Restrict who can read and write this sample and which user group owns the sample.
                </Alert>

                <Panel>
                    <Panel.Body>
                        <Input
                            type="select"
                            label="Group"
                            value={this.props.group}
                            onChange={this.handleChangeGroup}
                        >
                            <option value="none">None</option>
                            {nameOptionComponents}
                        </Input>

                        <Input
                            type="select"
                            name="groupRights"
                            label="Group Rights"
                            value={groupRights}
                            onChange={(e) => this.handleChangeRights(e, "group")}
                        >
                            <option value="">None</option>
                            <option value="r">Read</option>
                            <option value="rw">Read & write</option>
                        </Input>

                        <Input
                            type="select"
                            name="allUsers"
                            label="All Users' Rights"
                            value={allRights}
                            onChange={(e) => this.handleChangeRights(e, "all")}
                        >
                            <option value="">None</option>
                            <option value="r">Read</option>
                            <option value="rw">Read & write</option>
                        </Input>
                    </Panel.Body>
                </Panel>

        );
    }
}

const mapStateToProps = state => {

    const { all_read, all_write, group, group_read, group_write, id, user } = state.samples.detail;

    return {
        accountId: state.account.id,
        isAdmin: state.account.administrator,
        groups: state.groups.list,
        ownerId: user.id,
        sampleId: id,
        group,
        group_read,
        group_write,
        all_read,
        all_write
    };
};

const mapDispatchToProps = dispatch => ({

    onListGroups: () => {
        dispatch(listGroups());
    },

    onChangeGroup: (sampleId, groupId) => {
        dispatch(updateSampleRights(sampleId, {group: groupId}));
    },

    onChangeRights: (sampleId, scope, value) => {
        const update = {
            [`${scope}_read`]: includes(value, "r"),
            [`${scope}_write`]: includes(value, "w")
        };

        dispatch(updateSampleRights(sampleId, update));
    }

});

export default connect(mapStateToProps, mapDispatchToProps)(SampleRights);
<|endoftext|>


<commit_before>/*jshint node: true */
'use strict';

/*
* Name :  PagesViewSpec.js
* Module : UnitTest
* Location : /frontend/test/unit/View
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.1         2015-06-25  Maria Giovanna Chinellato   Fix test
*
* 0.1.0         2015-06-13  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-06-13  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

describe('PageView', function(){

	beforeEach(angular.mock.module('norris-nrti'));

	var html, info, element, scope, controller, PageFactory, PagesList, pagesList;

	beforeEach(inject(function($rootScope, $compile, $controller, $injector, $routeParams) {
    	scope = $rootScope.$new();
    	PagesList = $injector.get('PagesList');
    	PageFactory = $injector.get('PageFactory');

    	info = {
    		data: [
    			{
    				'properties': {
    					'ID':'page1',
    					'name':'Pagina 1 Last Sync: 25/6/2015 @ 19:21:56',
    					'description':'Questa è una bella pagina Last Sync: 25/6/2015 @ 19:21:56',
    					'socketURL':'http://norris-nrti-dev.herokuapp.com/norris/page1'
    				}
    			}
        	]
    	};

        pagesList = new PagesList(info);

    	controller = $controller('PageController', { $scope : scope, PagesList : pagesList, $routeParams : { pageId: '0' } });
    	html = angular.element('<page></page>');

    	scope.graphs = [
    		{ 'id' : 1, 'type' : 'MapChart', 'url' : 'http://example/map.com'},
    		{ 'id' : 2, 'type' : 'LineChart', 'url' : 'http://example/line.com'},
    		{ 'id' : 3, 'type' : 'BarChart', 'url' : 'http://example/bar.com'},
    		{ 'id' : 4, 'type' : 'Table', 'url' : 'http://example/table.com'}
    	];

    	element = $compile(html)(scope);
    	scope.$digest();

  	}));

  	describe('Constructor', function() {
		it('works fine', function() {
			var map = element.find('map-chart');
			var line = element.find('line-chart');
			var bar = element.find('bar-chart');
			var tab = element.find('table-chart');
			expect(map).toBeDefined();
			expect(line).toBeDefined();
			expect(bar).toBeDefined();
			expect(tab).toBeDefined();
		});
	});

});<commit_msg>some fixes<commit_after>/*jshint node: true */
'use strict';

/*
* Name :  PagesViewSpec.js
* Module : UnitTest
* Location : /frontend/test/unit/View
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.1         2015-06-25  Maria Giovanna Chinellato   Fix test
*
* 0.1.0         2015-06-13  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-06-13  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

describe('PageView', function(){

	beforeEach(angular.mock.module('norris-nrti'));

	var html, info, element, scope, controller, PageFactory, PagesList, pagesList;

	beforeEach(inject(function($rootScope, $compile, $controller, $injector, $routeParams) {
    	scope = $rootScope.$new();
    	PagesList = $injector.get('PagesList');
    	PageFactory = $injector.get('PageFactory');

    	info = {
    		data: [
    			{
    				'properties': {
    					'ID':'page1',
    					'name':'Pagina 1 Last Sync: 25/6/2015 @ 19:21:56',
    					'description':'Questa è una bella pagina Last Sync: 25/6/2015 @ 19:21:56',
    					'socketURL':'http://norris-nrti-dev.herokuapp.com/norris/page1'
    				}
    			}
        	]
    	};

        PagesList.addPage(info);

    	controller = $controller('PageController', { $scope : scope, PagesList : PagesList, $routeParams : { pageId: '0' } });
    	html = angular.element('<page></page>');

    	scope.graphs = [
    		{ 'id' : 1, 'type' : 'MapChart', 'url' : 'http://example/map.com'},
    		{ 'id' : 2, 'type' : 'LineChart', 'url' : 'http://example/line.com'},
    		{ 'id' : 3, 'type' : 'BarChart', 'url' : 'http://example/bar.com'},
    		{ 'id' : 4, 'type' : 'Table', 'url' : 'http://example/table.com'}
    	];

    	element = $compile(html)(scope);
    	scope.$digest();

  	}));

  	describe('Constructor', function() {
		it('works fine', function() {
			var map = element.find('map-chart');
			var line = element.find('line-chart');
			var bar = element.find('bar-chart');
			var tab = element.find('table-chart');
			expect(map).toBeDefined();
			expect(line).toBeDefined();
			expect(bar).toBeDefined();
			expect(tab).toBeDefined();
		});
	});

});<|endoftext|>


<commit_before>
'use strict';

let map;
let marker;
let geoip_latlng;

// Create a marker if it does not exist, set its position
//
function set_marker_position(lat, lng) {
  const leaflet = require('leaflet').noConflict();

  if (!map) return;

  if (marker) {
    marker.setLatLng({ lat, lng });
    return;
  }

  // copied from leaflet.Icon.Default.prototype.options with icon urls replaced
  let icon = leaflet.icon({
    iconUrl:       '$$ JSON.stringify(asset_url("nodeca.core/client/vendor/leaflet/images/marker-icon.png")) $$',
    iconRetinaUrl: '$$ JSON.stringify(asset_url("nodeca.core/client/vendor/leaflet/images/marker-icon-2x.png")) $$',
    shadowUrl:     '$$ JSON.stringify(asset_url("nodeca.core/client/vendor/leaflet/images/marker-shadow.png")) $$',
    iconSize:      [ 25, 41 ],
    iconAnchor:    [ 12, 41 ],
    popupAnchor:   [ 1, -34 ],
    tooltipAnchor: [ 16, -28 ],
    shadowSize:    [ 41, 41 ]
  });

  marker = leaflet.marker([], { icon, draggable: true });

  marker.setLatLng({ lat, lng });
  marker.addTo(map);

  // prevent marker from moving when user clicks on it
  marker.on('click', leaflet.DomEvent.stop);

  $('.user-settings-location__submit').prop('disabled', false);
}

N.wire.on('navigate.preload:' + module.apiPath, function load_deps(preload) {
  preload.push('vendor.leaflet');
});

// If location is not set, try to determine user location by their IP address
//
N.wire.before('navigate.done:' + module.apiPath, function get_user_coordinates() {
  if (N.runtime.page_data.location) return;

  let jqXhr = $.ajax({
    url: 'https://freegeoip.net/json/',
    type: 'GET',
    dataType: 'json',
    timeout: 2000
  });

  return Promise.resolve(jqXhr)
    .then(res => {
      if (typeof res.latitude === 'number' && typeof res.longitude === 'number') {
        geoip_latlng = [ res.latitude, res.longitude ];
      }
    }, () => { /* ignore errors */ });
});

N.wire.on('navigate.done:' + module.apiPath, function initialize_map() {
  const leaflet = require('leaflet').noConflict();

  let container = $('.user-settings-location__map');

  map = leaflet.map(container[0]);

  leaflet.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map);

  let Locator = leaflet.Control.extend({
    options: { position: 'topleft' },
    onAdd() {
      let container = $(N.runtime.render('users.settings.location.locator_btn'));
      let link = container.find('.user-settings-location__locator-btn')[0];

      // using code similar to leaflet core to make sure button behavior
      // is exactly the same as other buttons (zoom in/zoom out)
      leaflet.DomEvent
        .on(link, 'mousedown dblclick', leaflet.DomEvent.stopPropagation)
        .on(link, 'click', leaflet.DomEvent.stop)
        .on(link, 'click', function () {
          // wrap it into promise to ensure it resolves only once
          new Promise((resolve, reject) => {
            window.navigator.geolocation.getCurrentPosition(resolve, reject, { timeout: 10000 });
          }).then(function success(position) {
            // user moved to a different page
            if (!map) return;

            map.setView(
              [ position.coords.latitude, position.coords.longitude ],
              Math.max(10, map.getZoom())
            );
          }, function error(err) {
            // user moved to a different page
            if (!map) return;

            let err_map = { 1: 'denied', 2: 'unavailable', 3: 'timeout' };

            if (err.code && err_map[err.code]) {
              N.wire.emit('notify', t('err_geolocation_' + err_map[err.code]));
            }
          });
        });

      return container[0];
    }
  });

  map.addControl(new Locator());

  if (N.runtime.page_data.location) {
    set_marker_position(
      N.runtime.page_data.location[1],
      N.runtime.page_data.location[0]
    );

    map.setView([
      N.runtime.page_data.location[1],
      N.runtime.page_data.location[0]
    ], 10);
  } else if (geoip_latlng) {
    // no location set, zoom in on a location determined by ip address
    map.setView(geoip_latlng, 10);
  } else {
    // adjust position and zoom to fit the entire map in viewport
    map.setView([ 20, 0 ], container.width() > 600 ? 2 : 1);
  }

  let timer;
  let prevent_click = false;

  map.on('click', e => {
    // solution to avoid double-click triggering click event is similar to
    // https://css-tricks.com/snippets/javascript/bind-different-events-to-click-and-double-click/
    timer = setTimeout(function () {
      if (!prevent_click) {
        set_marker_position(e.latlng.lat, e.latlng.lng);
      }

      prevent_click = false;
    }, 300);
  });

  map.on('dblclick', () => {
    prevent_click = true;
    clearTimeout(timer);
  });
});

// Save marker position on the server when user clicks "save" button
//
N.wire.on(module.apiPath + ':save', function save_marker() {
  if (!marker) return;

  let latlng = marker.getLatLng();

  N.io.rpc('users.settings.location.update', {
    // normalize lng into [ -180, 180 ] range, lat should be correct as is
    latitude:  latlng.lat,
    longitude: latlng.lng > 0 ?
               ((latlng.lng + 180) % 360) - 180 :
               ((latlng.lng - 180) % 360) + 180
  }).then(() => {
    return N.wire.emit('navigate.to', { apiPath: 'users.settings.about' });
  }).catch(err => N.wire.emit('error', err));
});

N.wire.on('navigate.exit:users.settings.location', function teardown_map() {
  if (marker) {
    marker.remove();
    marker = null;
  }

  if (map) {
    map.remove();
    map = null;
  }
});
<commit_msg>freegeoip.net → freegeoip.app<commit_after>
'use strict';

let map;
let marker;
let geoip_latlng;

// Create a marker if it does not exist, set its position
//
function set_marker_position(lat, lng) {
  const leaflet = require('leaflet').noConflict();

  if (!map) return;

  if (marker) {
    marker.setLatLng({ lat, lng });
    return;
  }

  // copied from leaflet.Icon.Default.prototype.options with icon urls replaced
  let icon = leaflet.icon({
    iconUrl:       '$$ JSON.stringify(asset_url("nodeca.core/client/vendor/leaflet/images/marker-icon.png")) $$',
    iconRetinaUrl: '$$ JSON.stringify(asset_url("nodeca.core/client/vendor/leaflet/images/marker-icon-2x.png")) $$',
    shadowUrl:     '$$ JSON.stringify(asset_url("nodeca.core/client/vendor/leaflet/images/marker-shadow.png")) $$',
    iconSize:      [ 25, 41 ],
    iconAnchor:    [ 12, 41 ],
    popupAnchor:   [ 1, -34 ],
    tooltipAnchor: [ 16, -28 ],
    shadowSize:    [ 41, 41 ]
  });

  marker = leaflet.marker([], { icon, draggable: true });

  marker.setLatLng({ lat, lng });
  marker.addTo(map);

  // prevent marker from moving when user clicks on it
  marker.on('click', leaflet.DomEvent.stop);

  $('.user-settings-location__submit').prop('disabled', false);
}

N.wire.on('navigate.preload:' + module.apiPath, function load_deps(preload) {
  preload.push('vendor.leaflet');
});

// If location is not set, try to determine user location by their IP address
//
N.wire.before('navigate.done:' + module.apiPath, function get_user_coordinates() {
  if (N.runtime.page_data.location) return;

  let jqXhr = $.ajax({
    url: 'https://freegeoip.app/json/',
    type: 'GET',
    dataType: 'json',
    timeout: 2000
  });

  return Promise.resolve(jqXhr)
    .then(res => {
      if (typeof res.latitude === 'number' && typeof res.longitude === 'number') {
        geoip_latlng = [ res.latitude, res.longitude ];
      }
    }, () => { /* ignore errors */ });
});

N.wire.on('navigate.done:' + module.apiPath, function initialize_map() {
  const leaflet = require('leaflet').noConflict();

  let container = $('.user-settings-location__map');

  map = leaflet.map(container[0]);

  leaflet.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map);

  let Locator = leaflet.Control.extend({
    options: { position: 'topleft' },
    onAdd() {
      let container = $(N.runtime.render('users.settings.location.locator_btn'));
      let link = container.find('.user-settings-location__locator-btn')[0];

      // using code similar to leaflet core to make sure button behavior
      // is exactly the same as other buttons (zoom in/zoom out)
      leaflet.DomEvent
        .on(link, 'mousedown dblclick', leaflet.DomEvent.stopPropagation)
        .on(link, 'click', leaflet.DomEvent.stop)
        .on(link, 'click', function () {
          // wrap it into promise to ensure it resolves only once
          new Promise((resolve, reject) => {
            window.navigator.geolocation.getCurrentPosition(resolve, reject, { timeout: 10000 });
          }).then(function success(position) {
            // user moved to a different page
            if (!map) return;

            map.setView(
              [ position.coords.latitude, position.coords.longitude ],
              Math.max(10, map.getZoom())
            );
          }, function error(err) {
            // user moved to a different page
            if (!map) return;

            let err_map = { 1: 'denied', 2: 'unavailable', 3: 'timeout' };

            if (err.code && err_map[err.code]) {
              N.wire.emit('notify', t('err_geolocation_' + err_map[err.code]));
            }
          });
        });

      return container[0];
    }
  });

  map.addControl(new Locator());

  if (N.runtime.page_data.location) {
    set_marker_position(
      N.runtime.page_data.location[1],
      N.runtime.page_data.location[0]
    );

    map.setView([
      N.runtime.page_data.location[1],
      N.runtime.page_data.location[0]
    ], 10);
  } else if (geoip_latlng) {
    // no location set, zoom in on a location determined by ip address
    map.setView(geoip_latlng, 10);
  } else {
    // adjust position and zoom to fit the entire map in viewport
    map.setView([ 20, 0 ], container.width() > 600 ? 2 : 1);
  }

  let timer;
  let prevent_click = false;

  map.on('click', e => {
    // solution to avoid double-click triggering click event is similar to
    // https://css-tricks.com/snippets/javascript/bind-different-events-to-click-and-double-click/
    timer = setTimeout(function () {
      if (!prevent_click) {
        set_marker_position(e.latlng.lat, e.latlng.lng);
      }

      prevent_click = false;
    }, 300);
  });

  map.on('dblclick', () => {
    prevent_click = true;
    clearTimeout(timer);
  });
});

// Save marker position on the server when user clicks "save" button
//
N.wire.on(module.apiPath + ':save', function save_marker() {
  if (!marker) return;

  let latlng = marker.getLatLng();

  N.io.rpc('users.settings.location.update', {
    // normalize lng into [ -180, 180 ] range, lat should be correct as is
    latitude:  latlng.lat,
    longitude: latlng.lng > 0 ?
               ((latlng.lng + 180) % 360) - 180 :
               ((latlng.lng - 180) % 360) + 180
  }).then(() => {
    return N.wire.emit('navigate.to', { apiPath: 'users.settings.about' });
  }).catch(err => N.wire.emit('error', err));
});

N.wire.on('navigate.exit:users.settings.location', function teardown_map() {
  if (marker) {
    marker.remove();
    marker = null;
  }

  if (map) {
    map.remove();
    map = null;
  }
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name         MyFitnessPal Calorie Display Remover
// @namespace    gordondev
// @version      0.1
// @description  For us weirdos on MyFitnessPal that don't want to focus so much on the calories. This script removes all calorie displays from the diary.
// @author       Shauna Gordon
// @match        *www.myfitnesspal.com/food/diary/*
// @grant        none
// ==/UserScript==

function addJquery() {
	script = document.createElement("script");
    script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js");
    document.body.appendChild(script);
}

function getUser() {
	return $('.user-2').first().attr('title');
}

function main() {
	// jQuery just makes life easier
	// We won't be picky with whether it's jQuery or Zepto, though
	if(typeof $ == 'undefined') {
		addJquery();
	}

	var user = getUser();
	var url = window.location.pathname.toLowerCase();
	if(url.indexOf(user) > -1) {
		$('.first + td').hide();
	}
}

main();
<commit_msg>Delete mfp-calorie-remover.js<commit_after><|endoftext|>


<commit_before>var Telegram = require('node-telegram-bot-api');
var fs = require('fs');
var irc = require('./irc');

// tries to read chat ids from a file
var readChatIds = function(arr) {
    console.log('\n');
    console.log('NOTE!');
    console.log('=====');

    var idMissing = false;
    try {
        var json = JSON.parse(fs.readFileSync(process.env.HOME + '/.teleirc/chat_ids'));
        for (var i = 0; i < arr.length; i++) {
            var key = arr[i].tgGroup;
            if (key in json) {
                arr[i].tgChatId = json[key];
                console.log('id found for:', key, ':', json[key]);
            } else {
                console.log('id not found:', key);
                idMissing = true;
            }
        }
    } catch (e) {
        console.log('~/.teleirc/chat_ids file not found!');
        idMissing = true;
    }

    if (idMissing) {
        console.log(
            '\nPlease add your Telegram bot to a Telegram group and have' +
            '\nsomeone send a message to that group.' +
            '\nteleirc will then automatically store your group chat_id.');
    }

    console.log('\n');
};

var writeChatIds = function(config) {
    var json = {};
    for (var i = 0; i < config.channels.length; i++) {
        if (config.channels[i].tgChatId) {
            json[config.channels[i].tgGroup] = config.channels[i].tgChatId;
        }
    }
    json = JSON.stringify(json);
    fs.writeFile(process.env.HOME + '/.teleirc/chat_ids', json, function(err) {
        if (err) {
            console.log('error while storing chat ID:');
            console.log(err);
        } else {
            console.log('successfully stored chat ID in ~/.teleirc/chat_ids');
        }
    });
};

module.exports = function(config, sendTo) {
    var tg = new Telegram(config.tgToken,{polling: true});

    readChatIds(config.channels);

    tg.on('message', function(msg) {
        var channel = config.channels.filter(function(channel) {
            return channel.tgGroup === msg.chat.title;
        })[0];

        if (!channel) {
            return;
        }

        if (!channel.tgChatId) {
            console.log('storing chat ID: ' + msg.chat.id);
            channel.tgChatId = msg.chat.id;
            writeChatIds(config);
        }

        var user = msg.from.first_name ? msg.from.first_name + ' ' : '';
        user += msg.from.last_name ? msg.from.last_name : '';
        user += msg.from.username ? '(@' + msg.from.username + ')' : '';

        // skip posts containing media if it's configured off
        if ((msg.audio || msg.document || msg.photo || msg.sticker || msg.video ||
            msg.voice || msg.contact || msg.location) && !config.showMedia) {
            return;
        }

        var text;

        if (msg.reply_to_message && msg.text) {
            text = '@' + msg.reply_to_message.from.username + ', ' + msg.text;
        } else if (msg.audio) {
            text = '(Audio)';
        } else if (msg.document) {
            text = '(Document)';
        } else if (msg.photo) {
            text = '(Image, ' + msg.photo.slice(-1)[0].width + 'x' +
                                msg.photo.slice(-1)[0].height + ')';
        } else if (msg.sticker) {
            text = '(Sticker)';
        } else if (msg.video) {
            text = '(Video, ' + msg.video.duration + 's)';
        } else if (msg.voice) {
            text = '(Voice, ' + msg.audio.duration + 's)';
        } else if (msg.contact) {
            text = '(Contact, ' + '"' + msg.contact.first_name + ' ' +
                                        msg.contact.last_name + '", ' +
                                        msg.contact.phone_number + ')';
        } else if (msg.location) {
            text = '(Location, lon: ' + msg.location.longitude +
                            ', lat: ' + msg.location.latitude + ')';
        } else if (msg.new_chat_participant) {
            text = '(Added: ' + msg.new_chat_participant.first_name + ')';
        } else if (msg.left_chat_participant) {
            text = '(Removed: ' + msg.left_chat_participant.first_name + ')';
        } else {
            text = msg.text;
        }

        sendTo.irc(channel.ircChan, '<' + user + '>: ' + text);
    });

    sendTo.tg = function(channel, msg) {
        console.log('  >> relaying to TG: ' + msg);

        if (!channel.tgChatId) {
            var err = 'ERROR: No chat_id set! Add me to a Telegram group ' +
                      'and say hi so I can find your group\'s chat_id!';
            sendTo.irc(channel.ircChan, err);
            console.error(err);
            return;
        }

        tg.sendMessage(channel.tgChatId, msg);
    };
};
<commit_msg>I have programmed the lines with show who sended the message from telegram to irc, with the configuration on the config.js<commit_after>var Telegram = require('node-telegram-bot-api');
var fs = require('fs');
var irc = require('./irc');

// tries to read chat ids from a file
var readChatIds = function(arr) {
    console.log('\n');
    console.log('NOTE!');
    console.log('=====');

    var idMissing = false;
    try {
        var json = JSON.parse(fs.readFileSync(process.env.HOME + '/.teleirc/chat_ids'));
        for (var i = 0; i < arr.length; i++) {
            var key = arr[i].tgGroup;
            if (key in json) {
                arr[i].tgChatId = json[key];
                console.log('id found for:', key, ':', json[key]);
            } else {
                console.log('id not found:', key);
                idMissing = true;
            }
        }
    } catch (e) {
        console.log('~/.teleirc/chat_ids file not found!');
        idMissing = true;
    }

    if (idMissing) {
        console.log(
            '\nPlease add your Telegram bot to a Telegram group and have' +
            '\nsomeone send a message to that group.' +
            '\nteleirc will then automatically store your group chat_id.');
    }

    console.log('\n');
};

var writeChatIds = function(config) {
    var json = {};
    for (var i = 0; i < config.channels.length; i++) {
        if (config.channels[i].tgChatId) {
            json[config.channels[i].tgGroup] = config.channels[i].tgChatId;
        }
    }
    json = JSON.stringify(json);
    fs.writeFile(process.env.HOME + '/.teleirc/chat_ids', json, function(err) {
        if (err) {
            console.log('error while storing chat ID:');
            console.log(err);
        } else {
            console.log('successfully stored chat ID in ~/.teleirc/chat_ids');
        }
    });
};

module.exports = function(config, sendTo) {
    var tg = new Telegram(config.tgToken,{polling: true});

    readChatIds(config.channels);

    tg.on('message', function(msg) {
        var channel = config.channels.filter(function(channel) {
            return channel.tgGroup === msg.chat.title;
        })[0];

        if (!channel) {
            return;
        }

        if (!channel.tgChatId) {
            console.log('storing chat ID: ' + msg.chat.id);
            channel.tgChatId = msg.chat.id;
            writeChatIds(config);
        }

        var user;

        if(config.ircTgShowName == 1){
          // first_name
          user = msg.from.first_name ? msg.from.first_name + '' : '';
        }else{
          if(config.ircTgShowName == 2){
            // first_name last_name
            user = msg.from.first_name ? msg.from.first_name + ' ' : '';
            user += msg.from.last_name ? msg.from.last_name : '';
          }else{
            if(config.ircTgShowName == 3){
              // first_name last_name @username
              user = msg.from.first_name ? msg.from.first_name + ' ' : '';
              user += msg.from.last_name ? msg.from.last_name : '';
              user += msg.from.username ? '(@' + msg.from.username + ')' : '(No username)';
            }else{
              // @username
              user = msg.from.username ? '@' + msg.from.username : msg.from.first_name+' '+msg.from.last_name;
            }
          }
        }

        // skip posts containing media if it's configured off
        if ((msg.audio || msg.document || msg.photo || msg.sticker || msg.video ||
            msg.voice || msg.contact || msg.location) && !config.showMedia) {
            return;
        }

        var text;

        if (msg.reply_to_message && msg.text) {
            text = '@' + msg.reply_to_message.from.username + ', ' + msg.text;
        } else if (msg.audio) {
            text = '(Audio)';
        } else if (msg.document) {
            text = '(Document)';
        } else if (msg.photo) {
            text = '(Image, ' + msg.photo.slice(-1)[0].width + 'x' +
                                msg.photo.slice(-1)[0].height + ')';
        } else if (msg.sticker) {
            text = '(Sticker)';
        } else if (msg.video) {
            text = '(Video, ' + msg.video.duration + 's)';
        } else if (msg.voice) {
            text = '(Voice, ' + msg.audio.duration + 's)';
        } else if (msg.contact) {
            text = '(Contact, ' + '"' + msg.contact.first_name + ' ' +
                                        msg.contact.last_name + '", ' +
                                        msg.contact.phone_number + ')';
        } else if (msg.location) {
            text = '(Location, lon: ' + msg.location.longitude +
                            ', lat: ' + msg.location.latitude + ')';
        } else if (msg.new_chat_participant) {
            text = '(Added: ' + msg.new_chat_participant.first_name + ')';
        } else if (msg.left_chat_participant) {
            text = '(Removed: ' + msg.left_chat_participant.first_name + ')';
        } else {
            text = msg.text;
        }

        sendTo.irc(channel.ircChan, '<' + user + '>: ' + text);
    });

    sendTo.tg = function(channel, msg) {
        console.log('  >> relaying to TG: ' + msg);

        if (!channel.tgChatId) {
            var err = 'ERROR: No chat_id set! Add me to a Telegram group ' +
                      'and say hi so I can find your group\'s chat_id!';
            sendTo.irc(channel.ircChan, err);
            console.error(err);
            return;
        }

        tg.sendMessage(channel.tgChatId, msg);
    };
};
<|endoftext|>


<commit_before>var FORMAT_TYPE = [
   { "type" : "UINT8"   , "length" : 1 }
  ,{ "type" : "UINT16"  , "length" : 2 }
  ,{ "type" : "UINT32"  , "length" : 4 }
  ,{ "type" : "SINT8"   , "length" : 1 }
  ,{ "type" : "SINT16"  , "length" : 2 }
  ,{ "type" : "SINT32"  , "length" : 4 }
  ,{ "type" : "BIT8"    , "length" : 1 }
  ,{ "type" : "BIT16"   , "length" : 2 }
  ,{ "type" : "BIT32"   , "length" : 4 }
  ,{ "type" : "OCT8"    , "length" : 1 }
  ,{ "type" : "OCT16"   , "length" : 2 }
  ,{ "type" : "OCT32"   , "length" : 4 }
  ,{ "type" : "HEX8"    , "length" : 1 }
  ,{ "type" : "HEX16"   , "length" : 2 }
  ,{ "type" : "HEX32"   , "length" : 4 }
  ,{ "type" : "DUMMY8"  , "length" : 1 }
  ,{ "type" : "DUMMY16" , "length" : 2 }
  ,{ "type" : "DUMMY32" , "length" : 4 }
];

var wTrTool = {};

// command line argument
(function(){
  var opt = {};

  var objArgs = WScript.Arguments;

  optGet = (function(objArgs, key , default_value){
    if(objArgs.Named.Exists(key) && (objArgs.Named.Item(key) !== undefined)){
      return objArgs.Named.Item(key);
    }else{
      return default_value;
    }
  });

  var options = [
                /* key,     default_value */
                ["input",   "input.dat"]
              , ["output",  "output.csv"]
              , ["format",  "format.json"]
              , ["pattern", "sample"]
              , ["endian",  true]
            ];

  for(var i = 0; i < options.length; i++){
    opt[options[i][0]] = optGet(objArgs, options[i][0], options[i][1]);
  }

//  WScript.Echo( "opt = " + JSON.stringify(opt) );

  wTrTool.option = opt;
})();

// pattern select
(function(){

  var objFS = new ActiveXObject("Scripting.FileSystemObject");

  var format_stream = objFS.OpenTextFile(wTrTool.option.format, 1, false, -2);
  var format_txt = format_stream.ReadAll();
  var formats = JSON.parse(format_txt);
  var pattern = null;

  for(var i = 0; i < formats.length; i++){
    if(formats[i].patternname === wTrTool.option.pattern){
      pattern = formats[i];
      break;
    }
  }

  if(pattern === null){
    WScript.Echo( "Error: pattern not found" );
    WScript.Quit(-1);
  }

  wTrTool.pattern = pattern;

})();

// format preproc
(function(){
  var format = [];
  var prefix = "";
  var suffix = "";

  (function format_convert(format, pattern, prefix, suffix){
    for(var i = 0; i < pattern.length; i++){
      if("union" in pattern[i]){
        // WScript.Echo( "union" );
        var union_obj = {};
        var tbl = [];
        union_obj.label = pattern[i].label;
        for(var k = 0; k < pattern[i].union.length; k++){
          var union_prefix_top = "";
          var union_prefix_bottom = "";
          if(prefix === ""){
            union_prefix_top = "";
          }else{
            union_prefix_top = prefix + ".";
          }
          union_prefix_bottom = pattern[i].label + "." + pattern[i].union[k].label + ".";
          format_convert(tbl, pattern[i].union[k].format, union_prefix_top + union_prefix_bottom, suffix);
        }
        union_obj.union = tbl;
        format.push(union_obj);
      }else if("array" in pattern[i]){
        // WScript.Echo( "array" );
        for(var j = 0; j < pattern[i].array.num; j++){
          var array_suffix = "[" + j + "]";
          var array_prefix = "";
          if(prefix === ""){
            array_prefix = pattern[i].label;
          }else{
            array_prefix = prefix + suffix + "." + pattern[i].label;
          }
          format_convert(format, pattern[i].array.format, array_prefix, array_suffix);
        }
      }else{
        // WScript.Echo( "member" );
        var obj = {};
        obj.type = pattern[i].type;
        if(suffix === ""){
          obj.label = prefix + pattern[i].label;
        }else{
          if(pattern[i].label === ""){
            obj.label = prefix + suffix;
          }else{
            obj.label = prefix + suffix + "." + pattern[i].label;
          }
        }
        format.push(obj);
      }
    }
  })(format, wTrTool.pattern.format, prefix, suffix);

  wTrTool.format = format;
})();

// input file read
(function(){

  var a = WSH_BINARY.Readfile2Array(wTrTool.option.input);

  wTrTool.binarys = a;

})();

WScript.Echo( JSON.stringify(wTrTool.pattern) );
WScript.Echo( "========================================================================" );
WScript.Echo( JSON.stringify(wTrTool.binarys) );
WScript.Echo( "========================================================================" );
WScript.Echo( JSON.stringify(wTrTool.format) );
WScript.Echo( "========================================================================" );

// output
(function(){
  var top = [];
  var binarys = wTrTool.binarys;

  (function make_header_str(header,format){
    for(var i = 0; i < format.length; i++){
      if("union" in format[i]){
        make_header_str(header, format[i].union);
      }else{
        if(format[i].type.search("DUMMY") === -1){
          header.push(format[i].label);
        }
      }
    }
  })(top, wTrTool.format);

  WScript.Echo( JSON.stringify(top) );
  WScript.Echo( "------------------------------------------------------------------------" );

  while(binarys.length > 0){
    var data = [];

    (function make_convert_str(str, tbl, format){
      if("union" in format){
        //@TODO
        var union_tbl = tbl;
        var min_tbl = tbl;
        for(var j = 0; j < format.union.length; j++){
          var temp_tbl = union_tbl;
          make_convert_str(str, temp_tbl, format.union[j]);
          if(min_tbl.length > temp_tbl.length){
            min_tbl = temp_tbl;
          }
        }
        tbl = min_tbl;
      }else if("label" in format){
        var flg = true;
        for(var k = 0; k < FORMAT_TYPE.length; k++){
          if(FORMAT_TYPE[k].type === format.type){
            var d = [];
            for(var l = 0; l < FORMAT_TYPE[k].length; l++){
              d.push(tbl.shift());
            }

            flg = false;
            str.push(d);
          }
        }
        if(flg){
          WScript.Echo("Error : invalid type");
          WScript.Quit(-1);
        }
      }else{
        for(var i = 0; i < format.length; i++){
          make_convert_str(str, tbl, format[i]);
        }
      }
    })(data, binarys, wTrTool.format);

    WScript.Echo( JSON.stringify(data) );
  }

})();

<commit_msg>端数データの処理をruby版に合わせる<commit_after>var FORMAT_TYPE = [
   { "type" : "UINT8"   , "length" : 1 }
  ,{ "type" : "UINT16"  , "length" : 2 }
  ,{ "type" : "UINT32"  , "length" : 4 }
  ,{ "type" : "SINT8"   , "length" : 1 }
  ,{ "type" : "SINT16"  , "length" : 2 }
  ,{ "type" : "SINT32"  , "length" : 4 }
  ,{ "type" : "BIT8"    , "length" : 1 }
  ,{ "type" : "BIT16"   , "length" : 2 }
  ,{ "type" : "BIT32"   , "length" : 4 }
  ,{ "type" : "OCT8"    , "length" : 1 }
  ,{ "type" : "OCT16"   , "length" : 2 }
  ,{ "type" : "OCT32"   , "length" : 4 }
  ,{ "type" : "HEX8"    , "length" : 1 }
  ,{ "type" : "HEX16"   , "length" : 2 }
  ,{ "type" : "HEX32"   , "length" : 4 }
  ,{ "type" : "DUMMY8"  , "length" : 1 }
  ,{ "type" : "DUMMY16" , "length" : 2 }
  ,{ "type" : "DUMMY32" , "length" : 4 }
];

var wTrTool = {};

// command line argument
(function(){
  var opt = {};

  var objArgs = WScript.Arguments;

  optGet = (function(objArgs, key , default_value){
    if(objArgs.Named.Exists(key) && (objArgs.Named.Item(key) !== undefined)){
      return objArgs.Named.Item(key);
    }else{
      return default_value;
    }
  });

  var options = [
                /* key,     default_value */
                ["input",   "input.dat"]
              , ["output",  "output.csv"]
              , ["format",  "format.json"]
              , ["pattern", "sample"]
              , ["endian",  true]
            ];

  for(var i = 0; i < options.length; i++){
    opt[options[i][0]] = optGet(objArgs, options[i][0], options[i][1]);
  }

//  WScript.Echo( "opt = " + JSON.stringify(opt) );

  wTrTool.option = opt;
})();

// pattern select
(function(){

  var objFS = new ActiveXObject("Scripting.FileSystemObject");

  var format_stream = objFS.OpenTextFile(wTrTool.option.format, 1, false, -2);
  var format_txt = format_stream.ReadAll();
  var formats = JSON.parse(format_txt);
  var pattern = null;

  for(var i = 0; i < formats.length; i++){
    if(formats[i].patternname === wTrTool.option.pattern){
      pattern = formats[i];
      break;
    }
  }

  if(pattern === null){
    WScript.Echo( "Error: pattern not found" );
    WScript.Quit(-1);
  }

  wTrTool.pattern = pattern;

})();

// format preproc
(function(){
  var format = [];
  var prefix = "";
  var suffix = "";

  (function format_convert(format, pattern, prefix, suffix){
    for(var i = 0; i < pattern.length; i++){
      if("union" in pattern[i]){
        // WScript.Echo( "union" );
        var union_obj = {};
        var tbl = [];
        union_obj.label = pattern[i].label;
        for(var k = 0; k < pattern[i].union.length; k++){
          var union_prefix_top = "";
          var union_prefix_bottom = "";
          if(prefix === ""){
            union_prefix_top = "";
          }else{
            union_prefix_top = prefix + ".";
          }
          union_prefix_bottom = pattern[i].label + "." + pattern[i].union[k].label + ".";
          format_convert(tbl, pattern[i].union[k].format, union_prefix_top + union_prefix_bottom, suffix);
        }
        union_obj.union = tbl;
        format.push(union_obj);
      }else if("array" in pattern[i]){
        // WScript.Echo( "array" );
        for(var j = 0; j < pattern[i].array.num; j++){
          var array_suffix = "[" + j + "]";
          var array_prefix = "";
          if(prefix === ""){
            array_prefix = pattern[i].label;
          }else{
            array_prefix = prefix + suffix + "." + pattern[i].label;
          }
          format_convert(format, pattern[i].array.format, array_prefix, array_suffix);
        }
      }else{
        // WScript.Echo( "member" );
        var obj = {};
        obj.type = pattern[i].type;
        if(suffix === ""){
          obj.label = prefix + pattern[i].label;
        }else{
          if(pattern[i].label === ""){
            obj.label = prefix + suffix;
          }else{
            obj.label = prefix + suffix + "." + pattern[i].label;
          }
        }
        format.push(obj);
      }
    }
  })(format, wTrTool.pattern.format, prefix, suffix);

  wTrTool.format = format;
})();

// input file read
(function(){

  var a = WSH_BINARY.Readfile2Array(wTrTool.option.input);

  wTrTool.binarys = a;

})();

WScript.Echo( JSON.stringify(wTrTool.pattern) );
WScript.Echo( "========================================================================" );
WScript.Echo( JSON.stringify(wTrTool.binarys) );
WScript.Echo( "========================================================================" );
WScript.Echo( JSON.stringify(wTrTool.format) );
WScript.Echo( "========================================================================" );

// output
(function(){
  var top = [];
  var binarys = wTrTool.binarys;

  (function make_header_str(header,format){
    for(var i = 0; i < format.length; i++){
      if("union" in format[i]){
        make_header_str(header, format[i].union);
      }else{
        if(format[i].type.search("DUMMY") === -1){
          header.push(format[i].label);
        }
      }
    }
  })(top, wTrTool.format);

  WScript.Echo( JSON.stringify(top) );
  WScript.Echo( "------------------------------------------------------------------------" );

  while(binarys.length > 0){
    var data = [];

    (function make_convert_str(str, tbl, format){
      if(tbl.length !== 0){
        if("union" in format){
          //@TODO
          var union_tbl = tbl;
          var min_tbl = tbl;
          for(var j = 0; j < format.union.length; j++){
            var temp_tbl = union_tbl;
            make_convert_str(str, temp_tbl, format.union[j]);
            if(min_tbl.length > temp_tbl.length){
              min_tbl = temp_tbl;
            }
          }
          tbl = min_tbl;
        }else if("label" in format){
          var flg = true;
          for(var k = 0; k < FORMAT_TYPE.length; k++){
            if(FORMAT_TYPE[k].type === format.type){
              var d = [];
              for(var l = 0; l < FORMAT_TYPE[k].length; l++){
                d.push(tbl.shift());
              }

              flg = false;
              str.push(d);
            }
          }
          if(flg){
            WScript.Echo("Error : invalid type");
            WScript.Quit(-1);
          }
        }else{
          for(var i = 0; i < format.length; i++){
            make_convert_str(str, tbl, format[i]);
          }
        }
      }
    })(data, binarys, wTrTool.format);

    WScript.Echo( JSON.stringify(data) );
  }

})();

<|endoftext|>


<commit_before>const Discord = require("discord.js");
const bot = new Discord.Client();
const token = "";

var commands = {
    "ping": {
        description: "Pings the bot",
        process: function(message){
            message.reply("pong");
        }
    }
};

var checkForCommand = function(message){
    if(!message.author.bot){
        if(message.content === "!ping"){ //change this
            commands.ping.process(message);
        }
    }
}

bot.on("ready", () => console.log("Bot ready!"));
bot.on("guildMemberAdd", member => member.guild.defaultChannel.send(`Welcome to the server, ${member}!`));
bot.on("message", message => checkForCommand(message));
bot.on("messageUpdate", (oldMessage, newMessage) => checkForCommand(newMessage));

bot.login(token);<commit_msg>Add picabot token<commit_after>const Discord = require("discord.js");
const bot = new Discord.Client();
const token = "MzI3MTIyNTk3OTAyODExMTM3.DCwwQQ.BIxxQQEfezftpzywZLtawDeMoKU";

var commands = {
    "ping": {
        description: "Pings the bot",
        process: function(message){
            message.reply("pong");
        }
    }
};

var checkForCommand = function(message){
    if(!message.author.bot){
        if(message.content === "!ping"){ //change this
            commands.ping.process(message);
        }
    }
}

bot.on("ready", () => console.log("Bot ready!"));
bot.on("guildMemberAdd", member => member.guild.defaultChannel.send(`Welcome to the server, ${member}!`));
bot.on("message", message => checkForCommand(message));
bot.on("messageUpdate", (oldMessage, newMessage) => checkForCommand(newMessage));

bot.login(token);<|endoftext|>


<commit_before>//@flow
import GridView from '../views/GridView';
import meta from '../meta';
import VirtualCollection from '../../collections/VirtualCollection';
import factory from '../factory';

/*
 * @param {Array} options.excludeActions Array of strings. Example: [ 'archive', 'delete' ].
 * @param {Array} options.additionalActions Array of objects [ id,  name,
 * type=button'|'checkbox', isChecked, iconClass, severity].
 * @param {Boolean} options.showCheckbox show or hide checkbox
 */

const defaultOptions = {
    isSliding: true,
    showHeader: true,
    handleSearch: true
};

export default Marionette.Object.extend({
    initialize(options = {}) {
        this.options = Object.assign({}, defaultOptions, options);
        this.__createView(this.options);
    },

    setLoading(state) {
        this.view.setLoading(state);
    },

    __createView(options) {
        const allToolbarActions = new VirtualCollection(new Backbone.Collection(this.__getToolbarActions()));
        const comparator = factory.getDefaultComparator(options.columns);
        const collection = factory.createWrappedCollection(Object.assign({}, options, { comparator }));

        const debounceUpdateAction = _.debounce(() => this.__updateActions(allToolbarActions, collection), 10);
        this.__updateActions(allToolbarActions, collection);
        if (this.options.showToolbar) {
            if (this.options.showCheckbox) {
                this.listenTo(collection, 'check:all check:some check:none', debounceUpdateAction);
            } else {
                this.listenTo(collection, 'select:all select:some select:none deselect:one select:one', debounceUpdateAction);
            }
        }

        this.view = new GridView(
            Object.assign(this.options, {
                actions: allToolbarActions,
                collection,
                columns: options.columns
            })
        );

        this.listenTo(this.view, 'search', text => this.__onSearch(text, options.columns, collection));
        this.listenTo(this.view, 'execute:action', model => this.__executeAction(model, collection));
        this.listenTo(this.view, 'childview:click', this.__onItemClick);
        this.listenTo(this.view, 'childview:dblclick', this.__onItemDblClick);
        this.listenTo(this.view, 'drag:drop', this.__onItemMoved);
    },

    __onSearch(text, columns, collection) {
        if (!this.getOption('handleSearch')) {
            this.trigger('search', text);
            return;
        }
        if (text) {
            this.__applyFilter(new RegExp(text, 'i'), columns, collection);
            this.__highlightCollection(text, collection);
        } else {
            this.__clearFilter(collection);
            this.__unhighlightCollection(collection);
        }
    },

    __applyFilter(regexp, columns, collection) {
        collection.filter(model => {
            let result = false;
            const searchableColumns = columns.filter(column => column.searchable !== false).map(column => column.id || column.key);
            searchableColumns.forEach(column => {
                const values = model.get(column);
                const testValueFunction = value => {
                    if (value) {
                        const testValue = value.name || value.text || value.toString();
                        return regexp.test(testValue);
                    }
                };
                if (Array.isArray(values) && values.length) {
                    values.forEach(value => {
                        result = result || testValueFunction(value);
                    });
                } else {
                    result = result || testValueFunction(values);
                }
            });

            return result;
        });
    },

    __clearFilter(collection) {
        collection.filter();
    },

    __highlightCollection(text, collection) {
        collection.each(model => {
            model.highlight(text);
        });
    },

    __unhighlightCollection(collection) {
        collection.each(model => {
            model.unhighlight();
        });
    },

    __getToolbarActions() {
        let toolbarActions = [];
        const defaultActions = meta.getDefaultActions();
        if (!this.options.excludeActions) {
            toolbarActions = defaultActions;
        } else if (this.options.excludeActions !== 'all') {
            toolbarActions = defaultActions.filter(action => this.options.excludeActions.indexOf(action.id) === -1);
        }
        if (this.options.additionalActions) {
            toolbarActions = toolbarActions.concat(this.options.additionalActions);
        }
        return toolbarActions;
    },

    __updateActions(allToolbarActions, collection) {
        const selected = this.__getSelectedItems(collection).length;

        allToolbarActions.filter(action => {
            switch (action.get('contextType')) {
                case 'void':
                    return true;
                case 'one':
                    return selected === 1;
                case 'any':
                    return selected;
                default:
                    return true;
            }
        });
    },

    __getSelectedItems(collection) {
        const selected = (this.options.showCheckbox ? collection.checked : collection.selected) || {};
        if (selected instanceof Backbone.Model) {
            return [selected];
        }
        return Object.values(selected);
    },

    __executeAction(model, collection) {
        const selected = this.__getSelectedItems(collection);
        switch (model.get('id')) {
            case 'delete':
                this.__confirmUserAction(
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.TEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.TITLE'),
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.YESBUTTONTEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.NOBUTTONTEXT')
                ).then(result => {
                    if (result) {
                        this.__triggerAction(model, selected);
                    }
                });
                break;
            case 'archive':
                this.__confirmUserAction(
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.TEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.TITLE'),
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.YESBUTTONTEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.NOBUTTONTEXT')
                ).then(result => {
                    if (result) {
                        this.__triggerAction(model, selected);
                    }
                });
                break;
            case 'unarchive':
                this.__confirmUserAction(
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.TEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.TITLE'),
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.YESBUTTONTEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.NOBUTTONTEXT')
                ).then(result => {
                    if (result) {
                        this.__triggerAction(model, selected);
                    }
                });
                break;
            case 'add':
            default:
                this.__triggerAction(model, selected);
                break;
        }
    },

    __confirmUserAction(text, title, yesButtonText, noButtonText) {
        return Core.services.MessageService.showMessageDialog(text || '', title || '', [{ id: true, text: yesButtonText || 'Yes' }, { id: false, text: noButtonText || 'No' }]);
    },

    __triggerAction(model, selected) {
        this.trigger('execute', model, selected);
    },

    __onItemClick(model) {
        this.trigger('click', model);
    },

    __onItemDblClick(model) {
        this.trigger('dblclick', model);
    },

    __onItemMoved(...args) {
        this.trigger('move', ...args);
    }
});
<commit_msg>GridController: confirm popup buttons in correct order<commit_after>//@flow
import GridView from '../views/GridView';
import meta from '../meta';
import VirtualCollection from '../../collections/VirtualCollection';
import factory from '../factory';

/*
 * @param {Array} options.excludeActions Array of strings. Example: [ 'archive', 'delete' ].
 * @param {Array} options.additionalActions Array of objects [ id,  name,
 * type=button'|'checkbox', isChecked, iconClass, severity].
 * @param {Boolean} options.showCheckbox show or hide checkbox
 */

const defaultOptions = {
    isSliding: true,
    showHeader: true,
    handleSearch: true
};

export default Marionette.Object.extend({
    initialize(options = {}) {
        this.options = Object.assign({}, defaultOptions, options);
        this.__createView(this.options);
    },

    setLoading(state) {
        this.view.setLoading(state);
    },

    __createView(options) {
        const allToolbarActions = new VirtualCollection(new Backbone.Collection(this.__getToolbarActions()));
        const comparator = factory.getDefaultComparator(options.columns);
        const collection = factory.createWrappedCollection(Object.assign({}, options, { comparator }));

        const debounceUpdateAction = _.debounce(() => this.__updateActions(allToolbarActions, collection), 10);
        this.__updateActions(allToolbarActions, collection);
        if (this.options.showToolbar) {
            if (this.options.showCheckbox) {
                this.listenTo(collection, 'check:all check:some check:none', debounceUpdateAction);
            } else {
                this.listenTo(collection, 'select:all select:some select:none deselect:one select:one', debounceUpdateAction);
            }
        }

        this.view = new GridView(
            Object.assign(this.options, {
                actions: allToolbarActions,
                collection,
                columns: options.columns
            })
        );

        this.listenTo(this.view, 'search', text => this.__onSearch(text, options.columns, collection));
        this.listenTo(this.view, 'execute:action', model => this.__executeAction(model, collection));
        this.listenTo(this.view, 'childview:click', this.__onItemClick);
        this.listenTo(this.view, 'childview:dblclick', this.__onItemDblClick);
        this.listenTo(this.view, 'drag:drop', this.__onItemMoved);
    },

    __onSearch(text, columns, collection) {
        if (!this.getOption('handleSearch')) {
            this.trigger('search', text);
            return;
        }
        if (text) {
            this.__applyFilter(new RegExp(text, 'i'), columns, collection);
            this.__highlightCollection(text, collection);
        } else {
            this.__clearFilter(collection);
            this.__unhighlightCollection(collection);
        }
    },

    __applyFilter(regexp, columns, collection) {
        collection.filter(model => {
            let result = false;
            const searchableColumns = columns.filter(column => column.searchable !== false).map(column => column.id || column.key);
            searchableColumns.forEach(column => {
                const values = model.get(column);
                const testValueFunction = value => {
                    if (value) {
                        const testValue = value.name || value.text || value.toString();
                        return regexp.test(testValue);
                    }
                };
                if (Array.isArray(values) && values.length) {
                    values.forEach(value => {
                        result = result || testValueFunction(value);
                    });
                } else {
                    result = result || testValueFunction(values);
                }
            });

            return result;
        });
    },

    __clearFilter(collection) {
        collection.filter();
    },

    __highlightCollection(text, collection) {
        collection.each(model => {
            model.highlight(text);
        });
    },

    __unhighlightCollection(collection) {
        collection.each(model => {
            model.unhighlight();
        });
    },

    __getToolbarActions() {
        let toolbarActions = [];
        const defaultActions = meta.getDefaultActions();
        if (!this.options.excludeActions) {
            toolbarActions = defaultActions;
        } else if (this.options.excludeActions !== 'all') {
            toolbarActions = defaultActions.filter(action => this.options.excludeActions.indexOf(action.id) === -1);
        }
        if (this.options.additionalActions) {
            toolbarActions = toolbarActions.concat(this.options.additionalActions);
        }
        return toolbarActions;
    },

    __updateActions(allToolbarActions, collection) {
        const selected = this.__getSelectedItems(collection).length;

        allToolbarActions.filter(action => {
            switch (action.get('contextType')) {
                case 'void':
                    return true;
                case 'one':
                    return selected === 1;
                case 'any':
                    return selected;
                default:
                    return true;
            }
        });
    },

    __getSelectedItems(collection) {
        const selected = (this.options.showCheckbox ? collection.checked : collection.selected) || {};
        if (selected instanceof Backbone.Model) {
            return [selected];
        }
        return Object.values(selected);
    },

    __executeAction(model, collection) {
        const selected = this.__getSelectedItems(collection);
        switch (model.get('id')) {
            case 'delete':
                this.__confirmUserAction(
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.TEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.TITLE'),
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.YESBUTTONTEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.DELETE.CONFIRM.NOBUTTONTEXT')
                ).then(result => {
                    if (result) {
                        this.__triggerAction(model, selected);
                    }
                });
                break;
            case 'archive':
                this.__confirmUserAction(
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.TEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.TITLE'),
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.YESBUTTONTEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.ARCHIVE.CONFIRM.NOBUTTONTEXT')
                ).then(result => {
                    if (result) {
                        this.__triggerAction(model, selected);
                    }
                });
                break;
            case 'unarchive':
                this.__confirmUserAction(
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.TEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.TITLE'),
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.YESBUTTONTEXT'),
                    Localizer.get('CORE.GRID.ACTIONS.UNARCHIVE.CONFIRM.NOBUTTONTEXT')
                ).then(result => {
                    if (result) {
                        this.__triggerAction(model, selected);
                    }
                });
                break;
            case 'add':
            default:
                this.__triggerAction(model, selected);
                break;
        }
    },

    __confirmUserAction(text, title, yesButtonText, noButtonText) {
        return Core.services.MessageService.showMessageDialog(text || '', title || '', [{ id: false, text: noButtonText || 'No' }, { id: true, text: yesButtonText || 'Yes' }]);
    },

    __triggerAction(model, selected) {
        this.trigger('execute', model, selected);
    },

    __onItemClick(model) {
        this.trigger('click', model);
    },

    __onItemDblClick(model) {
        this.trigger('dblclick', model);
    },

    __onItemMoved(...args) {
        this.trigger('move', ...args);
    }
});
<|endoftext|>