<commit_before>import React from 'react';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import { Link } from 'gatsby';

import theme from '../theme';
import { media } from '../utils';
import SEO from '../components/SEO';
import Spacing from '../components/Spacing';
import Navigation from '../components/Navigation';
import Terminal from '../components/Terminal';

export default () => (
  <Wrapper>
    <SEO />

    <Navigation isHome />

    <Hero>
      <Title>
        Taito
         CLI
      </Title>

      <Spacing dir="y" />
      <Slogan>An extensible toolkit for DevOps and NoOps.</Slogan>
      <Spacing dir="y" amount={24} />

      <Actions>
        <Button to="/docs">Get started</Button>
        <Spacing amount={32} sm={{ amount: 16 }} />
        <Button to="/tutorial" variant="light">
          See the tutorial
        </Button>
      </Actions>
    </Hero>

    <Content>

        <SectionText>
          <SectionTitle>Standard command set</SectionTitle>

            Use the same simple command set from project to project no matter
            the technology or infrastructure. Easily manage your containers,
            functions, databases, object storages, and legacy applications
            wherever they are deployed. Just add a taito configuration file to
            your project, and you’re good to go.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>open client:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>status:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>logs:server:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>db copy:dev test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>db connect:test</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Any cloud, hybrid cloud, multicloud</SectionTitle>

            Deploy your applications to multiple platforms without any extra
            hassle. Leverage public cloud for fluent collaboration between
            in-house and external personnel during development. Deploy to
            on-premises to meet the extra security requirements of a production
            environment.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>zone create gcp</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>zone create vmware</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                project create full-stack-template
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:dev</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:canary</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:prod</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env merge:dev canary</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Simple to use</SectionTitle>

            Many daily tasks, such as connecting to a database, can be extremely
            tedious. Before actually connecting to the database, you have to
            locate the correct database cluster, the correct database in it, and
            the credentials for database access. You may also have to establish
            a secure tunnel by using a proxy.

With Taito CLI you achieve all this with a one simple command.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>db connect:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.grey[500]}>
                #
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>Without Taito CLI:</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                cloud_sql_proxy
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -instances=acme-zone:europe-west1:acme-postgres=tcp:127.0.0.1:5001
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                psql
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                psql -h 127.0.0.1 -p 5001 -d acme_chat_test -U acme_chat_test
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                Password:
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>******************</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>No lock-in</SectionTitle>

            Taito CLI is a lightweight wrapper that reduces technology and
            vendor lock-in by providing a standard command set on top of various
            platform specific tools. You just run a simple taito command, and
            Taito CLI runs a number of platform or technology specific commands
            under the hood based on your configuration.

            However, you can use all the tools also directly without Taito CLI.
            Therefore you can stop using Taito CLI at any time, if you like.
            There is no lock-in with Taito CLI.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>--verbose status:dev</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                [kubectl]
              </Terminal.LinePrefix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                config set-context acme-chat-dev
                --cluster=gke_my-gcp_europe-west1-c_my-kube1
                --user=gke_my-gcp_europe-west1-c_my-kube1
                --namespace=acme-chat-dev
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                config use-context acme-chat-dev
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>get cronjobs</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>get pods</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>top pod</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>{`get pods -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq`}</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                [helm]
              </Terminal.LinePrefix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                helm
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                list --namespace acme-chat-dev
              </Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>All tools included</SectionTitle>

            Working with modern hybrid cloud environments requires lots of
            tools. Taito CLI Docker container image contains all the tools you
            need, and you can upgrade it anytime by running:

          <InlineCode>taito upgrade</InlineCode>

            And if you need something special, it is very easy to customize the
            Taito CLI image with your own requirements.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>-- terraform apply</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -- kubectl get pods --namespace acme-chat-dev
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -- gcloud dns managed-zones list
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -- aws ec2 describe-instances
              </Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Extensible</SectionTitle>

            Add Taito CLI support for any technology by implementing a Taito CLI
            plugin. Create custom commands and share them with your colleagues
            as Taito CLI extensions. Implement project specific Taito CLI
            commands with npm or make.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                basket add pizza margherita
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>hours add 6.5</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Uniform conventions</SectionTitle>

            Maintain good and uniform conventions by providing reusable
            infrastructure templates and project templates. Use the same
            conventions no matter the technology or infrastructure.

            Customize software development workflows for your organization with
            custom Taito CLI extensions.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix color={theme.info}>
                nano
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                ~/.taito/taito-config.sh
              </Terminal.LineSuffix>,
            ],

              taito_global_extensions="git@github.com:MyOrg/myorg-extension.git"
            ,
            taito_global_plugins="myorg-git-global ...",
          ]}
        />

    </Content>
  </Wrapper>
);

const Wrapper = styled.div`
  width: 100%;
  height: 100%;

  & p {
    line-height: 1.5;
  }
`;

const Hero = styled.div`
  padding-top: 50px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 400px;
  background-color: ${props => props.theme.primary[500]};

  ${media.sm`
    height: auto;
    padding: 88px 16px 32px 16px;
    justify-content: flex-end;
    text-align: center;
  `}
`;

const Title = styled.h1`
  font-size: 48px;
  font-weight: 200;
  color: #fff;
  margin: 0px;

  ${media.sm`
    font-size: 32px;
  `}
`;

const Slogan = styled.h2`
  font-size: 20px;
  font-weight: 400;
  color: #fff;
  margin: 0;

  ${media.sm`
    font-size: 18px;
  `}
`;

const Actions = styled.div`
  display: flex;
  flex-direction: row;
`;

const Button = styled(Link)`
  padding: 8px 24px;
  background-color: ${props => props.theme.primary[300]};
  color: ${props => props.theme.primary[900]};
  text-align: center;
  text-decoration: none;
  border: none;
  border-radius: 99px;
  font-weight: 500;
  box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.2);

  ${props =>
    props.variant === 'light' &&
    css`
      background-color: #fff;
      color: ${props => props.theme.primary[500]};
    `}
`;

const Content = styled.div`
  max-width: 1100px;
  background-color: #fff;
  border-radius: 8px;
  padding: 23px;
  min-height: 100vh;
  box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.2);
  margin-top: -48px;
  margin-bottom: 32px;
  margin-right: auto;
  margin-left: auto;

  ${media.sm`
    padding: 16px;
    margin-top: 0px;
    box-shadow: none;
  `}
`;

const Section = styled.section`
  display: flex;
  flex-direction: row;

  ${media.sm`
    flex-direction: column;
    align-items: center;
  `}
`;

const Divider = styled.div`
  background-color: ${props => props.theme.grey[200]};
  height: 1px;
  width: 100%;
  margin: 64px 0px;

  ${media.sm`
    margin: 32px 0px;
  `}
`;

const SectionTitle = styled.h3`
  font-size: 24px;
  margin-top: 0px;
  margin-bottom: 16px;
  color: ${props => props.theme.black};
`;

const SectionText = styled.div`
  flex: 1;
`;

const InlineCode = styled.div`
  border-radius: 6px;
  background-color: ${props => props.theme.grey[200]};
  color: ${props => props.theme.grey[700]};
  padding: 8px 12px;
  font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono',
    'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono',
    'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L',
    'Courier New', Courier, monospace;
  font-size: 14px;
`;
<commit_msg>docs: add az command example, autoformatting<commit_after>import React from 'react';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import { Link } from 'gatsby';

import theme from '../theme';
import { media } from '../utils';
import SEO from '../components/SEO';
import Spacing from '../components/Spacing';
import Navigation from '../components/Navigation';
import Terminal from '../components/Terminal';

