<commit_before>var childProcess = require('child_process')
var escalade = require('escalade/sync')
var path = require('path')
var fs = require('fs')

var BrowserslistError = require('./error')

function detectLockfile () {
  var packageDir = escalade('.', function (dir, names) {
    return names.indexOf('package.json') !== -1 ? dir : ''
  })

  if (!packageDir) {
    throw new BrowserslistError(
      'Cannot find package.json. ' +
      'Is it a right project to run npx browserslist --update-db?'
    )
  }

  var lockfileNpm = path.join(packageDir, 'package-lock.json')
  var lockfileYarn = path.join(packageDir, 'yarn.lock')
  var lockfilePnpm = path.join(packageDir, 'pnpm-lock.yaml')

  /* istanbul ignore next */
  if (fs.existsSync(lockfilePnpm)) {
    return { mode: 'pnpm', file: lockfilePnpm }
  } else if (fs.existsSync(lockfileNpm)) {
    return { mode: 'npm', file: lockfileNpm }
  } else if (fs.existsSync(lockfileYarn)) {
    return { mode: 'yarn', file: lockfileYarn }
  } else {
    throw new BrowserslistError(
      'No lockfile found. Run "npm install", "yarn install" or "pnpm install"'
    )
  }
}

function getCurrentVersion (lock) {
  var match
  /* istanbul ignore if */
  if (lock.mode === 'pnpm') {
    match = /\/caniuse-lite\/([^:]+):/.exec(lock.content)
    if (match[1]) return match[1]
  } else if (lock.mode === 'npm') {
    var dependencies = JSON.parse(lock.content).dependencies
    if (dependencies && dependencies['caniuse-lite']) {
      return dependencies['caniuse-lite'].version
    }
  } else if (lock.mode === 'yarn') {
    match = /caniuse-lite@[^:]+:\n\s+version\s+"([^"]+)"/.exec(lock.content)
    if (match[1]) return match[1]
  }
  return null
}

function getLastestInfo () {
  return JSON.parse(
    childProcess.execSync('npm show caniuse-lite --json').toString()
  )
}

function updateLockfile (lock, latest) {
  if (lock.mode === 'npm') {
    var fixed = deletePackage(JSON.parse(lock.content))
    return JSON.stringify(fixed, null, '  ')
  } else {
    var lines = lock.content.split('\n')
    var i
    /* istanbul ignore if */
    if (lock.mode === 'pnpm') {
      for (i = 0; i < lines.length; i++) {
        if (lines[i].indexOf('caniuse-lite:') >= 0) {
          lines[i] = lines[i].replace(/: .*$/, ': ' + latest.version)
        } else if (lines[i].indexOf('/caniuse-lite') >= 0) {
          lines[i] = lines[i].replace(/\/[^/:]+:/, '/' + latest.version + ':')
          for (i = i + 1; i < lines.length; i++) {
            if (lines[i].indexOf('integrity: ') !== -1) {
              lines[i] = lines[i].replace(
                /integrity: .+/, 'integrity: ' + latest.dist.integrity
              )
            } else if (lines[i].indexOf(' /') !== -1) {
              break
            }
          }
        }
      }
    } else if (lock.mode === 'yarn') {
      for (i = 0; i < lines.length; i++) {
        if (lines[i].indexOf('caniuse-lite@') !== -1) {
          lines[i + 1] = lines[i + 1].replace(
            /version "[^"]+"/, 'version "' + latest.version + '"'
          )
          lines[i + 2] = lines[i + 2].replace(
            /resolved "[^"]+"/, 'resolved "' + latest.dist.tarball + '"'
          )
          lines[i + 3] = lines[i + 3].replace(
            /integrity .+/, 'integrity ' + latest.dist.integrity
          )
          i += 4
        }
      }
    }
    return lines.join('\n')
  }
}

function deletePackage (node) {
  if (node.dependencies) {
    delete node.dependencies['caniuse-lite']
    for (var i in node.dependencies) {
      node.dependencies[i] = deletePackage(node.dependencies[i])
    }
  }
  return node
}

module.exports = function updateDB (print) {
  var lock = detectLockfile()
  lock.content = fs.readFileSync(lock.file).toString()

  var current = getCurrentVersion(lock)
  var latest = getLastestInfo()

  if (typeof current === 'string') {
    print('Current version: ' + current + '\n')
  }
  print(
    'New version: ' + latest.version + '\n' +
    'Updating caniuse-lite…\n'
  )

  fs.writeFileSync(lock.file, updateLockfile(lock, latest))
  childProcess.execSync(lock.mode + ' install')

  print('caniuse-lite has been successfully updated')
}
<commit_msg>MINOR: fixing typo in function name (#530)<commit_after>var childProcess = require('child_process')
var escalade = require('escalade/sync')
var path = require('path')
var fs = require('fs')

var BrowserslistError = require('./error')

function detectLockfile () {
  var packageDir = escalade('.', function (dir, names) {
    return names.indexOf('package.json') !== -1 ? dir : ''
  })

  if (!packageDir) {
    throw new BrowserslistError(
      'Cannot find package.json. ' +
      'Is it a right project to run npx browserslist --update-db?'
    )
  }

  var lockfileNpm = path.join(packageDir, 'package-lock.json')
  var lockfileYarn = path.join(packageDir, 'yarn.lock')
  var lockfilePnpm = path.join(packageDir, 'pnpm-lock.yaml')

  /* istanbul ignore next */
  if (fs.existsSync(lockfilePnpm)) {
    return { mode: 'pnpm', file: lockfilePnpm }
  } else if (fs.existsSync(lockfileNpm)) {
    return { mode: 'npm', file: lockfileNpm }
  } else if (fs.existsSync(lockfileYarn)) {
    return { mode: 'yarn', file: lockfileYarn }
  } else {
    throw new BrowserslistError(
      'No lockfile found. Run "npm install", "yarn install" or "pnpm install"'
    )
  }
}

function getCurrentVersion (lock) {
  var match
  /* istanbul ignore if */
  if (lock.mode === 'pnpm') {
    match = /\/caniuse-lite\/([^:]+):/.exec(lock.content)
    if (match[1]) return match[1]
  } else if (lock.mode === 'npm') {
    var dependencies = JSON.parse(lock.content).dependencies
    if (dependencies && dependencies['caniuse-lite']) {
      return dependencies['caniuse-lite'].version
    }
  } else if (lock.mode === 'yarn') {
    match = /caniuse-lite@[^:]+:\n\s+version\s+"([^"]+)"/.exec(lock.content)
    if (match[1]) return match[1]
  }
  return null
}

function getLatestInfo () {
  return JSON.parse(
    childProcess.execSync('npm show caniuse-lite --json').toString()
  )
}

function updateLockfile (lock, latest) {
  if (lock.mode === 'npm') {
    var fixed = deletePackage(JSON.parse(lock.content))
    return JSON.stringify(fixed, null, '  ')
  } else {
    var lines = lock.content.split('\n')
    var i
    /* istanbul ignore if */
    if (lock.mode === 'pnpm') {
      for (i = 0; i < lines.length; i++) {
        if (lines[i].indexOf('caniuse-lite:') >= 0) {
          lines[i] = lines[i].replace(/: .*$/, ': ' + latest.version)
        } else if (lines[i].indexOf('/caniuse-lite') >= 0) {
          lines[i] = lines[i].replace(/\/[^/:]+:/, '/' + latest.version + ':')
          for (i = i + 1; i < lines.length; i++) {
            if (lines[i].indexOf('integrity: ') !== -1) {
              lines[i] = lines[i].replace(
                /integrity: .+/, 'integrity: ' + latest.dist.integrity
              )
            } else if (lines[i].indexOf(' /') !== -1) {
              break
            }
          }
        }
      }
    } else if (lock.mode === 'yarn') {
      for (i = 0; i < lines.length; i++) {
        if (lines[i].indexOf('caniuse-lite@') !== -1) {
          lines[i + 1] = lines[i + 1].replace(
            /version "[^"]+"/, 'version "' + latest.version + '"'
          )
          lines[i + 2] = lines[i + 2].replace(
            /resolved "[^"]+"/, 'resolved "' + latest.dist.tarball + '"'
          )
          lines[i + 3] = lines[i + 3].replace(
            /integrity .+/, 'integrity ' + latest.dist.integrity
          )
          i += 4
        }
      }
    }
    return lines.join('\n')
  }
}

function deletePackage (node) {
  if (node.dependencies) {
    delete node.dependencies['caniuse-lite']
    for (var i in node.dependencies) {
      node.dependencies[i] = deletePackage(node.dependencies[i])
    }
  }
  return node
}

module.exports = function updateDB (print) {
  var lock = detectLockfile()
  lock.content = fs.readFileSync(lock.file).toString()

  var current = getCurrentVersion(lock)
  var latest = getLatestInfo()

  if (typeof current === 'string') {
    print('Current version: ' + current + '\n')
  }
  print(
    'New version: ' + latest.version + '\n' +
    'Updating caniuse-lite…\n'
  )

  fs.writeFileSync(lock.file, updateLockfile(lock, latest))
  childProcess.execSync(lock.mode + ' install')

  print('caniuse-lite has been successfully updated')
}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React, { Component, Fragment } from 'react'
import { timeSince } from 'helpers/timeStampHelpers'
import UsernameText from 'components/Texts/UsernameText'
import UserListModal from 'components/Modals/UserListModal'
import {Link} from 'react-router-dom'
import { editTitle, deleteLink } from 'redux/actions/LinkActions'
import { connect } from 'react-redux'
import DropdownButton from 'components/DropdownButton'
import EditTitleForm from 'components/Texts/EditTitleForm'
import { cleanString } from 'helpers/stringHelpers'
import ConfirmModal from 'components/Modals/ConfirmModal'
import { Color } from 'constants/css'
import { css } from 'emotion'
import request from 'axios'
import { URL } from 'constants/URL'
const API_URL = `${URL}/content`

class LinkItem extends Component {
  static propTypes = {
    authLevel: PropTypes.number,
    canDelete: PropTypes.bool,
    canEdit: PropTypes.bool,
    deleteLink: PropTypes.func.isRequired,
    editTitle: PropTypes.func.isRequired,
    link: PropTypes.shape({
      content: PropTypes.string.isRequired,
      id: PropTypes.number.isRequired,
      title: PropTypes.string.isRequired,
      timeStamp: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
        .isRequired,
      uploaderName: PropTypes.string.isRequired,
      uploader: PropTypes.number.isRequired,
      likers: PropTypes.array.isRequired,
      numComments: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
        .isRequired
    }).isRequired,
    userId: PropTypes.number
  }

  apiUrl = 'https://api.embed.rocks/api'
  fallbackImage = '/img/link.png'

  constructor({ link: { thumbUrl } }) {
    super()
    this.state = {
      confirmModalShown: false,
      imageUrl: thumbUrl
        ? thumbUrl.replace('http://', 'https://')
        : '/img/link.png',
      userListModalShown: false,
      onEdit: false
    }
  }

  async componentDidMount() {
    this.mounted = true
    const { link: { id, content, siteUrl } } = this.props
    if (content && !siteUrl) {
      try {
        const { data: { image } } = await request.put(`${API_URL}/embed`, {
          url: content,
          linkId: id
        })
        if (this.mounted) {
          this.setState({
            imageUrl: image.url.replace('http://', 'https://')
          })
        }
      } catch (error) {
        console.error(error)
      }
    }
  }