export default () => (
  <Wrapper>
    <SEO />

    <Navigation isHome />

    <Hero>
      <Title>
        Taito
         CLI
      </Title>

      <Spacing dir="y" />
      <Slogan>An extensible toolkit for DevOps and NoOps.</Slogan>
      <Spacing dir="y" amount={24} />

      <Actions>
        <Button to="/docs">Get started</Button>
        <Spacing amount={32} sm={{ amount: 16 }} />
        <Button to="/tutorial" variant="light">
          See the tutorial
        </Button>
      </Actions>
    </Hero>

    <Content>

        <SectionText>
          <SectionTitle>Standard command set</SectionTitle>

            Use the same simple command set from project to project no matter
            the technology or infrastructure. Easily manage your containers,
            functions, databases, object storages, and legacy applications
            wherever they are deployed. Just add a taito configuration file to
            your project, and you’re good to go.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>open client:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>status:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>logs:server:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>db copy:dev test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>db connect:test</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Any cloud, hybrid cloud, multicloud</SectionTitle>

            Deploy your applications to multiple platforms without any extra
            hassle. Leverage public cloud for fluent collaboration between
            in-house and external personnel during development. Deploy to
            on-premises to meet the extra security requirements of a production
            environment.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>zone create gcp</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>zone create vmware</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                project create full-stack-template
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:dev</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:canary</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env apply:prod</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>env merge:dev canary</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Simple to use</SectionTitle>

            Many daily tasks, such as connecting to a database, can be extremely
            tedious. Before actually connecting to the database, you have to
            locate the correct database cluster, the correct database in it, and
            the credentials for database access. You may also have to establish
            a secure tunnel by using a proxy.

With Taito CLI you achieve all this with a one simple command.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>db connect:test</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.grey[500]}>
                #
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>Without Taito CLI:</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                cloud_sql_proxy
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -instances=acme-zone:europe-west1:acme-postgres=tcp:127.0.0.1:5001
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                psql
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                psql -h 127.0.0.1 -p 5001 -d acme_chat_test -U acme_chat_test
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                Password:
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>******************</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>No lock-in</SectionTitle>

            Taito CLI is a lightweight wrapper that reduces technology and
            vendor lock-in by providing a standard command set on top of various
            platform specific tools. You just run a simple taito command, and
            Taito CLI runs a number of platform or technology specific commands
            under the hood based on your configuration.

            However, you can use all the tools also directly without Taito CLI.
            Therefore you can stop using Taito CLI at any time, if you like.
            There is no lock-in with Taito CLI.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>--verbose status:dev</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                [kubectl]
              </Terminal.LinePrefix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                config set-context acme-chat-dev
                --cluster=gke_my-gcp_europe-west1-c_my-kube1
                --user=gke_my-gcp_europe-west1-c_my-kube1
                --namespace=acme-chat-dev
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                config use-context acme-chat-dev
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>get cronjobs</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>get pods</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>top pod</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                kubectl
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>{`get pods -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq`}</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                [helm]
              </Terminal.LinePrefix>,
            ],
            [
              <Terminal.LinePrefix color={theme.info}>
                helm
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                list --namespace acme-chat-dev
              </Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>All tools included</SectionTitle>

            Working with modern hybrid cloud environments requires lots of
            tools. Taito CLI Docker container image contains all the tools you
            need, and you can upgrade it anytime by running:

          <InlineCode>taito upgrade</InlineCode>

            And if you need something special, it is very easy to customize the
            Taito CLI image with your own requirements.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>-- terraform apply</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -- kubectl get pods --namespace acme-chat-dev
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -- aws ec2 describe-instances
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>-- az network nic list</Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                -- gcloud dns managed-zones list
              </Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Extensible</SectionTitle>

            Add Taito CLI support for any technology by implementing a Taito CLI
            plugin. Create custom commands and share them with your colleagues
            as Taito CLI extensions. Implement project specific Taito CLI
            commands with npm or make.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                basket add pizza margherita
              </Terminal.LineSuffix>,
            ],
            [
              <Terminal.LinePrefix>taito</Terminal.LinePrefix>,
              <Terminal.LineSuffix>hours add 6.5</Terminal.LineSuffix>,
            ],
          ]}
        />

      <Divider />

        <SectionText>
          <SectionTitle>Uniform conventions</SectionTitle>

            Maintain good and uniform conventions by providing reusable
            infrastructure templates and project templates. Use the same
            conventions no matter the technology or infrastructure.

            Customize software development workflows for your organization with
            custom Taito CLI extensions.

        </SectionText>

        <Spacing amount={24} sm={{ dir: 'y', amount: 32 }} />

        <Terminal
          lines={[
            [
              <Terminal.LinePrefix color={theme.info}>
                nano
              </Terminal.LinePrefix>,
              <Terminal.LineSuffix>
                ~/.taito/taito-config.sh
              </Terminal.LineSuffix>,
            ],

              taito_global_extensions="git@github.com:MyOrg/myorg-extension.git"
            ,
            taito_global_plugins="myorg-git-global ...",
          ]}
        />

    </Content>
  </Wrapper>
);

const Wrapper = styled.div`
  width: 100%;
  height: 100%;

  & p {
    line-height: 1.5;
  }
`;

const Hero = styled.div`
  padding-top: 50px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 400px;
  background-color: ${(props) => props.theme.primary[500]};

  ${media.sm`
    height: auto;
    padding: 88px 16px 32px 16px;
    justify-content: flex-end;
    text-align: center;
  `}
`;

const Title = styled.h1`
  font-size: 48px;
  font-weight: 200;
  color: #fff;
  margin: 0px;

  ${media.sm`
    font-size: 32px;
  `}
`;

const Slogan = styled.h2`
  font-size: 20px;
  font-weight: 400;
  color: #fff;
  margin: 0;

  ${media.sm`
    font-size: 18px;
  `}
`;

const Actions = styled.div`
  display: flex;
  flex-direction: row;
`;

const Button = styled(Link)`
  padding: 8px 24px;
  background-color: ${(props) => props.theme.primary[300]};
  color: ${(props) => props.theme.primary[900]};
  text-align: center;
  text-decoration: none;
  border: none;
  border-radius: 99px;
  font-weight: 500;
  box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.2);

  ${(props) =>
    props.variant === 'light' &&
    css`
      background-color: #fff;
      color: ${(props) => props.theme.primary[500]};
    `}
`;

const Content = styled.div`
  max-width: 1100px;
  background-color: #fff;
  border-radius: 8px;
  padding: 23px;
  min-height: 100vh;
  box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.2);
  margin-top: -48px;
  margin-bottom: 32px;
  margin-right: auto;
  margin-left: auto;

  ${media.sm`
    padding: 16px;
    margin-top: 0px;
    box-shadow: none;
  `}
`;

const Section = styled.section`
  display: flex;
  flex-direction: row;

  ${media.sm`
    flex-direction: column;
    align-items: center;
  `}
`;

const Divider = styled.div`
  background-color: ${(props) => props.theme.grey[200]};
  height: 1px;
  width: 100%;
  margin: 64px 0px;

  ${media.sm`
    margin: 32px 0px;
  `}
`;

const SectionTitle = styled.h3`
  font-size: 24px;
  margin-top: 0px;
  margin-bottom: 16px;
  color: ${(props) => props.theme.black};
`;

const SectionText = styled.div`
  flex: 1;
`;

const InlineCode = styled.div`
  border-radius: 6px;
  background-color: ${(props) => props.theme.grey[200]};
  color: ${(props) => props.theme.grey[700]};
  padding: 8px 12px;
  font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono',
    'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono',
    'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L',
    'Courier New', Courier, monospace;
  font-size: 14px;
`;
<|endoftext|>


<commit_before>"use strict";

let name;
let size_x;
let size_y;
let minimumIteration;
let maximumIteration;
let view;

var Module = {
    'wasmBinaryFile': "rustybrot.wasm",
    'print': function(text) { console.log(name + ' asm stdout: ' + text) },
    'printErr': function(text) { console.log(name + ' asm stderr: ' + text) },
    'onRuntimeInitialized': asmInitialized,
    'noInitialRun': true
};

function asmInitialized() {
	let pointer = Module._malloc(size_x*size_y*2*3); // allocate buffer in asm module heap
	let moduleSharedArray = new Uint16Array(Module.HEAPU16.buffer, pointer, size_x*size_y*3); // create an array from this allocated memory

	let get_buddhabrot;

	if (view.x_min < -1.0 && view.x_max > 0.5 && view.y_min < -0.5 && view.y_max > 0.5) {
		get_buddhabrot = Module.cwrap('get_buddhabrot_color', 'number', ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']);
		console.log(name + ": asm initialized using standard MCMC");
	} else {
		get_buddhabrot = Module.cwrap('get_buddhabrot_metropolis_color', 'number', ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']);
		console.log(name + ": asm initialized using Metropolis-Hasting MCMC");
	}

	let num_sample = 1000;
	const duration_goal = 4000;
	const zoom = 0.005;

	while(true) {
		const t0 = performance.now();
		get_buddhabrot(moduleSharedArray.byteOffset, size_x, size_y, view.x_min, view.x_max, view.y_min, view.y_max, 1, 5000, 1, 500, 1, 50, num_sample);
		//get_buddhabrot(moduleSharedArray.byteOffset, size_x, size_y, -0.5, 0.4, 0.4, 0.5, 1, 1000, num_sample);
		//get_buddhabrot(moduleSharedArray.byteOffset, size_x, size_y, -0.043-zoom, -0.043+zoom, -0.986-zoom, -0.986+zoom, 1, 1000000, num_sample);

		const t1 = performance.now();
		const duration = t1 - t0;
		console.log("gen_buddhabrot with " + num_sample + " samples took " + duration + "ms");
		console.log("perf: " + (num_sample * 1000 / duration) + " sample/s");
		num_sample = num_sample * duration_goal / duration;
		console.log("adjuting num_sample to " + num_sample);

		const workerResultBuffer = new ArrayBuffer(size_x*size_y*2*3);
		const workerResult = new Uint16Array(workerResultBuffer);
		for (let i = 0; i < moduleSharedArray.length; i++) {
			workerResult[i] = moduleSharedArray[i];
		}

		postMessage([name, workerResultBuffer], [workerResultBuffer]);
	}

	Module._free(moduleSharedArray.byteOffset);
}

onmessage = function(event) {
	[name, size_x, size_y, view, minimumIteration, maximumIteration] = event.data;

	console.log(name + ": size=" + size_x + "x" + size_y + ", min_iter=" + minimumIteration + ", max_iter=" + maximumIteration + ", view=" + view);

	importScripts('rustybrot.wasm.js');
}
<commit_msg>Raise initial number of sample to 10000<commit_after>"use strict";

let name;
let size_x;
let size_y;
let minimumIteration;
let maximumIteration;
let view;

var Module = {
    'wasmBinaryFile': "rustybrot.wasm",
    'print': function(text) { console.log(name + ' asm stdout: ' + text) },
    'printErr': function(text) { console.log(name + ' asm stderr: ' + text) },
    'onRuntimeInitialized': asmInitialized,
    'noInitialRun': true
};

function asmInitialized() {
	let pointer = Module._malloc(size_x*size_y*2*3); // allocate buffer in asm module heap
	let moduleSharedArray = new Uint16Array(Module.HEAPU16.buffer, pointer, size_x*size_y*3); // create an array from this allocated memory

	let get_buddhabrot;

	if (view.x_min < -1.0 && view.x_max > 0.5 && view.y_min < -0.5 && view.y_max > 0.5) {
		get_buddhabrot = Module.cwrap('get_buddhabrot_color', 'number', ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']);
		console.log(name + ": asm initialized using standard MCMC");
	} else {
		get_buddhabrot = Module.cwrap('get_buddhabrot_metropolis_color', 'number', ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']);
		console.log(name + ": asm initialized using Metropolis-Hasting MCMC");
	}

	let num_sample = 10000;
	const duration_goal = 4000;
	const zoom = 0.005;

	while(true) {
		const t0 = performance.now();
		get_buddhabrot(moduleSharedArray.byteOffset, size_x, size_y, view.x_min, view.x_max, view.y_min, view.y_max, 1, 5000, 1, 500, 1, 50, num_sample);
		//get_buddhabrot(moduleSharedArray.byteOffset, size_x, size_y, -0.5, 0.4, 0.4, 0.5, 1, 1000, num_sample);
		//get_buddhabrot(moduleSharedArray.byteOffset, size_x, size_y, -0.043-zoom, -0.043+zoom, -0.986-zoom, -0.986+zoom, 1, 1000000, num_sample);

		const t1 = performance.now();
		const duration = t1 - t0;
		console.log("gen_buddhabrot with " + num_sample + " samples took " + duration + "ms");
		console.log("perf: " + (num_sample * 1000 / duration) + " sample/s");
		num_sample = num_sample * duration_goal / duration;
		console.log("adjuting num_sample to " + num_sample);

		const workerResultBuffer = new ArrayBuffer(size_x*size_y*2*3);
		const workerResult = new Uint16Array(workerResultBuffer);
		for (let i = 0; i < moduleSharedArray.length; i++) {
			workerResult[i] = moduleSharedArray[i];
		}

		postMessage([name, workerResultBuffer], [workerResultBuffer]);
	}

	Module._free(moduleSharedArray.byteOffset);
}

onmessage = function(event) {
	[name, size_x, size_y, view, minimumIteration, maximumIteration] = event.data;

	console.log(name + ": size=" + size_x + "x" + size_y + ", min_iter=" + minimumIteration + ", max_iter=" + maximumIteration + ", view=" + view);

	importScripts('rustybrot.wasm.js');
}
<|endoftext|>


<commit_before>import { getApiKey, gw2 } from '../gw2'
import pMap from 'p-map';

// shows achievement progress
export function achievement(room, message) {
    const achievementId = message.text.split(' ', 3)[1];

    const users = [{ id: message.fromUser.id, name: message.fromUser.username }];
    message.mentions.forEach(user => users.push({ id: user.userId, name: user.screenName }));

    gw2.achievements().get(achievementId).then(achievement => {
        pMap(users, user =>
            getApiKey(user.id)
                .then(apiKey =>
                    gw2.authenticate(apiKey).account().achievements().get(achievementId)
                    .then(progress => ({ user, progress }))
                    .catch(error => ({ user, error }))
                ).catch(error => ({ user, error: 'Missing API key (use `!auth <API-KEY` to set)' }))
        ).then(users => {
            room.send(
                `**${achievement.name}**  \n${achievement.description}\n\n`
                + users.map(user =>
                    user.progress
                        ? `@${user.user.name}'s progress: ${user.progress.current}/${user.progress.max}`
                        : `@${user.user.name}'s progress: ${user.error}.`
                ).join('\n  '));
        });
    }).catch(error => room.send(`Oah! Quaggan couldn't connect to the GW2 Api (${error}).`));
}
<commit_msg>fix typo in !achievement missing api key message<commit_after>import { getApiKey, gw2 } from '../gw2'
import pMap from 'p-map';

// shows achievement progress
export function achievement(room, message) {
    const achievementId = message.text.split(' ', 3)[1];

    const users = [{ id: message.fromUser.id, name: message.fromUser.username }];
    message.mentions.forEach(user => users.push({ id: user.userId, name: user.screenName }));

    gw2.achievements().get(achievementId).then(achievement => {
        pMap(users, user =>
            getApiKey(user.id)
                .then(apiKey =>
                    gw2.authenticate(apiKey).account().achievements().get(achievementId)
                    .then(progress => ({ user, progress }))
                    .catch(error => ({ user, error }))
                ).catch(error => ({ user, error: 'Missing API key (use `!auth <API-KEY>` to set)' }))
        ).then(users => {
            room.send(
                `**${achievement.name}**  \n${achievement.description}\n\n`
                + users.map(user =>
                    user.progress
                        ? `@${user.user.name}'s progress: ${user.progress.current}/${user.progress.max}`
                        : `@${user.user.name}'s progress: ${user.error}.`
                ).join('\n  '));
        });
    }).catch(error => room.send(`Oah! Quaggan couldn't connect to the GW2 Api (${error}).`));
}
<|endoftext|>


<commit_before>/*
 * marry.js - Marry your imaginary waifu or someone
 *
 *  Contributed by Capuccino
 */

/* eslint-env node */

exports.commands = [
    'marry',
    'divorce'
];

exports.marry = {
    desc: 'Marry Someone',
    longDesc: 'Marry your waifu in the guild.',
    usage: '<Mention>',
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (!ctx.suffix) {
                ctx.createMessage('Mention or cite your partner\'s name.');
            } else if (ctx.mentions[0].id === ctx.author.id) {
                ctx.createMessage('Hey! You\'re not allowed to marry yourself.');
            } else {
                ctx.createMessage(`${ctx.mentions[0].mention}, Will you marry ${ctx.author.mention}?\n You have 30 seconds to respond yes or no.`).then(() => {
                    bot.awaitMessage(ctx.channel.id, ctx.mentions[0].id, () => true, 30000).then(m => {
                        if (/y(es)?/i.test(m.content)) {
                            return ctx.createMessage(`I hereby Pronounce ${ctx.mentions[0].mention} and ${ctx.author.mention} as husband and wife! :two_hearts:`);
                        } else if (/no?/i.test(m.content)) {
                            return ctx.createMessage(`I'm sorry ${ctx.author.mention}, but your partner declined.`);
                        }
                    }).then(resolve).catch(() => {
                        ctx.createMessage('Your partner didn\'t respond in time or gave an invalid response.');
                    });
                }).then(resolve).catch(reject);
            }
        });
    }
};

exports.divorce = {
    desc: 'Divorce your waifu',
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (!ctx.suffix) {
                ctx.createMessage('We need to find out the partner you are trying to divorce first. Mention him/her.');
            } else if (ctx.mentions[0].id === ctx.author.id) {
                ctx.createMessage('Wew lad.');
            } else {
                ctx.createMessage(`${ctx.mentions[0].mention}, will you let go of ${ctx.author.mention}?\n You have 30 seconds to respond yes or no.`).then(() => {
                    bot.awaitMessage(ctx.channel.id, ctx.mentions[0].id, () => true, 30000).then(m => {
                        if (/y(es)?/i.test(m.content)) {
                            return ctx.createMessage(`${ctx.msg.author}, you're no longer married to ${ctx.mentions[0].mention}`);
                        } else if (/no?/i.test(m.content)) {
                            return ctx.createMessage('Your partner decided not to let go of you. I can\'t seperate you.');
                        }
                    }).then(resolve).catch(() => {
                        ctx.createMessage('Your partner didn\'t respond in time or gave an invalid response.');
                    });
                }).then(resolve).catch(reject);
            }
        });
    }
};<commit_msg>Refactor marry<commit_after>/*
 * marry.js - Marry your imaginary waifu or someone
 *
 * Contributed by Capuccino and Ovyerus
 */

/* eslint-env node */

exports.commands = [
    'marry',
    'divorce'
];