  async componentDidUpdate(prevProps) {
    const { link: { content, id } } = this.props
    if (prevProps.link.content !== content) {
      try {
        const { data: { image } } = await request.put(`${API_URL}/embed`, {
          url: content,
          linkId: id
        })
        if (this.mounted) {
          this.setState({
            imageUrl: image.url.replace('http://', 'https://')
          })
        }
      } catch (error) {
        console.error(error)
      }
    }
  }

  render() {
    const {
      link: {
        id,
        title,
        timeStamp,
        uploaderName,
        uploader,
        likers,
        numComments,
        uploaderAuthLevel
      },
      authLevel,
      canEdit,
      canDelete,
      userId
    } = this.props
    const {
      confirmModalShown,
      imageUrl,
      userListModalShown,
      onEdit
    } = this.state
    const userIsUploader = userId === uploader
    const userCanEditThis =
      (canEdit || canDelete) && authLevel > uploaderAuthLevel
    const editButtonShown = userIsUploader || userCanEditThis
    const editMenuItems = []
    if (userIsUploader || canEdit) {
      editMenuItems.push({
        label: 'Edit',
        onClick: () => this.setState({ onEdit: true })
      })
    }
    if (userIsUploader || canDelete) {
      editMenuItems.push({
        label: 'Remove',
        onClick: () => this.setState({ confirmModalShown: true })
      })
    }

    return (

          <Link to={`/links/${id}`} onClickAsync={this.onLinkClick}>

          </Link>

                {!onEdit && (
                  <Link to={`/links/${id}`}>
                    {cleanString(title)}
                  </Link>
                )}
                {onEdit && (
                  <EditTitleForm
                    autoFocus
                    style={{ width: '80%' }}
                    maxLength={200}
                    title={title}
                    onEditSubmit={this.onEditedTitleSubmit}
                    onClickOutSide={() => this.setState({ onEdit: false })}
                  />
                )}

                Uploaded {`${timeSince(timeStamp)} `}by{' '}
                <UsernameText user={{ name: uploaderName, id: uploader }} />

              {likers.length > 0 && (
                <Fragment>
                   this.setState({ userListModalShown: true })}
                  >
                    {`${likers.length}`} like{likers.length > 1 ? 's' : ''}

                </Fragment>
              )}
              {numComments > 0 && (

                  {numComments} comment{numComments > 1 ? 's' : ''}

              )}

            {!onEdit &&
              editButtonShown && (
                <DropdownButton
                  snow
                  direction="left"
                  icon="pencil"
                  menuProps={editMenuItems}
                />
              )}

        {confirmModalShown && (
          <ConfirmModal
            title="Remove Link"
            onConfirm={this.onDelete}
            onHide={() => this.setState({ confirmModalShown: false })}
          />
        )}
        {userListModalShown && (
          <UserListModal
            users={likers}
            description="(You)"
            onHide={() => this.setState({ userListModalShown: false })}
            title="People who liked this link"
          />
        )}

    )
  }

  onDelete = () => {
    const { link, deleteLink } = this.props
    deleteLink(link.id)
  }

  onEditedTitleSubmit = text => {
    const { editTitle, link: { id } } = this.props
    return editTitle({ title: text, id }).then(() =>
      this.setState({ onEdit: false })
    )
  }

  onImageLoadError = () => {
    const { link: { thumbUrl } } = this.props
    this.setState(state => ({
      imageUrl:
        !thumbUrl || state.imageUrl === thumbUrl ? this.fallbackImage : thumbUrl
    }))
  }
}

export default connect(
  state => ({
    authLevel: state.UserReducer.authLevel,
    canDelete: state.UserReducer.canDelete,
    canEdit: state.UserReducer.canEdit,
    userId: state.UserReducer.userId
  }),
  { deleteLink, editTitle }
)(LinkItem)
<commit_msg>minor fix<commit_after>import PropTypes from 'prop-types'
import React, { Component, Fragment } from 'react'
import { timeSince } from 'helpers/timeStampHelpers'
import UsernameText from 'components/Texts/UsernameText'
import UserListModal from 'components/Modals/UserListModal'
import { Link } from 'react-router-dom'
import { editTitle, deleteLink } from 'redux/actions/LinkActions'
import { connect } from 'react-redux'
import DropdownButton from 'components/DropdownButton'
import EditTitleForm from 'components/Texts/EditTitleForm'
import { cleanString } from 'helpers/stringHelpers'
import ConfirmModal from 'components/Modals/ConfirmModal'
import { Color } from 'constants/css'
import { css } from 'emotion'
import request from 'axios'
import { URL } from 'constants/URL'
const API_URL = `${URL}/content`

class LinkItem extends Component {
  static propTypes = {
    authLevel: PropTypes.number,
    canDelete: PropTypes.bool,
    canEdit: PropTypes.bool,
    deleteLink: PropTypes.func.isRequired,
    editTitle: PropTypes.func.isRequired,
    link: PropTypes.shape({
      content: PropTypes.string.isRequired,
      id: PropTypes.number.isRequired,
      title: PropTypes.string.isRequired,
      timeStamp: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
        .isRequired,
      uploaderName: PropTypes.string.isRequired,
      uploader: PropTypes.number.isRequired,
      likers: PropTypes.array.isRequired,
      numComments: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
        .isRequired
    }).isRequired,
    userId: PropTypes.number
  }

  apiUrl = 'https://api.embed.rocks/api'
  fallbackImage = '/img/link.png'

  constructor({ link: { thumbUrl } }) {
    super()
    this.state = {
      confirmModalShown: false,
      imageUrl: thumbUrl
        ? thumbUrl.replace('http://', 'https://')
        : '/img/link.png',
      userListModalShown: false,
      onEdit: false
    }
  }

  async componentDidMount() {
    this.mounted = true
    const { link: { id, content, siteUrl } } = this.props
    if (content && !siteUrl) {
      try {
        const { data: { image } } = await request.put(`${API_URL}/embed`, {
          url: content,
          linkId: id
        })
        if (this.mounted) {
          this.setState({
            imageUrl: image.url.replace('http://', 'https://')
          })
        }
      } catch (error) {
        console.error(error)
      }
    }
  }

  async componentDidUpdate(prevProps) {
    const { link: { content, id } } = this.props
    if (prevProps.link.content !== content) {
      try {
        const { data: { image } } = await request.put(`${API_URL}/embed`, {
          url: content,
          linkId: id
        })
        if (this.mounted) {
          this.setState({
            imageUrl: image.url.replace('http://', 'https://')
          })
        }
      } catch (error) {
        console.error(error)
      }
    }
  }

  render() {
    const {
      link: {
        id,
        title,
        timeStamp,
        uploaderName,
        uploader,
        likers,
        numComments,
        uploaderAuthLevel
      },
      authLevel,
      canEdit,
      canDelete,
      userId
    } = this.props
    const {
      confirmModalShown,
      imageUrl,
      userListModalShown,
      onEdit
    } = this.state
    const userIsUploader = userId === uploader
    const userCanEditThis =
      (canEdit || canDelete) && authLevel > uploaderAuthLevel
    const editButtonShown = userIsUploader || userCanEditThis
    const editMenuItems = []
    if (userIsUploader || canEdit) {
      editMenuItems.push({
        label: 'Edit',
        onClick: () => this.setState({ onEdit: true })
      })
    }
    if (userIsUploader || canDelete) {
      editMenuItems.push({
        label: 'Remove',
        onClick: () => this.setState({ confirmModalShown: true })
      })
    }

    return (

          <Link to={`/links/${id}`}>

          </Link>

                {!onEdit && (
                  <Link to={`/links/${id}`}>{cleanString(title)}</Link>
                )}
                {onEdit && (
                  <EditTitleForm
                    autoFocus
                    style={{ width: '80%' }}
                    maxLength={200}
                    title={title}
                    onEditSubmit={this.onEditedTitleSubmit}
                    onClickOutSide={() => this.setState({ onEdit: false })}
                  />
                )}

                Uploaded {`${timeSince(timeStamp)} `}by{' '}
                <UsernameText user={{ name: uploaderName, id: uploader }} />

              {likers.length > 0 && (
                <Fragment>
                   this.setState({ userListModalShown: true })}
                  >
                    {`${likers.length}`} like{likers.length > 1 ? 's' : ''}

                </Fragment>
              )}
              {numComments > 0 && (

                  {numComments} comment{numComments > 1 ? 's' : ''}

              )}

            {!onEdit &&
              editButtonShown && (
                <DropdownButton
                  snow
                  direction="left"
                  icon="pencil"
                  menuProps={editMenuItems}
                />
              )}

        {confirmModalShown && (
          <ConfirmModal
            title="Remove Link"
            onConfirm={this.onDelete}
            onHide={() => this.setState({ confirmModalShown: false })}
          />
        )}
        {userListModalShown && (
          <UserListModal
            users={likers}
            description="(You)"
            onHide={() => this.setState({ userListModalShown: false })}
            title="People who liked this link"
          />
        )}

    )
  }

  onDelete = () => {
    const { link, deleteLink } = this.props
    deleteLink(link.id)
  }

  onEditedTitleSubmit = text => {
    const { editTitle, link: { id } } = this.props
    return editTitle({ title: text, id }).then(() =>
      this.setState({ onEdit: false })
    )
  }

  onImageLoadError = () => {
    const { link: { thumbUrl } } = this.props
    this.setState(state => ({
      imageUrl:
        !thumbUrl || state.imageUrl === thumbUrl ? this.fallbackImage : thumbUrl
    }))
  }
}

export default connect(
  state => ({
    authLevel: state.UserReducer.authLevel,
    canDelete: state.UserReducer.canDelete,
    canEdit: state.UserReducer.canEdit,
    userId: state.UserReducer.userId
  }),
  { deleteLink, editTitle }
)(LinkItem)
<|endoftext|>


<commit_before>import { DateTime, Interval } from "luxon";
import PropTypes from "prop-types";
import React, { useCallback, useMemo, useState } from "react";
import { useLocation } from "react-router-dom";
import styled from "styled-components";
import { mutate } from "swr";
import { RawFeatherIcon } from "@agir/front/genericComponents/FeatherIcon";

import { useSelector } from "@agir/front/globalContext/GlobalContext";
import {
  getIsConnected,
  getRoutes,
  getUser,
} from "@agir/front/globalContext/reducers";
import * as api from "@agir/events/common/api";

import Button from "@agir/front/genericComponents/Button";
import Link from "@agir/front/app/Link";
import { Hide } from "@agir/front/genericComponents/grid";
import SubscriptionTypeModal from "@agir/front/authentication/SubscriptionTypeModal";

import style from "@agir/front/genericComponents/_variables.scss";
import { displayHumanDate, displayIntervalEnd } from "@agir/lib/utils/time";

import QuitEventButton from "./QuitEventButton";

import logger from "@agir/lib/utils/logger";
import {rsvpEvent} from "../common/api";

const log = logger(__filename);

const EventHeaderContainer = styled.div`
  @media (min-width: ${style.collapse}px) {
    margin-bottom: 2rem;
  }
  > * {
    margin: 0.5rem 0;
  }
`;

const EventTitle = styled.h1`
  font-size: 1.75rem;
  line-height: 1.4;
  font-weight: 700;
  margin-bottom: 0;

  @media (max-width: ${style.collapse}px) {
    margin-bottom: 1rem;
    font-size: 1.25rem;
  }
`;