exports.marry = {
    desc: 'Marry someone.',
    usage: '<mention>',
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (ctx.args.length === 0 || ctx.mentionStrings.length === 0) {
                ctx.createMessage('Please mention your partner.').then(resolve).catch(reject);
            } else if (ctx.mentionStrings[0] === ctx.author.id) {
                ctx.createMessage("Hey! You're not allowed to marry yourself.").then(resolve).catch(reject);
            } else {
                ctx.createMessage(`<@${ctx.mentionStrings[0]}> will you marry ${ctx.author.mention}?\nRespond with yes or no. (30 seconds)`).then(() => {
                    return bot.awaitMessage(ctx.channel.id, ctx.mentionStrings[0], () => true, 30000);
                }).then(m => {
                    if (/y(es)?/i.test(m.content)) {
                        return ctx.createMessage(`I hereby pronounce <@${ctx.mentionStrings[0]}> and ${ctx.author.mention} as husband and wife. :sparkling_heart:`);
                    } else if (/no?/i.test(m.content)) {
                        return ctx.createMessage(`${ctx.author.mention}, unfortunately, your partner declined.`);
                    } else {
                        return ctx.createMessage(`<@${ctx.mentionStrings[0]}> that is not a valid answer.`);
                    }
                }).then(resolve).catch(err => {
                    if (err.message && err.message === 'Message await expired.') {
                        return ctx.createMessage(`${ctx.author.mention} your partner did not respond in time.`);
                    } else {
                        reject(err);
                    }
                }).then(resolve);
            }
        });
    }
};

exports.divorce = {
    desc: 'Divorce your partner.',
    usage: '<mention>',
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (ctx.args.length === 0 || ctx.mentionStrings.length === 0) {
                ctx.createMessage('Please mention your partner.').then(resolve).catch(reject);
            } else if (ctx.mentionStrings[0] === ctx.author.id) {
                ctx.createMessage("Hey! You can't divorce yourself.").then(resolve).catch(reject);
            } else {
                ctx.createMessage(`<@${ctx.mentionStrings[0]}>, will you let go of ${ctx.author.mention}?\nRespond with yes or no. (30 seconds)`).then(() => {
                    return bot.awaitMessage(ctx.channel.id, ctx.mentionStrings[0], () => true, 30000);
                }).then(m => {
                    if (/y(es)?/i.test(m.content)) {
                        return ctx.createMessage(`${ctx.author.mention} you're no longer married to <@${ctx.mentionStrings[0]}>.`);
                    } else if (/no?/i.test(m.content)) {
                        return ctx.createMessage(`${ctx.author.mention}, your partner won't let go.`);
                    } else {
                        return ctx.createMessage(`<@${ctx.mentionStrings[0]}> that is not a valid answer.`);
                    }
                }).then(resolve).catch(err => {
                    if (err.message && err.message === 'Message await expired.') {
                        return ctx.createMessage(`${ctx.author.mention} your partner did not respond in time.`);
                    } else {
                        reject(err);
                    }
                }).then(resolve);
            }
        });
    }
}<|endoftext|>


<commit_before>const Links = [
  {
    text: 'Support',
    href: 'http://read.ThinkingInReact.xyz/#support'
  },
  {
    text: 'Read',
    href: 'http://read.ThinkingInReact.xyz'
  },
  {
    text: 'GitHub',
    href: 'https://github.com/ThinkingInReact'
  },
  {
    text: 'Mailing list',
    href: 'http://eepurl.com/bU3k-j'
  }
];

export default Links;
<commit_msg>update Mailing List link label<commit_after>const Links = [
  {
    text: 'Support',
    href: 'http://read.ThinkingInReact.xyz/#support'
  },
  {
    text: 'Read',
    href: 'http://read.ThinkingInReact.xyz'
  },
  {
    text: 'GitHub',
    href: 'https://github.com/ThinkingInReact'
  },
  {
    text: 'Mailing List',
    href: 'http://eepurl.com/bU3k-j'
  }
];

export default Links;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
import { Link } from 'react-router'
import { injectIntl, intlShape, defineMessages, FormattedMessage } from 'react-intl'
import Items from '../components/Items'
import MediaType from '../components/MediaType'
import createPath from '../utils/createPath'
import { groupByBranch } from '../utils/sorting'

class SearchResult extends React.Component {
  constructor (props) {
    super(props)
    this.handleShowStatusClick = this.handleShowStatusClick.bind(this)
  }

  componentWillMount () {
    const { id } = this.props.result
    if (this.shouldShowStatus() && !this.props.resources[ id ]) {
      this.props.fetchWorkResource(id)
    }
  }

  renderContributors (contributors) {
    if (contributors.length > 0) {
      return (

{contributors.map(contribution => (

            {/* {this.props.intl.formatMessage({ id: contribution.role })} */}
            Av
            <Link to={contribution.agent.relativeUri}> {contribution.agent.name} </Link>

        ))}

      )
    }
  }

  renderDisplayTitle (result) {
    return (
      <Link data-automation-id="work-link" to={this.getResultUrl(result)}>

          {result.displayTitle}

      </Link>
    )
  }

  renderOriginalTitle (publication) {
    if (publication.originalTitle) {
      return (

            <FormattedMessage {...messages.originalTitle} /> {publication.originalTitle}

      )
    }
  }

  subjectSearchLink (subject) {
    return `/search?query=subject%3A${subject}`
  }

  genreSearchLink (genre) {
    return `/search?query=genre%3A${genre}`
  }

  seriesSearchLink (series) {
    return `/search?query=series%3A${series}`
  }

  renderSubjects (result) {
    if (result.subject) {
      return (

          <FormattedMessage {...messages.subjects} />

          {result.subject.map((subject, i) => (

                <Link
                  to={this.subjectSearchLink(subject)}> {subject} </Link> {(i < result.subject.length - 1) ? '|' : null}

          ))}

      )
    }
  }

  renderGenres (result) {
    if (result.genre) {
      return (

          <FormattedMessage {...messages.genres} />

          {result.genre.map((genre, i) => (

                <Link to={this.genreSearchLink(genre)}> {genre} </Link> {(i < result.genre.length - 1) ? '|' : null}

          ))}

      )
    }
  }

  renderSeries (publication) {
    return (

        <FormattedMessage {...messages.partOfSeries} />

          <Link to="#">Serie placeholder</Link>

    )

    // TOO: When series information is available ...
    /*
    return (

        <FormattedMessage {...messages.partOfSeries} />
        {publication.series.map((serie, i) => (

            <Link to={this.seriesSearchLink(serie)}> {serie} </Link> {(i < series.length - 1) ? '|' : null}

        ))}

    )
    */
  }

  getResultUrl (result) {
    const { pathname, search, hash } = window.location
    return createPath({
      pathname: result.relativePublicationUri || result.relativeUri,
      query: { back: `${pathname}${search}${hash}` }
    })
  }

  renderItems (result) {
    const resource = this.props.resources[ result.id ]
    if (resource) {
      return groupByBranch(resource.items).map(el => {
        return (

{el.branch}

            <Items items={el.items} />

        )
      })
    }
  }

  handleShowStatusClick (event) {
    event.stopPropagation()
    this.props.fetchWorkResource(this.props.result.id)
    this.props.showStatus(this.props.result.id)
  }

  shouldShowStatus () {
    const { locationQuery: { showStatus }, result: { id } } = this.props
    return (showStatus && showStatus === id || (Array.isArray(showStatus) && showStatus.includes(id)))
  }

  bookCoverText (result) {
    if (result.publication.mainEntryName) {
      return `${result.displayTitle} / ${result.publication.mainEntryName}`
    }
    return result.mainTitle
  }

  render () {
    const { result } = this.props
    const pubFormats = new Set()
    result.publication.formats = result.publication.formats || []
    result.publication.formats.forEach(format => {
      pubFormats.add(this.props.intl.formatMessage({ id: format }))
    })

    const formats = [ ...pubFormats ]
    const coverAltText = this.props.intl.formatMessage(messages.coverImageOf, { title: result.displayTitle })
    const missingCoverImage = '/images/no-cover.png'
    const missingCoverAltText = this.props.intl.formatMessage(messages.missingCoverImageOf, { title: result.displayTitle })
    return (
      <ReactCSSTransitionGroup
        transitionName="fade-in"
        transitionAppear
        transitionEnterTimeout={500}
        transitionLeaveTimeout={500}
        component="div"
        className="single-entry"
        data-formats={formats.join(', ')}>

          <Link to={this.getResultUrl(result)} className="book-cover-item">
            {result.image ?
              : }
          </Link>

            {result.mediaTypes.map(mediaType => {
              return <MediaType key={mediaType.uri} mediaType={mediaType} />
            })}

          {this.renderDisplayTitle(result)}
          {this.renderContributors(result.publication.contributors)}
          {this.renderOriginalTitle(result.publication)}
          {/* this.renderSeries(result.publication) */}
          {result.publication.abstract
            ?
{result.publication.abstract}

            : null
          }

          {this.renderSubjects(result.publication)}
          {this.renderGenres(result.publication)}

        {this.shouldShowStatus()
          ? [ (

<FormattedMessage {...messages.hideStatus} />

),
          (

            {this.renderItems(result)}

) ]
          : (

<FormattedMessage {...messages.showStatus} />

)
        }

      </ReactCSSTransitionGroup>
    )
  }
}

SearchResult.propTypes = {
  result: PropTypes.object.isRequired,
  locationQuery: PropTypes.object.isRequired,
  showStatus: PropTypes.func.isRequired,
  resources: PropTypes.object.isRequired,
  fetchWorkResource: PropTypes.func.isRequired,
  intl: intlShape.isRequired
}

export const messages = defineMessages({
  originalTitle: {
    id: 'SearchResult.originalTitle',
    description: 'The label for the original title',
    defaultMessage: 'Original title:'
  },
  allPublications: {
    id: 'SearchResult.allPublications',
    description: 'Link to go to all publications',
    defaultMessage: 'all publications ►'
  },
  availableAs: {
    id: 'SearchResult.availableAs',
    description: 'What formats the results is available as',
    defaultMessage: 'Available as:'
  },
  subjects: {
    id: 'SearchResult.subjects',
    description: 'The text displayed to identify subjects',
    defaultMessage: 'Subjects:'
  },
  genres: {
    id: 'SearchResult.genres',
    description: 'The text displayed to identify genres',
    defaultMessage: 'Genres:'
  },
  showStatus: {
    id: 'SearchResult.showStatus',
    description: 'Shown when the status is hidden',
    defaultMessage: 'Where can you find this'
  },
  hideStatus: {
    id: 'SearchResult.hideStatus',
    description: 'Shown when the status is shown',
    defaultMessage: 'Hide availability'
  },
  firstPublished: {
    id: 'SearchResult.firstPublished',
    description: 'Label for when the work was first published',
    defaultMessage: 'First published: '
  },
  coverImageOf: {
    id: 'SearchResult.coverImageOf',
    description: 'Used for alt text in images',
    defaultMessage: 'Cover image of: {title}'
  },
  missingCoverImageOf: {
    id: 'SearchResult.missingCoverImageOf',
    description: 'Used for placeholder cover images',
    defaultMessage: 'Missing cover image of: {title}'
  },
  partOfSeries: {
    id: 'SearchResult.partOfSeries',
    description: 'Text stating that publication is part of a series',
    defaultMessage: 'Part of series: '
  }
})

export default injectIntl(SearchResult)
<commit_msg>DIECH-290 Patron client - Add 'available as' to medatypes in search result<commit_after>import React, { PropTypes } from 'react'
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
import { Link } from 'react-router'
import { injectIntl, intlShape, defineMessages, FormattedMessage } from 'react-intl'
import Items from '../components/Items'
import MediaType from '../components/MediaType'
import createPath from '../utils/createPath'
import { groupByBranch } from '../utils/sorting'

class SearchResult extends React.Component {
  constructor (props) {
    super(props)
    this.handleShowStatusClick = this.handleShowStatusClick.bind(this)
  }

  componentWillMount () {
    const { id } = this.props.result
    if (this.shouldShowStatus() && !this.props.resources[ id ]) {
      this.props.fetchWorkResource(id)
    }
  }

  renderContributors (contributors) {
    if (contributors.length > 0) {
      return (

{contributors.map(contribution => (

            {/* {this.props.intl.formatMessage({ id: contribution.role })} */}
            Av
            <Link to={contribution.agent.relativeUri}> {contribution.agent.name} </Link>

        ))}

      )
    }
  }

  renderDisplayTitle (result) {
    return (
      <Link data-automation-id="work-link" to={this.getResultUrl(result)}>

          {result.displayTitle}

      </Link>
    )
  }

  renderOriginalTitle (publication) {
    if (publication.originalTitle) {
      return (

            <FormattedMessage {...messages.originalTitle} /> {publication.originalTitle}

      )
    }
  }

  subjectSearchLink (subject) {
    return `/search?query=subject%3A${subject}`
  }

  genreSearchLink (genre) {
    return `/search?query=genre%3A${genre}`
  }

  seriesSearchLink (series) {
    return `/search?query=series%3A${series}`
  }

  renderSubjects (result) {
    if (result.subject) {
      return (

          <FormattedMessage {...messages.subjects} />

          {result.subject.map((subject, i) => (

                <Link
                  to={this.subjectSearchLink(subject)}> {subject} </Link> {(i < result.subject.length - 1) ? '|' : null}

          ))}

      )
    }
  }

  renderGenres (result) {
    if (result.genre) {
      return (

          <FormattedMessage {...messages.genres} />

          {result.genre.map((genre, i) => (

                <Link to={this.genreSearchLink(genre)}> {genre} </Link> {(i < result.genre.length - 1) ? '|' : null}

          ))}

      )
    }
  }

  renderSeries (publication) {
    return (

        <FormattedMessage {...messages.partOfSeries} />

          <Link to="#">Serie placeholder</Link>

    )

    // TOO: When series information is available ...
    /*
    return (

        <FormattedMessage {...messages.partOfSeries} />
        {publication.series.map((serie, i) => (

            <Link to={this.seriesSearchLink(serie)}> {serie} </Link> {(i < series.length - 1) ? '|' : null}

        ))}

    )
    */
  }

  getResultUrl (result) {
    const { pathname, search, hash } = window.location
    return createPath({
      pathname: result.relativePublicationUri || result.relativeUri,
      query: { back: `${pathname}${search}${hash}` }
    })
  }

  renderItems (result) {
    const resource = this.props.resources[ result.id ]
    if (resource) {
      return groupByBranch(resource.items).map(el => {
        return (

{el.branch}

            <Items items={el.items} />

        )
      })
    }
  }

  handleShowStatusClick (event) {
    event.stopPropagation()
    this.props.fetchWorkResource(this.props.result.id)
    this.props.showStatus(this.props.result.id)
  }

  shouldShowStatus () {
    const { locationQuery: { showStatus }, result: { id } } = this.props
    return (showStatus && showStatus === id || (Array.isArray(showStatus) && showStatus.includes(id)))
  }

  bookCoverText (result) {
    if (result.publication.mainEntryName) {
      return `${result.displayTitle} / ${result.publication.mainEntryName}`
    }
    return result.mainTitle
  }

  render () {
    const { result } = this.props
    const pubFormats = new Set()
    result.publication.formats = result.publication.formats || []
    result.publication.formats.forEach(format => {
      pubFormats.add(this.props.intl.formatMessage({ id: format }))
    })

    const formats = [ ...pubFormats ]
    const coverAltText = this.props.intl.formatMessage(messages.coverImageOf, { title: result.displayTitle })
    const missingCoverImage = '/images/no-cover.png'
    const missingCoverAltText = this.props.intl.formatMessage(messages.missingCoverImageOf, { title: result.displayTitle })
    return (
      <ReactCSSTransitionGroup
        transitionName="fade-in"
        transitionAppear
        transitionEnterTimeout={500}
        transitionLeaveTimeout={500}
        component="div"
        className="single-entry"
        data-formats={formats.join(', ')}>

          <Link to={this.getResultUrl(result)} className="book-cover-item">
            {result.image ?
              : }
          </Link>

            <FormattedMessage {...messages.availableAs} />
            {result.mediaTypes.map(mediaType => {
              return <MediaType key={mediaType.uri} mediaType={mediaType} />
            })}

          {this.renderDisplayTitle(result)}
          {this.renderContributors(result.publication.contributors)}
          {this.renderOriginalTitle(result.publication)}
          {/* this.renderSeries(result.publication) */}
          {result.publication.abstract
            ?
{result.publication.abstract}

            : null
          }

          {this.renderSubjects(result.publication)}
          {this.renderGenres(result.publication)}

        {this.shouldShowStatus()
          ? [ (

<FormattedMessage {...messages.hideStatus} />

),
          (

            {this.renderItems(result)}

) ]
          : (

<FormattedMessage {...messages.showStatus} />

)
        }

      </ReactCSSTransitionGroup>
    )
  }
}

SearchResult.propTypes = {
  result: PropTypes.object.isRequired,
  locationQuery: PropTypes.object.isRequired,
  showStatus: PropTypes.func.isRequired,
  resources: PropTypes.object.isRequired,
  fetchWorkResource: PropTypes.func.isRequired,
  intl: intlShape.isRequired
}