const EventDate = styled.div`
  margin: 0.5rem 0;
  font-weight: 500;
`;

const SmallText = styled.div`
  font-size: 0.81rem;
  font-color: ${style.black500};
`;

const ActionButton = styled(Button)``;
const ActionLink = styled(Link)`
  font-weight: 700;
  text-decoration: underline;
`;
const ActionDetails = styled.div`
  margin-top: 0;
  font-size: 1rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;

  div {
    display: inline-flex;
    align-items: center;
  }
`;

const StyledActionButtons = styled.div`
  display: inline-grid;
  grid-gap: 0.5rem;
  grid-template-columns: auto auto;
  padding: 0.5rem 0;

  @media (max-width: ${style.collapse}px) {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  }

  ${Button} {
    margin: 0;
    justify-content: center;

    && *,
    && *::before {
      flex: 0 0 auto;
    }
  }

  ${Button} + ${Button} {
    margin-left: 0;
  }
`;

const RSVPButton = (props) => {
  const user = useSelector(getUser);
  const { id, forUsers, hasPrice, routes } = props;

  const [isLoading, setIsLoading] = useState(false);
  const [hasSubscriptionTypeModal, setHasSubscriptionTypeModal] =
    useState(false);

  const openSubscriptionTypeModal = useCallback(() => {
    setHasSubscriptionTypeModal(true);
  }, []);

  const closeSubscriptionTypeModal = useCallback(() => {
    setHasSubscriptionTypeModal(false);
  }, []);

  const handleRSVP = useCallback(
    async (e) => {
      e && e.preventDefault();
      setIsLoading(true);

      if (hasPrice) {
        log.debug("Has price, redirection.");
        window.location.href = routes.rsvp;
        return;
      }

      try {
        const response = await api.rsvpEvent(id);
        if (response.error) {
          log.error(response.error);
          await mutate(api.getEventEndpoint("getEvent", { eventPk: id }));
        }
      } catch (err) {
        window.location.reload();
      }

      setIsLoading(false);
      setHasSubscriptionTypeModal(false);

      await mutate(
        api.getEventEndpoint("getEvent", { eventPk: id }),
        (event) => ({
          ...event,
          rsvped: true,
        })
      );
    },
    [id, hasPrice, routes]
  );

  const shouldUpdateSubscription = useMemo(() => {
    if (!user) {
      return null;
    }
    if (forUsers === "2" && user.is2022) {
      return null;
    }
    if (forUsers === "I" && user.isInsoumise) {
      return null;
    }
    return forUsers === "2" ? "NSP" : "LFI";
  }, [user, forUsers]);

  return (

  );
};

const ActionButtons = (props) => {
  const {
    id,
    name,
    past,
    rsvped,
    logged,
    isOrganizer,
    routes,
    onlineUrl,
    hasPrice,
    allowGuests,
  } = props;

  if (past) {
    return (

    );
  }

  if (!logged) {
    return (

    );
  }

  if (rsvped) {
    return (
      <>

        <ActionDetails>

            <RawFeatherIcon name="check" color="green" />  Vous participez
            à l'évènement

          {!hasPrice && <QuitEventButton id={id} name={name} />}
        </ActionDetails>
      </>
    );
  }

  return <RSVPButton {...props} />;
};
RSVPButton.propTypes = ActionButtons.propTypes = {
  id: PropTypes.string,
  name: PropTypes.string,
  onlineUrl: PropTypes.string,
  hasSubscriptionForm: PropTypes.bool,
  hasPrice: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  routes: PropTypes.shape({
    manage: PropTypes.string,
    rsvp: PropTypes.string,
  }),
};

const AdditionalMessage = ({
  isOrganizer,
  logged,
  rsvped,
  price,
  forUsers,
}) => {
  const location = useLocation();

  if (!logged) {
    return (

        <ActionLink
          route="login"
          params={{ from: "event", forUsers, next: location.pathname }}
        >
          Je me connecte
        </ActionLink>{" "}
        ou{" "}
        <ActionLink
          route="signup"
          params={{ from: "event", forUsers, next: location.pathname }}
        >
          je m'inscris
        </ActionLink>{" "}
        pour participer à l'événement

    );
  }

  if (price) {
    return (
      <SmallText>
        Entrée :
        {price}
      </SmallText>
    );
  }

  if (!isOrganizer && !rsvped) {
    return (
      <SmallText>Votre email sera communiqué à l'organisateur·ice</SmallText>
    );
  }

  return <></>;
};
AdditionalMessage.propTypes = {
  id: PropTypes.string,
  name: PropTypes.string,
  hasSubscriptionForm: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  price: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
};

const EventHeader = ({
  id,
  name,
  rsvp,
  options,
  schedule,
  routes,
  isOrganizer,
  forUsers,
  hasRightSubscription,
  onlineUrl,
  allowGuests,
}) => {
  const globalRoutes = useSelector(getRoutes);
  const logged = useSelector(getIsConnected);

  const rsvped = rsvp === "CO";
  const now = DateTime.local();
  const past = now > schedule.end;
  let eventString = displayHumanDate(schedule.start);
  eventString = eventString.slice(0, 1).toUpperCase() + eventString.slice(1);

  const pending = now >= schedule.start && now <= schedule.end;
  const eventDate = pending ? displayIntervalEnd(schedule) : eventString;

  return (
    <EventHeaderContainer>
      <EventTitle>{name}</EventTitle>
      <Hide under>
        <EventDate>{eventDate}</EventDate>
      </Hide>
      <ActionButtons
        id={id}
        past={past}
        logged={logged}
        rsvped={rsvped}
        routes={routes}
        isOrganizer={isOrganizer}
        forUsers={forUsers}
        hasRightSubscription={hasRightSubscription}
        hasPrice={!!options && !!options.price}
        onlineUrl={onlineUrl}
        allowGuests={allowGuests}
      />
      {!past && (
        <AdditionalMessage
          id={id}
          name={name}
          isOrganizer={isOrganizer}
          past={past}
          logged={logged}
          rsvped={rsvped}
          price={options.price}
          routes={{ ...routes, ...globalRoutes }}
          forUsers={forUsers}
        />
      )}
    </EventHeaderContainer>
  );
};

EventHeader.propTypes = {
  id: PropTypes.string,
  name: PropTypes.string,
  onlineUrl: PropTypes.string,
  startTime: PropTypes.instanceOf(DateTime),
  endTime: PropTypes.instanceOf(DateTime),
  schedule: PropTypes.instanceOf(Interval),
  hasSubscriptionForm: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  options: PropTypes.shape({
    price: PropTypes.string,
  }),
  rsvp: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
  hasRightSubscription: PropTypes.bool,
  allowGuests: PropTypes.bool,
};

export default EventHeader;
<commit_msg>format correctly the add a guest button<commit_after>import { DateTime, Interval } from "luxon";
import PropTypes from "prop-types";
import React, { useCallback, useMemo, useState } from "react";
import { useLocation } from "react-router-dom";
import styled from "styled-components";
import { mutate } from "swr";
import { RawFeatherIcon } from "@agir/front/genericComponents/FeatherIcon";

import { useSelector } from "@agir/front/globalContext/GlobalContext";
import {
  getIsConnected,
  getRoutes,
  getUser,
} from "@agir/front/globalContext/reducers";
import * as api from "@agir/events/common/api";

import Button from "@agir/front/genericComponents/Button";
import Link from "@agir/front/app/Link";
import { Hide } from "@agir/front/genericComponents/grid";
import SubscriptionTypeModal from "@agir/front/authentication/SubscriptionTypeModal";

import style from "@agir/front/genericComponents/_variables.scss";
import { displayHumanDate, displayIntervalEnd } from "@agir/lib/utils/time";

import QuitEventButton from "./QuitEventButton";

import logger from "@agir/lib/utils/logger";

const log = logger(__filename);

const EventHeaderContainer = styled.div`
  @media (min-width: ${style.collapse}px) {
    margin-bottom: 2rem;
  }
  > * {
    margin: 0.5rem 0;
  }
`;

const EventTitle = styled.h1`
  font-size: 1.75rem;
  line-height: 1.4;
  font-weight: 700;
  margin-bottom: 0;

  @media (max-width: ${style.collapse}px) {
    margin-bottom: 1rem;
    font-size: 1.25rem;
  }
`;

const EventDate = styled.div`
  margin: 0.5rem 0;
  font-weight: 500;
`;

const SmallText = styled.div`
  font-size: 0.81rem;
  font-color: ${style.black500};
`;

const ActionButton = styled(Button)``;
const ActionLink = styled(Link)`
  font-weight: 700;
  text-decoration: underline;
`;
const ActionDetails = styled.div`
  margin-top: 0;
  font-size: 1rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;

  div {
    display: inline-flex;
    align-items: center;
  }
`;

const StyledActionButtons = styled.div`
  display: inline-grid;
  grid-gap: 0.5rem;
  grid-template-columns: auto auto;
  padding: 0.5rem 0;

  @media (max-width: ${style.collapse}px) {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  }

  ${Button} {
    margin: 0;
    justify-content: center;

    && *,
    && *::before {
      flex: 0 0 auto;
    }
  }

  ${Button} + ${Button} {
    margin-left: 0;
  }
`;

const RSVPButton = (props) => {
  const user = useSelector(getUser);
  const { id, forUsers, hasPrice, routes } = props;

  const [isLoading, setIsLoading] = useState(false);
  const [hasSubscriptionTypeModal, setHasSubscriptionTypeModal] =
    useState(false);

  const openSubscriptionTypeModal = useCallback(() => {
    setHasSubscriptionTypeModal(true);
  }, []);

  const closeSubscriptionTypeModal = useCallback(() => {
    setHasSubscriptionTypeModal(false);
  }, []);

  const handleRSVP = useCallback(
    async (e) => {
      e && e.preventDefault();
      setIsLoading(true);

      if (hasPrice) {
        log.debug("Has price, redirection.");
        window.location.href = routes.rsvp;
        return;
      }

      try {
        const response = await api.rsvpEvent(id);
        if (response.error) {
          log.error(response.error);
          await mutate(api.getEventEndpoint("getEvent", { eventPk: id }));
        }
      } catch (err) {
        window.location.reload();
      }

      setIsLoading(false);
      setHasSubscriptionTypeModal(false);

      await mutate(
        api.getEventEndpoint("getEvent", { eventPk: id }),
        (event) => ({
          ...event,
          rsvped: true,
        })
      );
    },
    [id, hasPrice, routes]
  );

  const shouldUpdateSubscription = useMemo(() => {
    if (!user) {
      return null;
    }
    if (forUsers === "2" && user.is2022) {
      return null;
    }
    if (forUsers === "I" && user.isInsoumise) {
      return null;
    }
    return forUsers === "2" ? "NSP" : "LFI";
  }, [user, forUsers]);

  return (

  );
};

const ActionButtons = (props) => {
  const {
    id,
    name,
    past,
    rsvped,
    logged,
    isOrganizer,
    routes,
    onlineUrl,
    hasPrice,
    allowGuests,
    guests,
  } = props;

  if (past) {
    return (

    );
  }

  if (!logged) {
    return (

    );
  }

  if (rsvped) {
    return (
      <>

        <ActionDetails>

            <RawFeatherIcon name="check" color="green" />  Vous participez
            à l'évènement

          {!hasPrice && <QuitEventButton id={id} name={name} />}
        </ActionDetails>
      </>
    );
  }

  return <RSVPButton {...props} />;
};
RSVPButton.propTypes = ActionButtons.propTypes = {
  id: PropTypes.string,
  name: PropTypes.string,
  onlineUrl: PropTypes.string,
  hasSubscriptionForm: PropTypes.bool,
  hasPrice: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  routes: PropTypes.shape({
    manage: PropTypes.string,
    rsvp: PropTypes.string,
  }),
};