export const messages = defineMessages({
  originalTitle: {
    id: 'SearchResult.originalTitle',
    description: 'The label for the original title',
    defaultMessage: 'Original title:'
  },
  allPublications: {
    id: 'SearchResult.allPublications',
    description: 'Link to go to all publications',
    defaultMessage: 'all publications ►'
  },
  availableAs: {
    id: 'SearchResult.availableAs',
    description: 'What formats the results is available as',
    defaultMessage: 'Available as:'
  },
  subjects: {
    id: 'SearchResult.subjects',
    description: 'The text displayed to identify subjects',
    defaultMessage: 'Subjects:'
  },
  genres: {
    id: 'SearchResult.genres',
    description: 'The text displayed to identify genres',
    defaultMessage: 'Genres:'
  },
  showStatus: {
    id: 'SearchResult.showStatus',
    description: 'Shown when the status is hidden',
    defaultMessage: 'Where can you find this'
  },
  hideStatus: {
    id: 'SearchResult.hideStatus',
    description: 'Shown when the status is shown',
    defaultMessage: 'Hide availability'
  },
  firstPublished: {
    id: 'SearchResult.firstPublished',
    description: 'Label for when the work was first published',
    defaultMessage: 'First published: '
  },
  coverImageOf: {
    id: 'SearchResult.coverImageOf',
    description: 'Used for alt text in images',
    defaultMessage: 'Cover image of: {title}'
  },
  missingCoverImageOf: {
    id: 'SearchResult.missingCoverImageOf',
    description: 'Used for placeholder cover images',
    defaultMessage: 'Missing cover image of: {title}'
  },
  partOfSeries: {
    id: 'SearchResult.partOfSeries',
    description: 'Text stating that publication is part of a series',
    defaultMessage: 'Part of series: '
  }
})

export default injectIntl(SearchResult)
<|endoftext|>


<commit_before>// Wraps all matrix.js API calls in Q promises.
//
// API calls usually accept callback functions. However, all API calls
// also return the result from request(opts, callback). It seems pointless
// to return from this since it is always "undefined". However, the "request"
// module is also injected into the SDK. This allows us to wrap the
// "request" module to return a promise, which is then passed all the
// way back up to the public facing API call.
//
// This wrapper is designed for Node.js development, but a similar
// technique can be trivially applied on the browser (e.g. for AngularJS)
"use strict";

var matrixcs = require("./matrix");
var request = require("request");
var q = require("q");

matrixcs.request(function(opts, callback) {
    var defer = q.defer();
    request(opts, function(err, response, body) {
        // TODO possibly expose a responseHandler API
        // to avoid duplicating the 400 check with the core lib.
        if (err) {
            defer.reject(err);
            return;
        }
        if (response.statusCode >= 400) {
            defer.reject(body);
        }
        else {
            defer.resolve(body);
        }
    });
    return defer.promise;
});
module.exports = matrixcs;

<commit_msg>Usage instructions<commit_after>// Wraps all matrix.js API calls in Q promises. To use this, simply
// require("matrix-promise") instead of require("matrix").
//
// API calls usually accept callback functions. However, all API calls
// also return the result from request(opts, callback). It seems pointless
// to return from this since it is always "undefined". However, the "request"
// module is also injected into the SDK. This allows us to wrap the
// "request" module to return a promise, which is then passed all the
// way back up to the public facing API call.
//
// This wrapper is designed for Node.js development, but a similar
// technique can be trivially applied on the browser (e.g. for AngularJS)
"use strict";

var matrixcs = require("./matrix");
var request = require("request");
var q = require("q");

matrixcs.request(function(opts, callback) {
    var defer = q.defer();
    request(opts, function(err, response, body) {
        // TODO possibly expose a responseHandler API
        // to avoid duplicating the 400 check with the core lib.
        if (err) {
            defer.reject(err);
            return;
        }
        if (response.statusCode >= 400) {
            defer.reject(body);
        }
        else {
            defer.resolve(body);
        }
    });
    return defer.promise;
});
module.exports = matrixcs;

<|endoftext|>


<commit_before>/*
 * message-scriba
 * https://github.com/parroit/message-scriba
 *
 * Copyright (c) 2013 parroit
 * Licensed under the MIT license.
 */

'use strict';

exports.Scriba = Scriba;

function Scriba() {

}

Scriba.prototype.run = function(dbPath,attachmentsPath){
    var eventError = "Please provide a non-empty string dbPath";
    if (typeof (dbPath) !== 'string') {
        throw new Error(eventError);
    }

    if (dbPath == '') {
        throw new Error(eventError);
    }

    eventError = "Please provide a non-empty attachmentsPath dbPath";
    if (typeof (attachmentsPath) !== 'string') {
        throw new Error(eventError);
    }

    if (attachmentsPath == '') {
        throw new Error(eventError);
    }

    var fs = require("fs");
    if (!fs.existsSync(attachmentsPath)){
        var mkdirp = require('mkdirp');
        mkdirp.sync(attachmentsPath,770);
    }

    var bus = require("corriera");

    var path = require("path");

    bus.on('attachmentParsing',/(.*)/,function(stream,fileName){
        var filePath = path.join(attachmentsPath, fileName);
        var diskFile = fs.createWriteStream(filePath);

        diskFile.once('finish',function(){

            bus.emit('attachmentSaved','any',filePath);
        });

        stream.pipe(diskFile);

    });

};
<commit_msg>permission<commit_after>/*
 * message-scriba
 * https://github.com/parroit/message-scriba
 *
 * Copyright (c) 2013 parroit
 * Licensed under the MIT license.
 */

'use strict';

exports.Scriba = Scriba;

function Scriba() {

}

Scriba.prototype.run = function(dbPath,attachmentsPath){
    var eventError = "Please provide a non-empty string dbPath";
    if (typeof (dbPath) !== 'string') {
        throw new Error(eventError);
    }

    if (dbPath == '') {
        throw new Error(eventError);
    }

    eventError = "Please provide a non-empty attachmentsPath dbPath";
    if (typeof (attachmentsPath) !== 'string') {
        throw new Error(eventError);
    }

    if (attachmentsPath == '') {
        throw new Error(eventError);
    }

    var fs = require("fs");
    if (!fs.existsSync(attachmentsPath)){
        var mkdirp = require('mkdirp');
        mkdirp.sync(attachmentsPath,770);
    }

    var bus = require("corriera");

    var path = require("path");

    bus.on('attachmentParsing',/(.*)/,function(stream,fileName){
        var filePath = path.join(attachmentsPath, fileName);
        try {
            var diskFile = fs.createWriteStream(filePath);

            diskFile.once('finish',function(){

                bus.emit('attachmentSaved','any',filePath);
            });

            stream.pipe(diskFile);
        } catch (err) {
            console.log(err);
        }

    });

};
<|endoftext|>


<commit_before>const rp = require('request-promise')
const api = require('vk-wrapper')

module.exports = (self) => {
  return () => {
    if (!self.longPollParams) {
      return api('messages.getLongPollServer', {
        need_pts: 1,
        lp_version: 2,
        access_token: self.settings.token,
        v: 5.65
      })
        .then((body) => {
          if (!body.response || !body.response.server) {
            throw new Error(JSON.stringify(body))
          }

          self.longPollParams = body.response
          self.listen()
        })
        .catch(console.error)
    }

    return rp({
      url: `https://${self.longPollParams.server}?act=a_check&key=${self.longPollParams.key}&ts=${self.longPollParams.ts}&wait=25&mode=2&version=2`,
      json: true
    })
      .then((body) => {
        if (body.failed) {
          if (body.failed && body.ts) {
            self.longPollParams.ts = body.ts
          } else {
            self.longPollParams = null
          }

          return self.listen()
        }

        if (body.ts) {
          self.longPollParams.ts = body.ts
        }

        self.listen()

        if (body.updates && body.updates.length) {
          body.updates.forEach((update) => {
            if (update[0] === 4 && (update[2] & 2) === 0) {
              const ctx = {
                user_id: update[3],
                body: update[5],
                attachments: update[6],
                date: update[4],
                message_id: update[1],
              }

              if (update[6].from) {
                ctx.from = +update[6].from
              }

              const getForward = (ctx) => {
                return new Promise((resolve) => {
                  if (!ctx.attachments || !ctx.attachments.fwd) {
                    resolve(null)
                  }

                  self.execute('messages.getById', {
                    message_ids: ctx.message_id,
                    v: 5.67
                  }, self.settings.token, (data) => {
                    resolve(self.getLastMessage(data.items[0]))
                  })
                })
              }

              getForward(ctx)
                .then((forward) => {
                  if (forward) {
                    ctx.forward = forward
                    ctx.body = forward.body
                  }

                  const attachmentsKeys = Object.keys(ctx.attachments).filter(key => key.search('attach') > -1 && key.search('type') === -1 && key.search('kind') === -1)
                  const attachments = []

                  attachmentsKeys.forEach((key) => {
                    const file = {}

                    file['type'] = ctx.attachments[`${key}_type`]
                    file[file.type] = ctx.attachments[key]

                    attachments.push(file)
                  })

                  ctx.attachments = attachments
                  ctx.body = ctx.body.replace(/
/g, '\n')

                  ctx.reply = (message, attachment) => self.reply(ctx.user_id, message, attachment)
                  ctx.sendMessage = (userId, message, attachment) => self.reply(ctx.user_id, message, attachment)

                  const command = ctx.body.toLowerCase()

                  if (self.actions.commands[command]) {
                    return self.actions.commands[command](ctx)
                  }

                  const method = {}

                  Object.keys(self.actions.hears).forEach((command) => {
                    method[command] = self.actions.hears[command]
                  })

                  if (Object.keys(method).length === 0) {
                    if (typeof self.actions.on.default === 'function') {
                      return self.actions.on.default(ctx)
                    }

                    return console.error('Bot can\'t found reserved reply.')
                  }

                  const hears = Object.keys(method).filter((regexp) => {
                    return new RegExp(regexp, 'i').test(command)
                  })

                  if (hears.length !== 0) {
                    return method[hears[0]](ctx)
                  }

                  if (typeof self.actions.on.default === 'function') {
                    return self.actions.on.default(ctx)
                  }

                  return console.error('Bot can\'t found reserved reply.')
                })
                .catch(console.error)
            }
          })
        }
      })
  }
}
<commit_msg>catch err in listen<commit_after>const rp = require('request-promise')
const api = require('vk-wrapper')

module.exports = (self) => {
  return () => {
    if (!self.longPollParams) {
      return api('messages.getLongPollServer', {
        need_pts: 1,
        lp_version: 2,
        access_token: self.settings.token,
        v: 5.65
      })
        .then((body) => {
          if (!body.response || !body.response.server) {
            throw new Error(JSON.stringify(body))
          }

          self.longPollParams = body.response
          self.listen()
        })
        .catch((err) => {
          self.longPollParams = null
          return self.listen()
        })
    }

    return rp({
      url: `https://${self.longPollParams.server}?act=a_check&key=${self.longPollParams.key}&ts=${self.longPollParams.ts}&wait=25&mode=2&version=2`,
      json: true
    })
      .then((body) => {
        if (body.failed) {
          if (body.failed && body.ts) {
            self.longPollParams.ts = body.ts
          } else {
            self.longPollParams = null
          }

          return self.listen()
        }

        if (body.ts) {
          self.longPollParams.ts = body.ts
        }

        self.listen()

        if (body.updates && body.updates.length) {
          body.updates.forEach((update) => {
            if (update[0] === 4 && (update[2] & 2) === 0) {
              const ctx = {
                user_id: update[3],
                body: update[5],
                attachments: update[6],
                date: update[4],
                message_id: update[1],
              }

              if (update[6].from) {
                ctx.from = +update[6].from
              }

              const getForward = (ctx) => {
                return new Promise((resolve) => {
                  if (!ctx.attachments || !ctx.attachments.fwd) {
                    resolve(null)
                  }

                  self.execute('messages.getById', {
                    message_ids: ctx.message_id,
                    v: 5.67
                  }, self.settings.token, (data) => {
                    resolve(self.getLastMessage(data.items[0]))
                  })
                })
              }

              getForward(ctx)
                .then((forward) => {
                  if (forward) {
                    ctx.forward = forward
                    ctx.body = forward.body
                  }

                  const attachmentsKeys = Object.keys(ctx.attachments).filter(key => key.search('attach') > -1 && key.search('type') === -1 && key.search('kind') === -1)
                  const attachments = []

                  attachmentsKeys.forEach((key) => {
                    const file = {}

                    file['type'] = ctx.attachments[`${key}_type`]
                    file[file.type] = ctx.attachments[key]

                    attachments.push(file)
                  })

                  ctx.attachments = attachments
                  ctx.body = ctx.body.replace(/
/g, '\n')

                  ctx.reply = (message, attachment) => self.reply(ctx.user_id, message, attachment)
                  ctx.sendMessage = (userId, message, attachment) => self.reply(ctx.user_id, message, attachment)

                  const command = ctx.body.toLowerCase()

                  if (self.actions.commands[command]) {
                    return self.actions.commands[command](ctx)
                  }

                  const method = {}

                  Object.keys(self.actions.hears).forEach((command) => {
                    method[command] = self.actions.hears[command]
                  })

                  if (Object.keys(method).length === 0) {
                    if (typeof self.actions.on.default === 'function') {
                      return self.actions.on.default(ctx)
                    }

                    return console.error('Bot can\'t found reserved reply.')
                  }

                  const hears = Object.keys(method).filter((regexp) => {
                    return new RegExp(regexp, 'i').test(command)
                  })

                  if (hears.length !== 0) {
                    return method[hears[0]](ctx)
                  }

                  if (typeof self.actions.on.default === 'function') {
                    return self.actions.on.default(ctx)
                  }

                  return console.error('Bot can\'t found reserved reply.')
                })
                .catch((err) => {
                  self.longPollParams = null
                  return self.listen()
                })
            }
          })
        }
      })
      .catch((err) => {
        self.longPollParams = null
        return self.listen()
      })
  }
}
<|endoftext|>


<commit_before>
"use strict";

var
    _       = require('underscore'),
    Promise = require("bluebird");

module.exports = function(sequelize, DataTypes) {
    var Leave = sequelize.define("Leave", {
        // TODO add validators!
        'status' : {
            type      : DataTypes.INTEGER,
            allowNull : false
        },
        employee_comment : {
            type      : DataTypes.STRING,
            allowNull : true,
        },
        approver_comment : {
            type      : DataTypes.STRING,
            allowNull : true,
        },
        decided_at : {
            type      : DataTypes.DATE,
            allowNull : true,
        },
    }, {

        classMethods : {
            associate : function( models ){
                Leave.belongsTo(models.User, { as : 'user',foreignKey     : 'id' });
                Leave.belongsTo(models.User, { as : 'approver',foreignKey : 'id' });
                Leave.belongsTo(models.LeaveType, { as : 'leave_type' } );
                Leave.hasMany(models.LeaveDay,    { as : 'days'       } );
            },

            /*
             * Create new leave for provided parameters.
             * Returns promise that is resolved with newly created leave row
             * */
            create_new_leave : function(args){

                // Make sure all required data is provided
                _.each(
                    ['for_employee','of_type','with_parameters'],
                    function(property){
                        if (! _.has(args, property)) {
                            throw new Error('No mandatory '+property+' was provided');
                        }
                    }
                );

                var employee      = args.for_employee,
                leave_type        = args.of_type,
                valide_attributes = args.with_parameters;

                // Make sure that booking to be created is not going to ovelap with
                // any existing bookings
                return Promise.try(function(){
                    return employee.validate_overlapping(valide_attributes);
                })
                .then(function(){
                    return employee.promise_superviser();
                })

                .then(function(superviser){

                    return sequelize.models.Leave.create({
                        UserId           : employee.id,
                        leaveTypeId      : leave_type.id,
                        status           : 1, // TODO remove magic number
                        ApproverId       : superviser.id,
                        employee_comment : valide_attributes.reason,
                    });
                })
                .then(function(leave){

                    var leave_request_attributes = _.clone(
                        valide_attributes
                    );
                    leave_request_attributes.leave = leave;

                    return Promise.try(function(){
                        return sequelize.models.LeaveDay.bulkCreate(
                            sequelize.models.LeaveDay.get_objects_for_bulk_create(
                                leave_request_attributes
                            )
                        );
                    })
                    .then(function(){
                        return Promise.resolve(leave);
                    });

                });
            }, // End of create_new_leave
        }, // End of class methods

        instanceMethods : {
            fit_with_leave_request : function(leave_request) {

                // If start and end dates are the same, check if one of them fit
                // into fist or last leave_days.
                if (
                    leave_request.is_within_one_day() && (
                        leave_request.does_fit_with_leave_day( _.last(this.days) )
                        ||
                        leave_request.does_fit_with_leave_day( _.first(this.days) )
                    )
                  ) {
                    return true;
                }

                // If start and end dates are different, check if start date
                // fits into end leave_day or end date fits int start leave_date.
                if (
                    (! leave_request.is_within_one_day()) && (
                        leave_request.does_fit_with_leave_day_at_start(
                             _.last(this.days)
                        )
                        ||
                        leave_request.does_fit_with_leave_day_at_end(
                             _.first(this.days)
                        )
                    )
                ) {
                    return true;
                }

                return false;
            } // End of fit_with_leave_request
        },

    });

    return Leave;
};
<commit_msg>REduce magic numbers<commit_after>
"use strict";

var
    _       = require('underscore'),
    Promise = require("bluebird");