const AdditionalMessage = ({
  isOrganizer,
  logged,
  rsvped,
  price,
  forUsers,
}) => {
  const location = useLocation();

  if (!logged) {
    return (

        <ActionLink
          route="login"
          params={{ from: "event", forUsers, next: location.pathname }}
        >
          Je me connecte
        </ActionLink>{" "}
        ou{" "}
        <ActionLink
          route="signup"
          params={{ from: "event", forUsers, next: location.pathname }}
        >
          je m'inscris
        </ActionLink>{" "}
        pour participer à l'événement

    );
  }

  if (price) {
    return (
      <SmallText>
        Entrée :
        {price}
      </SmallText>
    );
  }

  if (!isOrganizer && !rsvped) {
    return (
      <SmallText>Votre email sera communiqué à l'organisateur·ice</SmallText>
    );
  }

  return <></>;
};
AdditionalMessage.propTypes = {
  id: PropTypes.string,
  name: PropTypes.string,
  hasSubscriptionForm: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  price: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
};

const EventHeader = ({
  id,
  name,
  rsvp,
  options,
  schedule,
  routes,
  isOrganizer,
  forUsers,
  hasRightSubscription,
  onlineUrl,
  allowGuests,
  guests,
}) => {
  const globalRoutes = useSelector(getRoutes);
  const logged = useSelector(getIsConnected);

  const rsvped = rsvp === "CO";
  const now = DateTime.local();
  const past = now > schedule.end;
  let eventString = displayHumanDate(schedule.start);
  eventString = eventString.slice(0, 1).toUpperCase() + eventString.slice(1);

  const pending = now >= schedule.start && now <= schedule.end;
  const eventDate = pending ? displayIntervalEnd(schedule) : eventString;

  return (
    <EventHeaderContainer>
      <EventTitle>{name}</EventTitle>
      <Hide under>
        <EventDate>{eventDate}</EventDate>
      </Hide>
      <ActionButtons
        id={id}
        past={past}
        logged={logged}
        rsvped={rsvped}
        routes={routes}
        isOrganizer={isOrganizer}
        forUsers={forUsers}
        hasRightSubscription={hasRightSubscription}
        hasPrice={!!options && !!options.price}
        onlineUrl={onlineUrl}
        allowGuests={allowGuests}
        guests={guests}
      />
      {!past && (
        <AdditionalMessage
          id={id}
          name={name}
          isOrganizer={isOrganizer}
          past={past}
          logged={logged}
          rsvped={rsvped}
          price={options.price}
          routes={{ ...routes, ...globalRoutes }}
          forUsers={forUsers}
        />
      )}
    </EventHeaderContainer>
  );
};

EventHeader.propTypes = {
  id: PropTypes.string,
  name: PropTypes.string,
  onlineUrl: PropTypes.string,
  startTime: PropTypes.instanceOf(DateTime),
  endTime: PropTypes.instanceOf(DateTime),
  schedule: PropTypes.instanceOf(Interval),
  hasSubscriptionForm: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  options: PropTypes.shape({
    price: PropTypes.string,
  }),
  rsvp: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
  hasRightSubscription: PropTypes.bool,
  allowGuests: PropTypes.bool,
};

export default EventHeader;
<|endoftext|>


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

var jive = require("jive-sdk");
var gitHubFacade = require("github4jive/gitHubFacade");
var JiveContentBuilder = require("github4jive/JiveContentBuilder");
var helpers = require("github4jive/helpers");

var strategyBase = require("github4jive/strategies/EventStrategyBase");
var issueCommentStrategy = Object.create(strategyBase);
module.exports = issueCommentStrategy;

issueCommentStrategy.name = "Place_IssueComments";

/*
 * This strategy modifies anything in a place that is not on a tile in response to a created issue comment.
 * It could be split into separate strategies for fine grain configuration with the builder. Client code
 * should never be calling this function directly. It should be called from the StrategySetBuilderBase.
 * Which is invoked from the StrategySet.setup function returned from builder.build().
 *
 * Override of EventStrategyBase.Setup
 * SetupOptions are provided by a placeController.
 *
 */