module.exports = function(sequelize, DataTypes) {
    var Leave = sequelize.define("Leave", {
        // TODO add validators!
        'status' : {
            type      : DataTypes.INTEGER,
            allowNull : false
        },
        employee_comment : {
            type      : DataTypes.STRING,
            allowNull : true,
        },
        approver_comment : {
            type      : DataTypes.STRING,
            allowNull : true,
        },
        decided_at : {
            type      : DataTypes.DATE,
            allowNull : true,
        },
    }, {

        classMethods : {
            associate : function( models ){
                Leave.belongsTo(models.User, { as : 'user',foreignKey     : 'id' });
                Leave.belongsTo(models.User, { as : 'approver',foreignKey : 'id' });
                Leave.belongsTo(models.LeaveType, { as : 'leave_type' } );
                Leave.hasMany(models.LeaveDay,    { as : 'days'       } );
            },

            status_new : function(){
                return 1;
            },

            /*
             * Create new leave for provided parameters.
             * Returns promise that is resolved with newly created leave row
             * */
            create_new_leave : function(args){

                // Make sure all required data is provided
                _.each(
                    ['for_employee','of_type','with_parameters'],
                    function(property){
                        if (! _.has(args, property)) {
                            throw new Error('No mandatory '+property+' was provided');
                        }
                    }
                );

                var employee      = args.for_employee,
                leave_type        = args.of_type,
                valide_attributes = args.with_parameters;

                // Make sure that booking to be created is not going to ovelap with
                // any existing bookings
                return Promise.try(function(){
                    return employee.validate_overlapping(valide_attributes);
                })
                .then(function(){
                    return employee.promise_superviser();
                })

                .then(function(superviser){

                    return sequelize.models.Leave.create({
                        UserId           : employee.id,
                        leaveTypeId      : leave_type.id,
                        status           : Leave.status_new(),
                        ApproverId       : superviser.id,
                        employee_comment : valide_attributes.reason,
                    });
                })
                .then(function(leave){

                    var leave_request_attributes = _.clone(
                        valide_attributes
                    );
                    leave_request_attributes.leave = leave;

                    return Promise.try(function(){
                        return sequelize.models.LeaveDay.bulkCreate(
                            sequelize.models.LeaveDay.get_objects_for_bulk_create(
                                leave_request_attributes
                            )
                        );
                    })
                    .then(function(){
                        return Promise.resolve(leave);
                    });

                });
            }, // End of create_new_leave
        }, // End of class methods

        instanceMethods : {
            fit_with_leave_request : function(leave_request) {

                // If start and end dates are the same, check if one of them fit
                // into fist or last leave_days.
                if (
                    leave_request.is_within_one_day() && (
                        leave_request.does_fit_with_leave_day( _.last(this.days) )
                        ||
                        leave_request.does_fit_with_leave_day( _.first(this.days) )
                    )
                  ) {
                    return true;
                }

                // If start and end dates are different, check if start date
                // fits into end leave_day or end date fits int start leave_date.
                if (
                    (! leave_request.is_within_one_day()) && (
                        leave_request.does_fit_with_leave_day_at_start(
                             _.last(this.days)
                        )
                        ||
                        leave_request.does_fit_with_leave_day_at_end(
                             _.first(this.days)
                        )
                    )
                ) {
                    return true;
                }

                return false;
            } // End of fit_with_leave_request
        },

    });

    return Leave;
};
<|endoftext|>


<commit_before>https = require("https");

// Return the ISO 8601 format
// Ref: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Example.3a_ISO_8601_formatted_dates
function ISODateString(d){
 function pad(n){return n<10 ? '0'+n : n}
 return d.getUTCFullYear()+'-'
      + pad(d.getUTCMonth()+1)+'-'
      + pad(d.getUTCDate())+'T'
      + pad(d.getUTCHours())+':'
      + pad(d.getUTCMinutes())+':'
      + pad(d.getUTCSeconds())+'Z'
}

function GithubModule(settings) {
  this.settings = settings;

  // Created new date instance for the first time running
  // Set the time to midnight...
  var d = new Date();
  d.setUTCHours(0,0,0,0);
  var since = ISODateString(d);
  this.intervals = [[ function(cb){
    // console.log(since);
    options = {
      host: "api.github.com",
      path: '/repos/' + settings.repo +  '/issues?since=' + since
    };
    // Storing the current time. This time will be used
    // to pase in request next time
    since = ISODateString(new Date());
    https.get(options,function(res){
      data = "";
      res.on('data',function(d){
        data = data + d;
      });
      res.on('end',function(){
        data = JSON.parse(data);
        for(var i=0; i<data.length; i++){
          issue = data[i];
          msg = "*" + issue.title + "* reported by " + issue.user.login + ": " + issue.html_url;
          cb(msg);
        }
      })
    });
  }, this.settings.interval]];
}

exports.Module = GithubModule;
<commit_msg>Optimized GH a bit<commit_after>https = require("https");

// Return the ISO 8601 format
// Ref: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Example.3a_ISO_8601_formatted_dates
function ISODateString(d){
 function pad(n){return n<10 ? '0'+n : n}
 return d.getUTCFullYear()+'-'
      + pad(d.getUTCMonth()+1)+'-'
      + pad(d.getUTCDate())+'T'
      + pad(d.getUTCHours())+':'
      + pad(d.getUTCMinutes())+':'
      + pad(d.getUTCSeconds())+'Z'
}

function GithubModule(settings) {
  this.settings = settings;

  // Created new date instance for the first time running
  // Set the time to midnight...
  var d = new Date();
  d.setUTCHours(0,0,0,0);
  this.intervals = [[ function(cb){
    options = {
      host: "api.github.com",
      path: '/repos/' + settings.repo +  '/issues?since=' + ISODateString(d)
    };
    // Storing the current time. This time will be used
    // to pase in request next time
    d = new Date();
    https.get(options,function(res){
      data = "";
      res.on('data',function(d){
        data = data + d;
      });
      res.on('end',function(){
        data = JSON.parse(data);
        for(var i=0; i<data.length; i++){
          issue = data[i];
          msg = "*" + issue.title + "* reported by " + issue.user.login + ": " + issue.html_url;
          cb(msg);
        }
      })
    });
  }, this.settings.interval]];
}

exports.Module = GithubModule;
<|endoftext|>


<commit_before>// Require library
var Jimp = require('jimp');
var baseImage;
var pieces;
var coords = {
	"wK": {x: 0,   y: 0}, "bK":{x: 0,   y: 110},
	"wQ": {x: 110, y: 0}, "bQ":{x: 110, y: 110},
	"wB": {x: 220, y: 0}, "bB":{x: 220, y: 110},
	"wN": {x: 330, y: 0}, "bN":{x: 330, y: 110},
	"wR": {x: 440, y: 0}, "bR":{x: 440, y: 110},
	"wP": {x: 550, y: 0}, "bP":{x: 550, y: 110}
}
(function init(){
	var baseImageP = Jimp.read("./assets/base_board.png");
	var chessPieceP = Jimp.read("./assets/chess_pieces.png");
	Promise.all([baseImageP, chessPieceP]).then(function(values){
		baseImage = values[0];
		pieces = values[1];
	}).catch(function(err){
		console.log("ERROR LOADING PICTURES: " + err);
	});
})();

module.exports.createTestImage = function(){
	return new Promise(function (resolve, reject){
		console.log("Entering create Test Image");
		var image = new Jimp(1024, 1024, function (err, image){
			//idk if i need this call back;
			image.getBuffer(Jimp.MIME_PNG, function(err, thing){
				console.log("err: "+err);
				console.log(thing);
				resolve(thing);
			})
		});
	})
}

module.exports.createImage = function(board){
	return new Promise(function (resolve, reject){
		console.log("Entering create Test Image");
		console.log(baseImage);
		var image = baseImage.clone();
		return image.getBuffer(Jimp.MIME_PNG, function(err, thing){
			if (err){
				console.log("err: " + err);
				reject(err);
			}
			//Do things to image to make it board
			console.log(thing);
			resolve(thing);
		});
	})
}<commit_msg>Ok fixd stupid names still dont know why broke<commit_after>// Require library
var Jimp = require('jimp');
var baseImage;
var pieces;
var coords = {
	"wK": {x: 0,   y: 0}, "bK":{x: 0,   y: 110},
	"wQ": {x: 110, y: 0}, "bQ":{x: 110, y: 110},
	"wB": {x: 220, y: 0}, "bB":{x: 220, y: 110},
	"wN": {x: 330, y: 0}, "bN":{x: 330, y: 110},
	"wR": {x: 440, y: 0}, "bR":{x: 440, y: 110},
	"wP": {x: 550, y: 0}, "bP":{x: 550, y: 110}
}
	var baseImageP = Jimp.read("./assets/base_board.png");
	var chessPieceP = Jimp.read("./assets/chess_pieces.png");
	Promise.all([baseImageP, chessPieceP]).then(function(values){
		baseImage = values[0];
		pieces = values[1];
	}).catch(function(err){
		console.log("ERROR LOADING PICTURES: " + err);
	});
module.exports.createTestImage = function(){
	return new Promise(function (resolve, reject){
		console.log("Entering create Test Image");
		var image = new Jimp(1024, 1024, function (err, image){
			//idk if i need this call back;
			image.getBuffer(Jimp.MIME_PNG, function(err, thing){
				console.log("err: "+err);
				console.log(thing);
				resolve(thing);
			})
		});
	})
}

module.exports.createImage = function(board){
	return new Promise(function (resolve, reject){
		console.log("Entering create Test Image");
		console.log(baseImage);
		var image = baseImage.clone();
		return image.getBuffer(Jimp.MIME_PNG, function(err, thing){
			if (err){
				console.log("err: " + err);
				reject(err);
			}
			//Do things to image to make it board
			console.log(thing);
			resolve(thing);
		});
	})
}<|endoftext|>