issueCommentStrategy.setup = function(setupOptions) {

    var jiveApi = setupOptions.jiveApi;
    var owner = setupOptions.owner;
    var repo = setupOptions.repo;
    var auth = gitHubFacade.createOauthObject( setupOptions.gitHubToken);

    return gitHubFacade.subscribeToRepoEvent(owner, repo, gitHubFacade.Events.IssueComment, auth, function (gitData) {

        var gitComment = gitData.comment.body;

        if(gitComment.indexOf("<!--Jive-->") != 0){
            gitComment = "<!--GitHub-->" + gitComment;
            helpers.getDiscussionForIssue(jiveApi,setupOptions.placeUrl, gitData.issue.id).then(function (discussion) {
                if(discussion){

                    return gitHubFacade.getUserDetails(gitData.comment.user.login, auth).then(function (user) {
                        var builder = new JiveContentBuilder();
                        var comment = builder.message()
                            .body(gitComment)
                            .onBehalfOf(user.email || "", user.login)
                            .build();
                        return jiveApi.replyToDiscussion(discussion.contentID , comment).then(function (response) {
                            if (!response.success) {
                                jive.logger.error("Error creating comment on " + discussion.subject);
                                jive.logger.error(response);
                            }else{
                            jiveApi.attachPropsToReply(response.entity.id,{fromGitHub: true}).then(function (response) {
                                if (!response.success) {
                                    jive.logger.error("Error attaching props to comment");
                                    jive.logger.error(response);
                                }
                            })
                            }
                        })
                    });

                }
            }).catch(function (error) {
                jive.logger.error(error);
            });
        }

    });

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

var jive = require("jive-sdk");
var gitHubFacade = require("github4jive/gitHubFacade");
var JiveContentBuilder = require("github4jive/JiveContentBuilder");
var helpers = require("github4jive/helpers");

var strategyBase = require("github4jive/strategies/EventStrategyBase");
var issueCommentStrategy = Object.create(strategyBase);
module.exports = issueCommentStrategy;

issueCommentStrategy.name = "Place_IssueComments";

function commentDidNotOriginateFromJive(gitComment) {
    return gitComment.indexOf("<!--Jive-->") != 0;
}

function formatGitComment(gitComment) {
    gitComment = "<!--GitHub-->" + gitComment;
}

function addCommentToDiscussion(jiveApi, gitData, gitAuth, discussion){
    if(discussion){
        return gitHubFacade.getUserDetails(gitData.comment.user.login, gitAuth).then(function (user) {
            var builder = new JiveContentBuilder();
            var gitComment = gitData.comment.body;
            formatGitComment(gitComment);
            var comment = builder.message()
                .body(gitComment)
                .onBehalfOf(user.email || "", user.login)
                .build();
            return jiveApi.replyToDiscussion(discussion.contentID , comment).then(function (response) {
                if (!response.success) {
                    jive.logger.error("Error creating comment on " + discussion.subject, response);
                }else{
                    jiveApi.attachPropsToReply(response.entity.id,{fromGitHub: true}).then(function (response) {
                        if (!response.success) {
                            jive.logger.error("Error attaching props to comment", response);
                        }
                    })
                }
            })
        });

    }
}

/*
 * This strategy modifies anything in a place that is not on a tile in response to a created issue comment.
 * It could be split into separate strategies for fine grain configuration with the builder. Client code
 * should never be calling this function directly. It should be called from the StrategySetBuilderBase.
 * Which is invoked from the StrategySet.setup function returned from builder.build().
 *
 * Override of EventStrategyBase.Setup
 * SetupOptions are provided by a placeController.
 *
 */
issueCommentStrategy.setup = function(setupOptions) {

    var jiveApi = setupOptions.jiveApi;
    var owner = setupOptions.owner;
    var repo = setupOptions.repo;
    var auth = gitHubFacade.createOauthObject( setupOptions.gitHubToken);

    return gitHubFacade.subscribeToRepoEvent(owner, repo, gitHubFacade.Events.IssueComment, auth, function (gitData) {
        //GitHub comment event handler
        var gitComment = gitData.comment.body;

        if(commentDidNotOriginateFromJive(gitComment)){

            helpers.getDiscussionForIssue(jiveApi,setupOptions.placeUrl, gitData.issue.id)
                .then(function (discussion) {
                    addCommentToDiscussion(jiveApi, gitData, auth, discussion);
                })
                .catch(function (error) {
                    jive.logger.error(error);
            });
        }
    });
};
<|endoftext|>


<commit_before>$.extend($.noty.defaults, {
		animation: {
			open: {
				animation: 'fade',
				duration: '800ms',
			},
			close: {
				animation: 'fade left',
				duration: '800ms',
			}
		},
		callback:{
			onShow: function(){
				// Enable transition
				this.$bar.addClass('transition');
				// Actual transition
				this.$bar.transition(this.options.animation.open);
			},
			onClose: function(){
				this.$bar.transition(this.options.animation.close);
			}
		}
	});

	$.noty.themes.semanticUI = {
		name: 'semanticUI',
		modal: {
	        css: {
	            position: 'fixed',
	            width: '100%',
	            height: '100%',
	            backgroundColor: '#000',
	            zIndex: 10000,
	            opacity: 0.6,
	            display: 'none',
	            left: 0,
	            top: 0
	        }
	    },
	    style: function(){
			this.$message = this.$bar.find('.ui.message');

	    	this.$message.find('.header').html(this.options.header);
	    	this.$message.find('.content').append(this.options.text);

	    	this.$bar.css({
	    		margin: '0.5em'
	    	});

	    	if(this.options.icon){
	    		this.$message
	    			.addClass('icon')
	    			.prepend($('')
	    				.addClass(this.options.icon));
	    	}

	    	switch(this.options.size){
	    		case 'mini':
	    			this.$message.addClass('mini');
	    			break;
	    		case 'tiny':
	    			this.$message.addClass('tiny');
	    			break;
	    		case 'small':
	    			this.$message.addClass('small');
	    			break;
	    		case 'large':
	    			this.$message.addClass('large');
	    			break;
	    		case 'big':
	    			this.$message.addClass('big');
	    			break;
	    		case 'huge':
	    			this.$message.addClass('huge');
	    			break;
	    		case 'massive':
	    			this.$message.addClass('massive');
	    			break;
	    	}

	    	switch(this.options.type){
	    		case 'info':
	    			this.$message.addClass('info')
	    			break;
	    		case 'warning':
	    			this.$message.addClass('warning');
	    			break;
	    		case 'error':
	    			this.$message.addClass('error');
	    			break;
	    		case 'negative':
	    			this.$message.addClass('netivae');
	    			break;
	    		case 'success':
	    			this.$message.addClass('success');
	    			break;
	    		case 'positive':
	    			this.$message.addClass('positive');
	    		case 'floating':
	    			this.$message.addClass('floating');
	    	}
	    },
	    callback:{
	    	onShow: function(){},
	    	onClose: function(){}
	    }
	}
<commit_msg>Changed default template<commit_after>$.extend($.noty.defaults, {
	animation: {
		open: {
			animation: 'fade',
			duration: '800ms',
		},
		close: {
			animation: 'fade left',
			duration: '800ms',
		}
	},
	template: '

',
	callback:{
		onShow: function(){
			// Enable transition
			this.$bar.addClass('transition');
			// Actual transition
			this.$bar.transition(this.options.animation.open);
		},
		onClose: function(){
			this.$bar.transition(this.options.animation.close);
		}
	}
});

$.noty.themes.semanticUI = {
	name: 'semanticUI',
	modal: {
        css: {
            position: 'fixed',
            width: '100%',
            height: '100%',
            backgroundColor: '#000',
            zIndex: 10000,
            opacity: 0.6,
            display: 'none',
            left: 0,
            top: 0
        }
    },
    style: function(){
		this.$message = this.$bar.find('.ui.message');

    	this.$message.find('.header').html(this.options.header);
    	this.$message.find('.content').append(this.options.text);

    	this.$bar.css({
    		margin: '0.5em'
    	});

    	if(this.options.icon){
    		this.$message
    			.addClass('icon')
    			.prepend($('')
    				.addClass(this.options.icon));
    	}

    	switch(this.options.size){
    		case 'mini':
    			this.$message.addClass('mini');
    			break;
    		case 'tiny':
    			this.$message.addClass('tiny');
    			break;
    		case 'small':
    			this.$message.addClass('small');
    			break;
    		case 'large':
    			this.$message.addClass('large');
    			break;
    		case 'big':
    			this.$message.addClass('big');
    			break;
    		case 'huge':
    			this.$message.addClass('huge');
    			break;
    		case 'massive':
    			this.$message.addClass('massive');
    			break;
    	}

    	switch(this.options.type){
    		case 'info':
    			this.$message.addClass('info')
    			break;
    		case 'warning':
    			this.$message.addClass('warning');
    			break;
    		case 'error':
    			this.$message.addClass('error');
    			break;
    		case 'negative':
    			this.$message.addClass('netivae');
    			break;
    		case 'success':
    			this.$message.addClass('success');
    			break;
    		case 'positive':
    			this.$message.addClass('positive');
    		case 'floating':
    			this.$message.addClass('floating');
    	}
    },
    callback:{
    	onShow: function(){},
    	onClose: function(){}
    }
}
<|endoftext|>


<commit_before>'use strict'

const debug = require('debug')('0x: ticks-to-tree')

module.exports = ticksToTree

function labelInitFrames (frames) {
  const startupBootstrapNodeIndex = frames.findIndex(({name}, ix) => {
    if (frames[ix + 1] && /Module.runMain module\.js/.test(frames[ix + 1].name)) return false
    return /startup bootstrap_node\.js/.test(name)
  })

  if (startupBootstrapNodeIndex !== -1) {
    frames.slice(startupBootstrapNodeIndex + 1).forEach((frame) => {
      if (frame.isInit) return
      frame.name += ' [INIT]'
      frame.isInit = true
    })
  }

  const moduleRunMainIndex = frames.findIndex(({name}, ix) => {
    return /Module.runMain module\.js/.test(name)
  })

  if (moduleRunMainIndex !== -1) {
    frames.slice(moduleRunMainIndex + 1).forEach((frame) => {
      if (frame.isInit) return
      if (/.+ (internal\/)?module\.js/.test(frame.name)) frame.name += '[INIT]'
      frame.isInit = true
    })
  }

  return frames
}

function ticksToTree (ticks, mapFrames, inlined) {
  const merged = {
    name: 'all stacks',
    value: 0,
    top: 0,
    children: []
  }
  const unmerged = {
    name: 'all stacks',
    value: 0,
    top: 0,
    children: []
  }
  const inlineInfo = typeof inlined === 'object'

  ticks.forEach((stack) => {
    // stack = stack.filter(({name}, ix) => name !== stack[ix -1].name)
    if (typeof mapFrames === 'function') stack = mapFrames(stack)
    if (!stack) return
    stack = stack.map(({name, kind, type}, ix) => {
      name = name.replace(/ (:[0-9]+:[0-9]+)/, (_, loc) => ` [eval]${loc}`)
      // 0 no info
      // 1 unoptimized
      // 2 optimized
      // 3 inlinable unoptimized
      // 4 inlinable optimized
      var S = 0

      if (type === 'JS') {
        if (name[0] === ' ') name = '(anonymous)' + name
        if (inlineInfo === true) {
          const [ key ] = name.split(':')
          const info = inlined[key]
          if (info !== undefined) {
            const sameFn = info.length === 1 || info.every(({pos}, ix) => {
              const prev = info[ix - 1]
              if (!prev) return true
              return prev.pos === pos
            })
            if (sameFn === false) {
              // todo: resolve this edge case as follows:
              // collect stack frames with same key (fn + file) but different line:col
              // if the amount of stacks frames with same key matches size of `info`
              // then they can all be marked as inlinable
              // if not then,
              // sort functions in inlined by position
              // collect stack frames with same key (fn + file) but sort
              // them by line:col (const [ key, line, col ] = name.split(':'))
              // -- any stack frames that exceed length of info are *not* inlinable
              // the rest are
              debug(`multiple functions name collision in file skipping ${key}`)
            } else {
              const [ lookup ] = stack[ix - 1] ? (stack[ix - 1].name.split(':')) : []
              const callerMatch = inlined[key].find(({caller}) => caller.key === lookup)
              if (callerMatch) S += 2
            }
          }
        }
        if (kind === 'Unopt') S += 1
        if (kind === 'Opt') S += 2
      }

      if (type && type !== 'JS') name += ' [' + type + (kind ? ':' + kind : '') + ']'
      return {S, name, value: 0, top: 0}
    })

    stack = labelInitFrames(stack)

    addToMergedTree(stack.map(({S, name, value, top}) => ({S, name, value, top})))
    // mutate original (save another loop over stack + extra objects)
    addToUnmergedTree(stack)
  })

  function addToMergedTree (stack) {
    var lastFrame = null
    stack.forEach((frame, ix) => {
      // TODO need an elegant way to place inlined frames into *other* stacks
      // where the function has disappeared – for now we just remove inlined
      // stacks from merged graphs
      if (frame.S > 2) return // skip inlined
      if (ix > 0) lastFrame.children = lastFrame.children || []
      const children = (ix === 0) ? merged.children : lastFrame.children
      const child = children.find(({name}) => name === frame.name)

      if (child === undefined) children.push(frame)
      else frame = child

      if (ix === stack.length - 1) frame.top++
      if (ix === 0) merged.value += 1
      frame.value++

      lastFrame = frame
    })
  }

  function addToUnmergedTree (stack) {
    var lastFrame = null
    stack.forEach((frame, ix) => {
      // TODO need an elegant way to place inlined frames into *other* stacks
      // where the function has disappeared – for now we just remove inlined
      // stacks from merged graphs
      // adding children here means we avoid unnecessary arrays
      if (ix > 0) lastFrame.children = lastFrame.children || []
      const children = (ix === 0) ? unmerged.children : lastFrame.children
      const child = children.find(({fn, S}) => {
        return fn === frame.name && S === frame.S
      })

      if (child === undefined) {
        frame.fn = frame.name
        if (frame.S === 1) frame.name = '~' + frame.name
        if (frame.S === 2) frame.name = '*' + frame.name
        if (frame.S === 3) frame.name = '~' + frame.name + ' [INLINABLE]'
        if (frame.S === 4) frame.name = '*' + frame.name + ' [INLINABLE]'
        children.push(frame)
      } else frame = child

      if (ix === stack.length - 1) frame.top++
      if (ix === 0) unmerged.value += 1
      frame.value++

      lastFrame = frame
    })
  }

  return { merged, unmerged }
}
<commit_msg>remove instrumentation stacks<commit_after>'use strict'

const debug = require('debug')('0x: ticks-to-tree')
const { join } = require('path')
module.exports = ticksToTree

function ticksToTree (ticks, mapFrames, inlined) {
  const merged = {
    name: 'all stacks',
    value: 0,
    top: 0,
    children: []
  }
  const unmerged = {
    name: 'all stacks',
    value: 0,
    top: 0,
    children: []
  }
  const inlineInfo = typeof inlined === 'object'

  ticks.forEach((stack) => {
    stack = removeInstrumentationFrames(stack)
    if (typeof mapFrames === 'function') stack = mapFrames(stack)
    if (!stack) return
    stack = stack.map(({name, kind, type}, ix) => {
      name = name.replace(/ (:[0-9]+:[0-9]+)/, (_, loc) => ` [eval]${loc}`)
      // 0 no info
      // 1 unoptimized
      // 2 optimized
      // 3 inlinable unoptimized
      // 4 inlinable optimized
      var S = 0

      if (type === 'JS') {
        if (name[0] === ' ') name = '(anonymous)' + name
        if (inlineInfo === true) {
          const [ key ] = name.split(':')
          const info = inlined[key]
          if (info !== undefined) {
            const sameFn = info.length === 1 || info.every(({pos}, ix) => {
              const prev = info[ix - 1]
              if (!prev) return true
              return prev.pos === pos
            })
            if (sameFn === false) {
              // todo: resolve this edge case as follows:
              // collect stack frames with same key (fn + file) but different line:col
              // if the amount of stacks frames with same key matches size of `info`
              // then they can all be marked as inlinable
              // if not then,
              // sort functions in inlined by position
              // collect stack frames with same key (fn + file) but sort
              // them by line:col (const [ key, line, col ] = name.split(':'))
              // -- any stack frames that exceed length of info are *not* inlinable
              // the rest are
              debug(`multiple functions name collision in file skipping ${key}`)
            } else {
              const [ lookup ] = stack[ix - 1] ? (stack[ix - 1].name.split(':')) : []
              const callerMatch = inlined[key].find(({caller}) => caller.key === lookup)
              if (callerMatch) S += 2
            }
          }
        }
        if (kind === 'Unopt') S += 1
        if (kind === 'Opt') S += 2
      }

      if (type && type !== 'JS') name += ' [' + type + (kind ? ':' + kind : '') + ']'
      return {S, name, value: 0, top: 0}
    })

    stack = labelInitFrames(stack)

    addToMergedTree(stack.map(({S, name, value, top}) => ({S, name, value, top})))
    // mutate original (save another loop over stack + extra objects)
    addToUnmergedTree(stack)
  })

  function addToMergedTree (stack) {
    var lastFrame = null
    stack.forEach((frame, ix) => {
      // TODO need an elegant way to place inlined frames into *other* stacks
      // where the function has disappeared – for now we just remove inlined
      // stacks from merged graphs
      if (frame.S > 2) return // skip inlined
      if (ix > 0) lastFrame.children = lastFrame.children || []
      const children = (ix === 0) ? merged.children : lastFrame.children
      const child = children.find(({name}) => name === frame.name)

      if (child === undefined) children.push(frame)
      else frame = child

      if (ix === stack.length - 1) frame.top++
      if (ix === 0) merged.value += 1
      frame.value++

      lastFrame = frame
    })
  }

  function addToUnmergedTree (stack) {
    var lastFrame = null
    stack.forEach((frame, ix) => {
      // TODO need an elegant way to place inlined frames into *other* stacks
      // where the function has disappeared – for now we just remove inlined
      // stacks from merged graphs
      // adding children here means we avoid unnecessary arrays
      if (ix > 0) lastFrame.children = lastFrame.children || []
      const children = (ix === 0) ? unmerged.children : lastFrame.children
      const child = children.find(({fn, S}) => {
        return fn === frame.name && S === frame.S
      })

      if (child === undefined) {
        frame.fn = frame.name
        if (frame.S === 1) frame.name = '~' + frame.name
        if (frame.S === 2) frame.name = '*' + frame.name
        if (frame.S === 3) frame.name = '~' + frame.name + ' [INLINABLE]'
        if (frame.S === 4) frame.name = '*' + frame.name + ' [INLINABLE]'
        children.push(frame)
      } else frame = child

      if (ix === stack.length - 1) frame.top++
      if (ix === 0) unmerged.value += 1
      frame.value++

      lastFrame = frame
    })
  }

  return { merged, unmerged }
}

function labelInitFrames (frames) {
  const startupBootstrapNodeIndex = frames.findIndex(({name}, ix) => {
    if (frames[ix + 1] && /Module.runMain module\.js/.test(frames[ix + 1].name)) return false
    return /startup bootstrap_node\.js/.test(name)
  })

  if (startupBootstrapNodeIndex !== -1) {
    frames.slice(startupBootstrapNodeIndex + 1).forEach((frame) => {
      if (frame.isInit) return
      frame.name += ' [INIT]'
      frame.isInit = true
    })
  }

  const moduleRunMainIndex = frames.findIndex(({name}, ix) => {
    return /Module.runMain module\.js/.test(name)
  })

  if (moduleRunMainIndex !== -1) {
    frames.slice(moduleRunMainIndex + 1).forEach((frame) => {
      if (frame.isInit) return
      if (/.+ (internal\/)?module\.js/.test(frame.name)) frame.name += '[INIT]'
      frame.isInit = true
    })
  }

  return frames
}

function removeInstrumentationFrames (frames) {
  const preloadDirRx = RegExp(join(__dirname, 'preload'))
  return frames.filter((frame) => preloadDirRx.test(frame.name) === false)
}<|endoftext|>


<commit_before><commit_msg>Update Food2Fork API info<commit_after><|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var Q = require('q');
var debounce = require('debounce');
var utils = require('./utils');
var child_process = require('child_process');

// Returns a promise.
module.exports = exports = function push(target, watch) {
  var argsAsJson = JSON.stringify([].slice.call(arguments));
  return checkFileHandleLimit()
  .then(function(fileHandleLimit) {
    if (fileHandleLimit < 10000 && watch) {
      return relaunchWithBiggerUlimit(argsAsJson)
      .then(function() {
        return true;
      }, function() {
        // Setting ulimit can fail, so just continue on if it does.
      });
    }
  }).then(function(done) {
    if (done) {
      return;
    }
    target = !target || Array.isArray(target) ? target : [target];
    var ret = Q.when(target);
    if (!target) {
      ret = extractTargets();
    }
    return ret.then(function(targets) {
      return createSession(targets);
    }).then(function(session) {
      // Push the app and force a launch, even if it hasn't changed from a previous launch, since the app is being pushed for the first time.
      return pushAll(session.clientInfos, /* forceLaunch */ true)
      .then(function() {
        if (watch) {
          return watchFiles(session);
        }
      });
    });
  });
};

function extractTargets() {
  // TODO: Use adbkit for smarter auto-detection.
  var PushClient = require('chrome-app-developer-tool-client');
  return PushClient.detectAdbTargets()
  .then(function(targets) {
      if (!targets.length) {
          console.warn('No connected android devices detected. Defaulting to localhost.');
          targets = ['localhost:2424'];
      }
      return targets;
  }, function() {
      console.warn('Could not use adb to detect connected devices');
      return ['localhost:2424'];
  });
}

function createSession(targets) {
  var PushClient = require('chrome-app-developer-tool-client');

  var i = 0;
  var ret = {
    platforms: [],
    clientInfos: [],
    appType: null
  };

  var chromeAppPushRoot = null;
  if (fs.existsSync('www/manifest.json')) {
    chromeAppPushRoot = 'www';
  } else if (fs.existsSync('manifest.json')) {
    chromeAppPushRoot = '.';
  }
  ret.appType = chromeAppPushRoot ? 'chrome' : 'cordova';

  var platformMap = Object.create(null);
  function createClient() {
    var target = targets[i++];
    if (!target) {
      ret.platforms = Object.keys(platformMap);
      return ret;
    }
    var newClient = new PushClient(target);
    return newClient.info()
    .then(function(response) {
      var infoJson = response.body;
      var platform = infoJson['platform'];
      platformMap[platform] = true;
      if (ret.appType == 'chrome') {
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession(chromeAppPushRoot),
            watchDir: chromeAppPushRoot
        });
      } else {
        // Vanilla Cordova project.
        var wwwDir = utils.assetDirForPlatform(platform);
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession('.'), // push client figures out to use platforms/
            watchDir: wwwDir
        });
      }
      return createClient();
    }, function(error) {
      if (error.code === 'ECONNREFUSED') {
        console.warn();
        console.warn('Could not connect to device at ' + target);
        console.warn('For a USB connected Android device, try running: adb forward tcp:2424 tcp:2424');
        console.warn('For a networked device, use --target=DEVICE_IP_ADDRESS');
      } else if (error.code === 'ECONNRESET') {
        console.warn('\nPlease make sure that the Chrome App Developer Tool for Mobile is running on your device.');
      } else {
        console.error(error);
      }
      process.exit();
    });
  }
  return createClient();
}

var pushInProgress = false;
var pushAgainWhenDone = false;
// gaze uses fs.watchFile, which is classified as "unstable" (http://goo.gl/H16j5l).
// It sometimes causes multiple change events to be fired, and they're far enough apart that debouncing is ineffective.
// To deal with this, CADT-client's push functionality doesn't relaunch an app with no changes unless `forceLaunch` is true.
// Calls to `pushAll` can specify whether to force a launch.
function pushAll(clientInfos, forceLaunch) {
  if (pushInProgress) {
    pushAgainWhenDone = true;
    return Q();
  }
  pushInProgress = true;
  var allPromises = clientInfos.map(function(clientInfo) {
    try {
      return clientInfo.pushSession.push(forceLaunch);
    } catch (e) {
      if (/Not a Cordova project/.test(e)) {
        console.warn('Please navigate to a Chrome App or Cordova project, and then try pushing again.');
      } else {
        console.error(e);
      }
      process.exit();
    }
  });
  return Q.all(allPromises)
  .then(function() {
    if (pushAgainWhenDone) {
      process.nextTick(function() {
        // Push, but don't force a launch if the app hasn't changed.
        pushAll(clientInfos, /* forceLaunch */ false).done();
      });
    }
    pushInProgress = false;
    pushAgainWhenDone = false;
  }, function(e) {
    pushInProgress = false;
    pushAgainWhenDone = false;
    throw e;
  });
}

var debouncedPushAll = debounce(function(clientInfos) {
  // Push, but don't force a launch if the app hasn't changed.
  pushAll(clientInfos, /* forceLaunch */ false).done();
}, 50, false);

function watchFiles(session) {
  var gaze = require('gaze');
  var deferred = Q.defer();

  // TODO: This doesn't work for vanilla cordova apps + multiple platforms.
  var watchDir = session.clientInfos[0].watchDir;
  // Note: gaze doesn't work well with ./ prefix nor with absolute paths
  // (https://github.com/gruntjs/grunt-contrib-watch/issues/166)
  // path.join() is smart enough to remove the ./ prefix.
  gaze(path.join(watchDir, '**', '*'), function(err, watcher) {
    console.log('Watching for changes.');
    watcher.on('all', function(event, filepath) {
      debouncedPushAll(session.clientInfos);
    });
  });
  // TODO: Capture Ctrl-C and resolve the promise.
  return deferred.promise;
}

function checkFileHandleLimit() {
  var deferred = Q.defer();
  if (process.platform != 'win32' && process.env['SHELL']) {
    // gaze opens a lot of file handles, and the default on OS X is too small (EMFILE exceptions).
    // NOTE: This is fixed in node 0.11, and is a problem only on node 0.10.
    child_process.exec('ulimit -n', function(error, stdout, stderr) {
      var curLimit = !error && +stdout;
      deferred.resolve(curLimit || Infinity);
    });
  } else {
    deferred.resolve(Infinity);
  }
  return deferred.promise;
}

function relaunchWithBiggerUlimit(argsAsJson) {
  // re-run with the new ulimit
  var deferred = Q.defer();
  var args = ['-c', 'ulimit -n 10240 && exec "' + process.argv[0] + '" "' + __filename + '" "' + argsAsJson.replace(/"/g, '@') + '"'];
  var child = child_process.spawn(process.env['SHELL'], args, { stdio: 'inherit' });
  child.on('close', function(code) {
    if (code) {
      deferred.reject(code);
    } else {
      deferred.resolve(code);
    }
  });
  return deferred.promise;
}

// Gets called from EMFILE re-launch
if (require.main === module) {
  exports.apply(this, JSON.parse(process.argv[2].replace(/@/g, '"'))).done();
}
<commit_msg>Update to work when default shell is not bash<commit_after>var fs = require('fs');
var path = require('path');
var Q = require('q');
var debounce = require('debounce');
var utils = require('./utils');
var child_process = require('child_process');

// Returns a promise.
module.exports = exports = function push(target, watch) {
  var argsAsJson = JSON.stringify([].slice.call(arguments));
  return checkFileHandleLimit()
  .then(function(fileHandleLimit) {
    if (fileHandleLimit < 10000 && watch) {
      return relaunchWithBiggerUlimit(argsAsJson)
      .then(function() {
        return true;
      }, function() {
        // Setting ulimit can fail, so just continue on if it does.
      });
    }
  }).then(function(done) {
    if (done) {
      return;
    }
    target = !target || Array.isArray(target) ? target : [target];
    var ret = Q.when(target);
    if (!target) {
      ret = extractTargets();
    }
    return ret.then(function(targets) {
      return createSession(targets);
    }).then(function(session) {
      // Push the app and force a launch, even if it hasn't changed from a previous launch, since the app is being pushed for the first time.
      return pushAll(session.clientInfos, /* forceLaunch */ true)
      .then(function() {
        if (watch) {
          return watchFiles(session);
        }
      });
    });
  });
};

function extractTargets() {
  // TODO: Use adbkit for smarter auto-detection.
  var PushClient = require('chrome-app-developer-tool-client');
  return PushClient.detectAdbTargets()
  .then(function(targets) {
      if (!targets.length) {
          console.warn('No connected android devices detected. Defaulting to localhost.');
          targets = ['localhost:2424'];
      }
      return targets;
  }, function() {
      console.warn('Could not use adb to detect connected devices');
      return ['localhost:2424'];
  });
}

function createSession(targets) {
  var PushClient = require('chrome-app-developer-tool-client');

  var i = 0;
  var ret = {
    platforms: [],
    clientInfos: [],
    appType: null
  };

  var chromeAppPushRoot = null;
  if (fs.existsSync('www/manifest.json')) {
    chromeAppPushRoot = 'www';
  } else if (fs.existsSync('manifest.json')) {
    chromeAppPushRoot = '.';
  }
  ret.appType = chromeAppPushRoot ? 'chrome' : 'cordova';

  var platformMap = Object.create(null);
  function createClient() {
    var target = targets[i++];
    if (!target) {
      ret.platforms = Object.keys(platformMap);
      return ret;
    }
    var newClient = new PushClient(target);
    return newClient.info()
    .then(function(response) {
      var infoJson = response.body;
      var platform = infoJson['platform'];
      platformMap[platform] = true;
      if (ret.appType == 'chrome') {
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession(chromeAppPushRoot),
            watchDir: chromeAppPushRoot
        });
      } else {
        // Vanilla Cordova project.
        var wwwDir = utils.assetDirForPlatform(platform);
        ret.clientInfos.push({
            platform: platform,
            client: newClient,
            pushSession: newClient.createPushSession('.'), // push client figures out to use platforms/
            watchDir: wwwDir
        });
      }
      return createClient();
    }, function(error) {
      if (error.code === 'ECONNREFUSED') {
        console.warn();
        console.warn('Could not connect to device at ' + target);
        console.warn('For a USB connected Android device, try running: adb forward tcp:2424 tcp:2424');
        console.warn('For a networked device, use --target=DEVICE_IP_ADDRESS');
      } else if (error.code === 'ECONNRESET') {
        console.warn('\nPlease make sure that the Chrome App Developer Tool for Mobile is running on your device.');
      } else {
        console.error(error);
      }
      process.exit();
    });
  }
  return createClient();
}

var pushInProgress = false;
var pushAgainWhenDone = false;
// gaze uses fs.watchFile, which is classified as "unstable" (http://goo.gl/H16j5l).
// It sometimes causes multiple change events to be fired, and they're far enough apart that debouncing is ineffective.
// To deal with this, CADT-client's push functionality doesn't relaunch an app with no changes unless `forceLaunch` is true.
// Calls to `pushAll` can specify whether to force a launch.
function pushAll(clientInfos, forceLaunch) {
  if (pushInProgress) {
    pushAgainWhenDone = true;
    return Q();
  }
  pushInProgress = true;
  var allPromises = clientInfos.map(function(clientInfo) {
    try {
      return clientInfo.pushSession.push(forceLaunch);
    } catch (e) {
      if (/Not a Cordova project/.test(e)) {
        console.warn('Please navigate to a Chrome App or Cordova project, and then try pushing again.');
      } else {
        console.error(e);
      }
      process.exit();
    }
  });
  return Q.all(allPromises)
  .then(function() {
    if (pushAgainWhenDone) {
      process.nextTick(function() {
        // Push, but don't force a launch if the app hasn't changed.
        pushAll(clientInfos, /* forceLaunch */ false).done();
      });
    }
    pushInProgress = false;
    pushAgainWhenDone = false;
  }, function(e) {
    pushInProgress = false;
    pushAgainWhenDone = false;
    throw e;
  });
}

var debouncedPushAll = debounce(function(clientInfos) {
  // Push, but don't force a launch if the app hasn't changed.
  pushAll(clientInfos, /* forceLaunch */ false).done();
}, 50, false);

function watchFiles(session) {
  var gaze = require('gaze');
  var deferred = Q.defer();

  // TODO: This doesn't work for vanilla cordova apps + multiple platforms.
  var watchDir = session.clientInfos[0].watchDir;
  // Note: gaze doesn't work well with ./ prefix nor with absolute paths
  // (https://github.com/gruntjs/grunt-contrib-watch/issues/166)
  // path.join() is smart enough to remove the ./ prefix.
  gaze(path.join(watchDir, '**', '*'), function(err, watcher) {
    console.log('Watching for changes.');
    watcher.on('all', function(event, filepath) {
      debouncedPushAll(session.clientInfos);
    });
  });
  // TODO: Capture Ctrl-C and resolve the promise.
  return deferred.promise;
}

function checkFileHandleLimit() {
  var deferred = Q.defer();
  if (process.platform != 'win32' && process.env['SHELL']) {
    // gaze opens a lot of file handles, and the default on OS X is too small (EMFILE exceptions).
    // NOTE: This is fixed in node 0.11, and is a problem only on node 0.10.
    child_process.exec('ulimit -n', function(error, stdout, stderr) {
      var curLimit = !error && +stdout;
      deferred.resolve(curLimit || Infinity);
    });
  } else {
    deferred.resolve(Infinity);
  }
  return deferred.promise;
}

function relaunchWithBiggerUlimit(argsAsJson) {
  // re-run with the new ulimit
  var deferred = Q.defer();
  var args = ['-c', 'ulimit -n 10240 && exec "' + process.argv[0] + '" "' + __filename + '" "' + argsAsJson.replace(/"/g, '@') + '"'];
  var child = child_process.spawn('sh', args, { stdio: 'inherit' });
  child.on('close', function(code) {
    if (code) {
      deferred.reject(code);
    } else {
      deferred.resolve(code);
    }
  });
  return deferred.promise;
}

// Gets called from EMFILE re-launch
if (require.main === module) {
  exports.apply(this, JSON.parse(process.argv[2].replace(/@/g, '"'))).done();
}
<|endoftext|>


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

$(document).ready(function() {

// !!! Commenting out RSA Key field UI temporarily !!!
//
//  // rsa key field interaction
//  $("#addKeyBtn").unbind("click");
//  $("#addKeyBtn").click(function() {
//    $("#rsaKeyField").toggle(250);
//    $("#rsaKeyField").find(':input').val('');
//      $("#rsa_validation_error_text").text('');
//    $("#key_arrow").toggleClass("icon-chevron-left icon-chevron-down");
//  });
//
//  // tool tips
//  $("#key_tooltip").qtip({
//      content: 'You can provide a public key that will be used to securely SFTP to your landing zone. Public keys must be encrypted using RFC 4716 format. More Information',
//      position: {
//	  corner: {
//	      tooltip: 'bottomMiddle',
//	      target: 'topMiddle'
//	  }
//      },
//      hide: {
//	  fixed: true,
//	  when: {
//	      event: 'unfocus'
//	  }
//      },
//      style: {
//	  border: {
//              width: 1,
//              radius: 5
//          },
//	  padding: 5,
//	  tip: true
//      }
//  });
//
//  // put out spinner for provision button
//  $("#provisionButton").click(function() {
//      $("#spinner").show();
//  });
// !!! END Commenting out RSA Key field UI temporarily !!!

  if (is_sandbox) {
    var buttonEnableForCustom = function() {
      if($("#custom_ed_org").val().length == 0) {
        $("#provisionButton").attr("disabled","disabled")
      }
      else {
        $("#provisionButton").removeAttr("disabled")
      }
    }
    $("input[type=radio][id!=custom]").click(function() {
	$("#custom_ed_org").attr("disabled","disabled");
	$("#provisionButton").removeAttr("disabled");
	$("#sample_data_select").removeAttr("disabled")
    });
    $("#custom").click(function() {
      $("#custom_ed_org").removeAttr("disabled");
      $("#sample_data_select").attr("disabled","disabled");
      buttonEnableForCustom()
    });
    $("#custom_ed_org").bind('input propertychange', buttonEnableForCustom);
    if($("#custom").attr("type") == "radio"){
      $("#custom_ed_org").attr("disabled","disabled")
    }
    $("#provisionButton").attr("disabled", "disabled")
  }

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

$(document).ready(function() {

// !!! Commenting out RSA Key field UI temporarily !!!
//
//  // rsa key field interaction
//  $("#addKeyBtn").unbind("click");
//  $("#addKeyBtn").click(function() {
//    $("#rsaKeyField").toggle(250);
//    $("#rsaKeyField").find(':input').val('');
//      $("#rsa_validation_error_text").text('');
//    $("#key_arrow").toggleClass("icon-chevron-left icon-chevron-down");
//  });
//
//  // tool tips
//  $("#key_tooltip").qtip({
//      content: 'You can provide a public key that will be used to securely SFTP to your landing zone. Public keys must be encrypted using RFC 4716 format. More Information',
//      position: {
//	  corner: {
//	      tooltip: 'bottomMiddle',
//	      target: 'topMiddle'
//	  }
//      },
//      hide: {
//	  fixed: true,
//	  when: {
//	      event: 'unfocus'
//	  }
//      },
//      style: {
//	  border: {
//              width: 1,
//              radius: 5
//          },
//	  padding: 5,
//	  tip: true
//      }
//  });
//
//  // put out spinner for provision button
//  $("#provisionButton").click(function() {
//      $("#spinner").show();
//  });
// !!! END Commenting out RSA Key field UI temporarily !!!

  if (is_sandbox) {
    var buttonEnableForCustom = function() {
      if($("#custom_ed_org").val().length == 0) {
        $("#provisionButton").attr("disabled","disabled")
      }
      else {
        $("#provisionButton").removeAttr("disabled")
      }
    }
    $("input[type=radio][id!=custom]").click(function() {
	$("#custom_ed_org").attr("disabled","disabled");
	$("#provisionButton").removeAttr("disabled");
	$("#sample_data_select").removeAttr("disabled")
    });
    $("#custom").click(function() {
      $("#custom_ed_org").removeAttr("disabled");
      $("#sample_data_select").attr("disabled","disabled");
      buttonEnableForCustom()
    });
    $("#custom_ed_org").bind('input propertychange', buttonEnableForCustom);
    if($("#custom").attr("type") == "radio"){
      $("#custom_ed_org").attr("disabled","disabled")
    }
    $("#provisionButton").attr("disabled", "disabled");
    $("#sample_data_select").attr("disabled","disabled")
  }

})
<|endoftext|>


<commit_before>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

function Vector2(x,y){
    if(x instanceof Vector2){
        this.x = x.x;
        this.y = x.y;
    }else{
        this.x = typeof x !== 'undefined' ? x : 0.0;
        this.y = typeof y !== 'undefined' ? y : 0.0;
    }

    this.dX = function(s){
      this.x += s;
    };
    this.dY = function(s){
        this.y += s;
    };

    this.clone = function(){
        var clo = new Vector2(this.x,this.y);
        return clo;
    };

    this.length = function(){
        return this.lengthMaker(this.x, this.y);
    };

    this.distance = function(x){
        return this.lengthMaker(this.x - x.x, this.y - x.y);
    }

    this.lengthMaker = function(x,y){
        return Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
    };

}

function Circle(c, radius){
    //Copy Constructor
    if(c instanceof Circle){
        this.center = c.center;
        this.radius = c.radius;
    }else{//Everything else constructor
        this.center = typeof center !== 'undefined'? center : new Vector2();
        this.radius = typeof radius !== 'undefined' ? radius : 0;
    }

}

function KeyBoard(){

}

function webGLStart(){
    //var canvas = document.getElementById("mahCanvas");

    var myVector = new Vector2(2,2);
    var newVector = new Vector2(myVector);

    console.log(myVector);
    console.log(newVector);

    myVector.dX(2);
    console.log(newVector);
    console.log(typeof myVector);
}

<commit_msg>Rudamentary Vector2 implemented. Moving on to Circle.<commit_after>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

function Vector2(x,y){
    if(x instanceof Vector2){
        this.x = x.x;
        this.y = x.y;
    }else{
        this.x = typeof x !== 'undefined' ? x : 0.0;
        this.y = typeof y !== 'undefined' ? y : 0.0;
    }

    this.dX = function(s){
      this.x += s;
    };
    this.dY = function(s){
        this.y += s;
    };

    this.clone = function(){
        var clo = new Vector2(this.x,this.y);
        return clo;
    };

    this.length = function(){
        return this.lengthMaker(this.x, this.y);
    };

    this.distance = function(x){
        return this.lengthMaker(this.x - x.x, this.y - x.y);
    };

    this.add = function(x){
        this.x += x.x;
        this.y += x.y;
    };
    this.subtract = function(x){
        this.x -= x.x;
        this.y -= x.y;
    };

    this.equals = function(x){
        return this.x === x.x && this.y === x.y;
    };

    this.lengthMaker = function(x,y){
        return Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
    };

}

function Circle(c, radius){
    //Copy Constructor
    if(c instanceof Circle){
        this.center = c.center;
        this.radius = c.radius;
    }else{//Everything else constructor
        this.center = typeof center !== 'undefined'? center : new Vector2();
        this.radius = typeof radius !== 'undefined' ? radius : 0;
    }

}

function KeyBoard(){

}

function webGLStart(){
    //var canvas = document.getElementById("mahCanvas");

    var myVector = new Vector2(2,2);
    var newVector = new Vector2(myVector);

    console.log(myVector.equals(newVector));

    myVector.dX(2);
    console.log(newVector);
    console.log(typeof myVector);
}

<|endoftext|>


<commit_before>import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { Interval, DateTime } from "luxon";

import { useSelector } from "@agir/front/globalContext/GlobalContext";
import { getRoutes, getIsConnected } from "@agir/front/globalContext/reducers";

import Button from "@agir/front/genericComponents/Button";
import style from "@agir/front/genericComponents/_variables.scss";
import { Hide } from "@agir/front/genericComponents/grid";
import CSRFProtectedForm from "@agir/front/genericComponents/CSRFProtectedForm";
import { displayHumanDate } from "@agir/lib/utils/time";

const EventHeaderContainer = styled.div`
  @media (min-width: ${style.collapse}px) {
    margin-bottom: 4rem;
  }
  > * {
    margin: 0.5rem 0;
  }
`;

const EventTitle = styled.h1`
  font-size: 1.75rem;
  line-height: 1.4;
  font-weight: 700;
  margin-bottom: 0;

  @media (max-width: ${style.collapse}px) {
    margin-bottom: 1rem;
    font-size: 1.25rem;
  }
`;

const EventDate = styled.div`
  margin: 0.5rem 0;
  font-weight: 500;
`;

const SmallText = styled.div`
  font-size: 0.81rem;
  font-color: ${style.black500};
`;

/* Bouton qui prend 100 % de la largeur en petits écrans */
const ActionButton = styled(Button)`
  margin: 0.5rem 0;
  display: block;
  width: 100%;

  @media only screen and (min-width: 501px) {
    display: inline-block;
    width: auto;

    & + & {
      margin-left: 0.5rem;
    }
  }
`;

const ActionLink = styled.a`
  font-weight: 700;
  text-decoration: underline;
`;

const ActionButtons = (props) => {
  const {
    hasSubscriptionForm,
    past,
    rsvped,
    logged,
    isOrganizer,
    routes,
  } = props;

  if (past) {
    return (
      <>
        <Button disabled color="unavailable">
          Événement terminé
        </Button>
        {isOrganizer && (
          <ActionButton icon="settings" as="a" href={routes.manage}>
            Gérer l'événement
          </ActionButton>
        )}
      </>
    );
  }

  if (!logged) {
    return (
      <ActionButton color="secondary" disabled={true}>
        Participer à l'événement
      </ActionButton>
    );
  }

  if (rsvped) {
    return (
      <>
        <ActionButton icon="check" color="confirmed">
          Je participe
        </ActionButton>
        {isOrganizer && (
          <ActionButton icon="settings" as="a" href={routes.manage}>
            Gérer l'événement
          </ActionButton>
        )}
      </>
    );
  }

  if (hasSubscriptionForm) {
    return (
      <ActionButton as="a" color="secondary" href={`${routes.rsvp}`}>
        Participer à l'événement
      </ActionButton>
    );
  }

  return (
    <CSRFProtectedForm method="post" action={routes.rsvp}>
      <ActionButton type="submit" color="secondary">
        Participer à l'événement
      </ActionButton>
    </CSRFProtectedForm>
  );
};
ActionButtons.propTypes = {
  hasSubscriptionForm: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  routes: PropTypes.shape({
    manage: PropTypes.string,
    rsvp: PropTypes.string,
  }),
};

const AdditionalMessage = ({ logged, rsvped, price, routes, forUsers }) => {
  if (!logged) {
    return (

        <ActionLink href={routes.login}>Je me connecte</ActionLink> ou{" "}
        <ActionLink href={`${routes.join}?type=${forUsers}`}>
          je m'inscris
        </ActionLink>{" "}
        pour participer à l'événement

    );
  }

  if (rsvped) {
    return (
      <SmallText>
        Annuler ma participation
      </SmallText>
    );
  }

  if (price) {
    return (
      <SmallText>
        Entrée :
        {price}
      </SmallText>
    );
  }

  return (
    <SmallText>Votre email sera communiquée à l'organisateur.rice</SmallText>
  );
};
AdditionalMessage.propTypes = {
  hasSubscriptionForm: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  price: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
};

const EventHeader = ({
  name,
  rsvp,
  options,
  schedule,
  routes,
  isOrganizer,
  hasSubscriptionForm,
  forUsers,
}) => {
  const globalRoutes = useSelector(getRoutes);
  const logged = useSelector(getIsConnected);

  const rsvped = rsvp === "CO";
  const now = DateTime.local();
  const past = now > schedule.end;
  let eventString = displayHumanDate(schedule.start);
  eventString = eventString.slice(0, 1).toUpperCase() + eventString.slice(1);

  return (
    <EventHeaderContainer>
      <EventTitle>{name}</EventTitle>
      <Hide under>
        <EventDate>{eventString}</EventDate>
      </Hide>
      <ActionButtons
        hasSubscriptionForm={hasSubscriptionForm}
        past={past}
        logged={logged}
        rsvped={rsvped}
        routes={routes}
        isOrganizer={isOrganizer}
        forUsers={forUsers}
      />
      {!past && (
        <AdditionalMessage
          past={past}
          logged={logged}
          rsvped={rsvped}
          price={options.price}
          routes={{ ...routes, ...globalRoutes }}
          forUsers={forUsers}
        />
      )}
    </EventHeaderContainer>
  );
};

EventHeader.propTypes = {
  name: PropTypes.string,
  schedule: PropTypes.instanceOf(Interval),
  hasSubscriptionForm: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  options: PropTypes.shape({
    price: PropTypes.string,
  }),
  rsvp: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
  canRSVP: PropTypes.bool,
};

export default EventHeader;
<commit_msg>fix: EventHeader button alignment<commit_after>import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { Interval, DateTime } from "luxon";

import { useSelector } from "@agir/front/globalContext/GlobalContext";
import { getRoutes, getIsConnected } from "@agir/front/globalContext/reducers";

import Button from "@agir/front/genericComponents/Button";
import style from "@agir/front/genericComponents/_variables.scss";
import { Hide } from "@agir/front/genericComponents/grid";
import CSRFProtectedForm from "@agir/front/genericComponents/CSRFProtectedForm";
import { displayHumanDate } from "@agir/lib/utils/time";

const EventHeaderContainer = styled.div`
  @media (min-width: ${style.collapse}px) {
    margin-bottom: 4rem;
  }
  > * {
    margin: 0.5rem 0;
  }
`;

const EventTitle = styled.h1`
  font-size: 1.75rem;
  line-height: 1.4;
  font-weight: 700;
  margin-bottom: 0;

  @media (max-width: ${style.collapse}px) {
    margin-bottom: 1rem;
    font-size: 1.25rem;
  }
`;

const EventDate = styled.div`
  margin: 0.5rem 0;
  font-weight: 500;
`;

const SmallText = styled.div`
  font-size: 0.81rem;
  font-color: ${style.black500};
`;

const ActionButton = styled(Button)``;
const ActionLink = styled.a`
  font-weight: 700;
  text-decoration: underline;
`;

const StyledActionButtons = styled.div`
  display: inline-grid;
  grid-gap: 0.5rem;
  grid-template-columns: auto auto;
  padding: 0.5rem 0;

  @media (max-width: ${style.collapse}px) {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  }

  ${Button} {
    margin: 0;
    justify-content: center;

    && *,
    && *::before {
      flex: 0 0 auto;
    }
  }

  ${Button} + ${Button} {
    margin-left: 0;
  }
`;

const ActionButtons = (props) => {
  const {
    hasSubscriptionForm,
    past,
    rsvped,
    logged,
    isOrganizer,
    routes,
  } = props;

  if (past) {
    return (

    );
  }

  if (!logged) {
    return (

    );
  }

  if (rsvped) {
    return (

    );
  }

  if (hasSubscriptionForm) {
    return (

    );
  }

  return (

  );
};
ActionButtons.propTypes = {
  hasSubscriptionForm: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  routes: PropTypes.shape({
    manage: PropTypes.string,
    rsvp: PropTypes.string,
  }),
};

const AdditionalMessage = ({ logged, rsvped, price, routes, forUsers }) => {
  if (!logged) {
    return (

        <ActionLink href={routes.login}>Je me connecte</ActionLink> ou{" "}
        <ActionLink href={`${routes.join}?type=${forUsers}`}>
          je m'inscris
        </ActionLink>{" "}
        pour participer à l'événement

    );
  }

  if (rsvped) {
    return (
      <SmallText>
        Annuler ma participation
      </SmallText>
    );
  }

  if (price) {
    return (
      <SmallText>
        Entrée :
        {price}
      </SmallText>
    );
  }

  return (
    <SmallText>Votre email sera communiquée à l'organisateur.rice</SmallText>
  );
};
AdditionalMessage.propTypes = {
  hasSubscriptionForm: PropTypes.bool,
  past: PropTypes.bool,
  rsvped: PropTypes.bool,
  logged: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  price: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
};

const EventHeader = ({
  name,
  rsvp,
  options,
  schedule,
  routes,
  isOrganizer,
  hasSubscriptionForm,
  forUsers,
}) => {
  const globalRoutes = useSelector(getRoutes);
  const logged = useSelector(getIsConnected);

  const rsvped = rsvp === "CO";
  const now = DateTime.local();
  const past = now > schedule.end;
  let eventString = displayHumanDate(schedule.start);
  eventString = eventString.slice(0, 1).toUpperCase() + eventString.slice(1);

  return (
    <EventHeaderContainer>
      <EventTitle>{name}</EventTitle>
      <Hide under>
        <EventDate>{eventString}</EventDate>
      </Hide>
      <ActionButtons
        hasSubscriptionForm={hasSubscriptionForm}
        past={past}
        logged={logged}
        rsvped={rsvped}
        routes={routes}
        isOrganizer={isOrganizer}
        forUsers={forUsers}
      />
      {!past && (
        <AdditionalMessage
          past={past}
          logged={logged}
          rsvped={rsvped}
          price={options.price}
          routes={{ ...routes, ...globalRoutes }}
          forUsers={forUsers}
        />
      )}
    </EventHeaderContainer>
  );
};

EventHeader.propTypes = {
  name: PropTypes.string,
  schedule: PropTypes.instanceOf(Interval),
  hasSubscriptionForm: PropTypes.bool,
  isOrganizer: PropTypes.bool,
  options: PropTypes.shape({
    price: PropTypes.string,
  }),
  rsvp: PropTypes.string,
  routes: PropTypes.object,
  forUsers: PropTypes.string,
  canRSVP: PropTypes.bool,
};

export default EventHeader;
<|endoftext|>