<commit_before>'use strict'
var estraverse = require('estraverse')

// Node type unknown to estraverse
var keys = {
	ParenthesizedExpression: ['expression'],
}

function blocks(a, isEnd) {
	var bs = []
	for (var i = 0; i < a.length;) {
		for (var j = i + 1; j < a.length; j++)
			if (isEnd(a[j], j))
				break
		bs.push(a.slice(i, j))
		i = j
	}
	return bs
}

function cmp(a, b) {
	if (a < b)
		return -1
	if (a > b)
		return 1
	return 0
}

function cmpCases(a, b) {
	function key(x) {
		x = x.test
		if (!x)
			return '\uffff'
		switch (x.type) {
		case 'Identifier':
			return x.name
		case 'Literal':
			return x.value
		}
	}

	return cmp(key(a), key(b))
}

function hasTerminator(c) {
	var a = c.consequent
	if (!a.length)
		return
	return isTerminator(last(a))
}

function isExport(a) {
	if (a.type !== 'ExpressionStatement')
		return
	a = a.expression
	if (a.type !== 'AssignmentExpression')
		return
	if (a.left.type !== 'MemberExpression')
		return
	if (a.left.object.type !== 'Identifier')
		return
	if (a.left.object.name !== 'exports')
		return
	if (a.right.type !== 'Identifier')
		return
	return true
}

function isRequire(a) {
	if (a.type !== 'VariableDeclaration')
		return
	if (a.declarations.length !== 1)
		return
	a = a.declarations[0].init
	if (!a)
		return
	if (a.type !== 'CallExpression')
		return
	if (a.callee.type !== 'Identifier')
		return
	if (a.callee.name !== 'require')
		return
	return true
}

function isTerminator(a) {
	switch (a.type) {
	case 'BreakStatement':
	case 'ContinueStatement':
	case 'ReturnStatement':
	case 'ThrowStatement':
		return true
	}
}

function last(a) {
	return a[a.length - 1]
}

function negate(f) {
	return a => !f(a)
}

function print(a) {
	console.log(require('util').inspect(a, {
		colors: true,
		depth: null,
		maxArrayLength: null,
		showHidden: false,
	}))
}

function run(a) {
	// ===
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'BinaryExpression')
				return
			if (a.left.value !== null && a.right.value !== null)
				switch (a.operator) {
				case '!=':
					a.operator = '!=='
					break
				case '==':
					a.operator = '==='
					break
				}
		},
		keys,
	})

	// Braces
	estraverse.traverse(a, {
		enter(a) {
			switch (a.type) {
			case 'DoWhileStatement':
			case 'ForInStatement':
			case 'ForOfStatement':
			case 'ForStatement':
			case 'WhileStatement':
				a.body = unbrace(a.body)
				break
			case 'IfStatement':
				a.consequent = unbrace(a.consequent)
				a.alternate = unbrace(a.alternate)
				break
			}
		},
		keys,
	})

	// Break
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'SwitchStatement')
				return
			if (!a.cases.length)
				return
			var c = last(a.cases)
			if (hasTerminator(c))
				return
			c.consequent.push({
				loc: a.loc,
				type: 'BreakStatement',
			})
		},
		keys,
	})

	// Comments
	estraverse.traverse(a, {
		enter(a) {
			if (!a.leadingComments)
				return
			for (var c of a.leadingComments) {
				if (c.type !== 'Line')
					continue
				var s = c.value
				for (var i = 0; i < s.length; i++)
					if (s[i] !== ' ') {
						c.value = s.slice(0, i) + s[i].toUpperCase() + s.slice(i + 1)
						break
					}
			}
		},
		keys,
	})

	// Vars
	estraverse.traverse(a, {
		enter(a, parent) {
			if (a.type !== 'VariableDeclaration')
				return
			switch (parent.type) {
			case 'BlockStatement':
			case 'Program':
				var body = parent.body
				break
			case 'SwitchCase':
				body = parent.consequent
				break
			default:
				return
			}
			var vars = a.declarations
			if (a.leadingComments)
				vars[0].leadingComments = (vars[0].leadingComments || []).concat(a.leadingComments)
			for (var i = 0; i < vars.length; i++)
				vars[i] = {
					declarations: [vars[i]],
					type: a.type,
				}
			body.splice(body.indexOf(a), 1, ...vars)
		},
		keys,
	})

	// Sort cases
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'SwitchStatement')
				return
			a.cases = sortElements(
				a.cases,
				c => true,
				(c, i) => a.cases[i - 1].consequent.length,
				cmpCases,
				b =>  {
					var consequent = []
					for (var c of b)
						if (c.consequent.length) {
							consequent = c.consequent
							c.consequent = []
						}
					last(b).consequent = consequent
				})
			a.cases = sortBlocks(a.cases, (c, i) => a.cases[i - 1].consequent.length && hasTerminator(a.cases[i - 1]), cmpCases)
		},
		keys,
	})

	// Sort exports
	estraverse.traverse(a, {
		enter(a) {
			if (!a.body)
				return
			a.body = sortElements(
				a.body,
				isExport,
				negate(isExport),
				(a, b) =>  {
					function key(x) {
						return x.expression.right.name
					}

					return cmp(key(a), key(b))
				})
		},
		keys,
	})

	// Sort functions
	estraverse.traverse(a, {
		enter(a) {
			if (!a.body)
				return
			a.body = sortElements(
				a.body,
				b => b.type === 'FunctionDeclaration',
				b => b.type !== 'FunctionDeclaration' || b.leadingComments,
				(a, b) =>  {
					function key(x) {
						return x.id.name
					}

					return cmp(key(a), key(b))
				},
				a =>  {
					var comment
					for (var i = 0; i < a.length; i++) {
						if (a[i].leadingComments) {
							comment = a[i].leadingComments
							delete a[i].leadingComments
						}
						a[0].leadingComments = comment
					}
				})
		},
		keys,
	})

	// Sort properties
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'ObjectExpression')
				return
			a.properties.sort(
				(a, b) =>  {
					function key(x) {
						x = x.key
						switch (x.type) {
						case 'Identifier':
							return x.name
						case 'Literal':
							return x.value
						}
					}

					return cmp(key(a), key(b))
				})
		},
		keys,
	})

	// Sort requires
	estraverse.traverse(a, {
		enter(a) {
			if (!a.body)
				return
			a.body = sortElements(
				a.body,
				isRequire,
				negate(isRequire),
				(a, b) =>  {
					function key(x) {
						return x.declarations[0].id.name
					}

					return cmp(key(a), key(b))
				})
		},
		keys,
	})
}

function sortBlocks(a, isEnd, cmp) {
	var bs = blocks(a, isEnd)
	bs = bs.sort((x, y) => cmp(x[0], y[0]))
	return [].concat(...bs)
}

function sortElements(a, isSortableStart, isSortableEnd, cmp, post) {
	if (a.constructor !== Array)
		return a
	var r = []
	for (var i = 0; i < a.length;) {
		if (!isSortableStart(a[i], j)) {
			r.push(a[i++])
			continue
		}
		for (var j = i + 1; j < a.length; j++)
			if (isSortableEnd(a[j], j))
				break
		var b = a.slice(i, j).sort(cmp)
		if (post)
			post(b)
		r.push(...b)
		i = j
	}
	return r
}

function unbrace(a) {
	if (!a)
		return a
	if (a.type !== 'BlockStatement')
		return a
	switch (a.body.length) {
	case 0:
		return {
			type: 'EmptyStatement',
		}
	case 1:
		return a.body[0]
	}
	return a
}

exports.run = run
<commit_msg>sort vars<commit_after>'use strict'
var estraverse = require('estraverse')

// Node type unknown to estraverse
var keys = {
	ParenthesizedExpression: ['expression'],
}

function blocks(a, isEnd) {
	var bs = []
	for (var i = 0; i < a.length;) {
		for (var j = i + 1; j < a.length; j++)
			if (isEnd(a[j], j))
				break
		bs.push(a.slice(i, j))
		i = j
	}
	return bs
}

function cmp(a, b) {
	if (a < b)
		return -1
	if (a > b)
		return 1
	return 0
}

function cmpCases(a, b) {
	function key(x) {
		x = x.test
		if (!x)
			return '\uffff'
		switch (x.type) {
		case 'Identifier':
			return x.name
		case 'Literal':
			return x.value
		}
	}

	return cmp(key(a), key(b))
}

function hasTerminator(c) {
	var a = c.consequent
	if (!a.length)
		return
	return isTerminator(last(a))
}

function isConst(a) {
	if (!a)
		return true
	switch (a.type) {
	case 'ArrayExpression':
		return !a.elements.length
	case 'Literal':
		return true
	case 'ObjectExpression':
		return !a.properties.length
	}
}

function isConstVar(a) {
	if (a.type !== 'VariableDeclaration')
		return
	if (a.declarations.length !== 1)
		return
	return isConst(a.declarations[0].init)
}

function isExport(a) {
	if (a.type !== 'ExpressionStatement')
		return
	a = a.expression
	if (a.type !== 'AssignmentExpression')
		return
	if (a.left.type !== 'MemberExpression')
		return
	if (a.left.object.type !== 'Identifier')
		return
	if (a.left.object.name !== 'exports')
		return
	if (a.right.type !== 'Identifier')
		return
	return true
}

function isRequire(a) {
	if (a.type !== 'VariableDeclaration')
		return
	if (a.declarations.length !== 1)
		return
	a = a.declarations[0].init
	if (!a)
		return
	if (a.type !== 'CallExpression')
		return
	if (a.callee.type !== 'Identifier')
		return
	if (a.callee.name !== 'require')
		return
	return true
}

function isTerminator(a) {
	switch (a.type) {
	case 'BreakStatement':
	case 'ContinueStatement':
	case 'ReturnStatement':
	case 'ThrowStatement':
		return true
	}
}

function last(a) {
	return a[a.length - 1]
}

function negate(f) {
	return a => !f(a)
}

function print(a) {
	console.log(require('util').inspect(a, {
		colors: true,
		depth: null,
		maxArrayLength: null,
		showHidden: false,
	}))
}

function run(a) {
	// ===
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'BinaryExpression')
				return
			if (a.left.value !== null && a.right.value !== null)
				switch (a.operator) {
				case '!=':
					a.operator = '!=='
					break
				case '==':
					a.operator = '==='
					break
				}
		},
		keys,
	})

	// Braces
	estraverse.traverse(a, {
		enter(a) {
			switch (a.type) {
			case 'DoWhileStatement':
			case 'ForInStatement':
			case 'ForOfStatement':
			case 'ForStatement':
			case 'WhileStatement':
				a.body = unbrace(a.body)
				break
			case 'IfStatement':
				a.consequent = unbrace(a.consequent)
				a.alternate = unbrace(a.alternate)
				break
			}
		},
		keys,
	})

	// Break
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'SwitchStatement')
				return
			if (!a.cases.length)
				return
			var c = last(a.cases)
			if (hasTerminator(c))
				return
			c.consequent.push({
				loc: a.loc,
				type: 'BreakStatement',
			})
		},
		keys,
	})

	// Comments
	estraverse.traverse(a, {
		enter(a) {
			if (!a.leadingComments)
				return
			for (var c of a.leadingComments) {
				if (c.type !== 'Line')
					continue
				var s = c.value
				for (var i = 0; i < s.length; i++)
					if (s[i] !== ' ') {
						c.value = s.slice(0, i) + s[i].toUpperCase() + s.slice(i + 1)
						break
					}
			}
		},
		keys,
	})

	// Vars
	estraverse.traverse(a, {
		enter(a, parent) {
			if (a.type !== 'VariableDeclaration')
				return
			switch (parent.type) {
			case 'BlockStatement':
			case 'Program':
				var body = parent.body
				break
			case 'SwitchCase':
				body = parent.consequent
				break
			default:
				return
			}
			var vars = a.declarations
			if (a.leadingComments)
				vars[0].leadingComments = (vars[0].leadingComments || []).concat(a.leadingComments)
			for (var i = 0; i < vars.length; i++)
				vars[i] = {
					declarations: [vars[i]],
					type: a.type,
				}
			body.splice(body.indexOf(a), 1, ...vars)
		},
		keys,
	})

	// Sort cases
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'SwitchStatement')
				return
			a.cases = sortElements(
				a.cases,
				c => true,
				(c, i) => a.cases[i - 1].consequent.length,
				cmpCases,
				b =>  {
					var consequent = []
					for (var c of b)
						if (c.consequent.length) {
							consequent = c.consequent
							c.consequent = []
						}
					last(b).consequent = consequent
				})
			a.cases = sortBlocks(a.cases, (c, i) => a.cases[i - 1].consequent.length && hasTerminator(a.cases[i - 1]), cmpCases)
		},
		keys,
	})

	// Sort exports
	estraverse.traverse(a, {
		enter(a) {
			if (!a.body)
				return
			a.body = sortElements(
				a.body,
				isExport,
				negate(isExport),
				(a, b) =>  {
					function key(x) {
						return x.expression.right.name
					}

					return cmp(key(a), key(b))
				})
		},
		keys,
	})

	// Sort functions
	estraverse.traverse(a, {
		enter(a) {
			if (!a.body)
				return
			a.body = sortElements(
				a.body,
				b => b.type === 'FunctionDeclaration',
				b => b.type !== 'FunctionDeclaration' || b.leadingComments,
				(a, b) =>  {
					function key(x) {
						return x.id.name
					}

					return cmp(key(a), key(b))
				},
				a =>  {
					var comment
					for (var i = 0; i < a.length; i++) {
						if (a[i].leadingComments) {
							comment = a[i].leadingComments
							delete a[i].leadingComments
						}
						a[0].leadingComments = comment
					}
				})
		},
		keys,
	})

	// Sort properties
	estraverse.traverse(a, {
		enter(a) {
			if (a.type !== 'ObjectExpression')
				return
			a.properties.sort(
				(a, b) =>  {
					function key(x) {
						x = x.key
						switch (x.type) {
						case 'Identifier':
							return x.name
						case 'Literal':
							return x.value
						}
					}

					return cmp(key(a), key(b))
				})
		},
		keys,
	})

	// Sort requires
	estraverse.traverse(a, {
		enter(a) {
			if (!a.body)
				return
			a.body = sortElements(
				a.body,
				isRequire,
				negate(isRequire),
				(a, b) =>  {
					function key(x) {
						return x.declarations[0].id.name
					}

					return cmp(key(a), key(b))
				})
		},
		keys,
	})

	// Sort vars
	estraverse.traverse(a, {
		enter(a) {
			if (!a.body)
				return
			a.body = sortElements(
				a.body,
				isConstVar,
				negate(isConstVar),
				(a, b) =>  {
					function key(x) {
						return x.declarations[0].id.name
					}

					return cmp(key(a), key(b))
				})
		},
		keys,
	})
}

function sortBlocks(a, isEnd, cmp) {
	var bs = blocks(a, isEnd)
	bs = bs.sort((x, y) => cmp(x[0], y[0]))
	return [].concat(...bs)
}

function sortElements(a, isSortableStart, isSortableEnd, cmp, post) {
	if (a.constructor !== Array)
		return a
	var r = []
	for (var i = 0; i < a.length;) {
		if (!isSortableStart(a[i], j)) {
			r.push(a[i++])
			continue
		}
		for (var j = i + 1; j < a.length; j++)
			if (isSortableEnd(a[j], j))
				break
		var b = a.slice(i, j).sort(cmp)
		if (post)
			post(b)
		r.push(...b)
		i = j
	}
	return r
}

function unbrace(a) {
	if (!a)
		return a
	if (a.type !== 'BlockStatement')
		return a
	switch (a.body.length) {
	case 0:
		return {
			type: 'EmptyStatement',
		}
	case 1:
		return a.body[0]
	}
	return a
}

exports.run = run
<|endoftext|>


<commit_before>import { connect } from 'react-redux'
import { SITE_META, SITE_NAME } from '../constants/index'
import Banner from '../components/topic/banner'
import Description from '../components/topic/description'
import Helmet from 'react-helmet'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import Related from '../components/topic/related'
import styled from 'styled-components'
import SystemError from '../components/SystemError'
import TopicHeader from '../components/topic/header'
// @twreporter
import twreporterRedux from '@twreporter/redux'
// lodash
import forEach from 'lodash/forEach'
import get from 'lodash/get'
import merge from 'lodash/merge'

const { actions, reduxStateFields, utils } = twreporterRedux

const _  = {
  forEach,
  get,
  merge
}

const Container = styled.div`
  position: relative;
`

class TopicLandingPage extends Component {
  static defaultProps = {
    entities: {},
    selectedTopic: {}
  }

  static propTypes = {
    // from redux store
    entities: PropTypes.object,
    selectedTopic: PropTypes.object,
    // react-router `match` object
    match: PropTypes.object.isRequired
  }

  componentDidMount() {
    const { fetchAFullTopic, match } = this.props
    const slug = _.get(match, 'params.slug')
    fetchAFullTopic(slug)
  }

  _renderLoadingElements() {
    /* TODO: Add loading mockup or spinner */
    return (
      <Container>
        <TopicHeader />
      </Container>
    )
  }

  _renderTopic(slug) {
    const { entities } = this.props
    const postEntities = _.get(entities, reduxStateFields.postsInEntities, {})
    const topicEntities = _.get(entities, reduxStateFields.topicsInEntities, {})
    const topic = _.get(utils.denormalizeTopics(slug, topicEntities, postEntities), '0')
    if (!topic) {
      console.error('There is no topic in store corresponding with the given slug:', slug) // eslint-disable-line no-console
      return <SystemError error={{ status: 404 }} />
    }
    const {
      relateds_background,
      relateds_format,
      title_position,
      og_image,
      leading_image,
      leading_video,
      leading_image_portrait,
      relateds,
      headline,
      subtitle,
      title
    } = topic
    const topicDescription = _.get(topic, 'description.api_data', [])
    const teamDescription = _.get(topic, 'team_description.api_data', [])
    const ogDescription =  _.get(topic, 'og_description', '') || SITE_META.DESC
    const ogTitle = _.get(topic, 'og_title', '') || _.get(topic, 'title', '')
    const publishedDate = _.get(topic, 'published_date', '')

    const canonical = `${SITE_META.URL}topics/${slug}`
    const fullTitle = ogTitle + SITE_NAME.SEPARATOR + SITE_NAME.FULL
    return (
      <Container>
        <Helmet
          title={fullTitle}
          link={[
            { rel: 'canonical', href: canonical }
          ]}
          meta={[
            { name: 'description', content: ogDescription },
            { name: 'twitter:title', content: fullTitle },
            { name: 'twitter:description', content: ogDescription },
            { name: 'twitter:image', content: og_image },
            { name: 'twitter:card', content: 'summary_large_image' },
            { property: 'og:title', content: fullTitle },
            { property: 'og:description', content: ogDescription },
            { property: 'og:image', content: og_image },
            { property: 'og:type', content: 'website' },
            { property: 'og:url', content: canonical },
            { property: 'og:rich_attachment', content: 'true' }
          ]}
        />
        <Banner
          theme={title_position}
          headline={headline}
          title={title}
          subtitle={subtitle}
          publishedDate={publishedDate}
          leadingVideo={leading_video}
          leadingImage={leading_image}
          leadingImagePortrait={leading_image_portrait}
          ogImage={og_image}
        />
        <TopicHeader />
        <Description
          topicDescription={topicDescription}
          teamDescription={teamDescription}
        />
        <Related
          items={relateds}
          format={relateds_format}
          background={relateds_background}
        />
      </Container>
    )
  }

  render() {
    const { selectedTopic } = this.props
    const error = _.get(selectedTopic, 'error')
    if (error) {
      return (
        <SystemError error={error} />
      )
    }
    const isFetching = _.get(selectedTopic, 'isFetching', false)
    const slug = _.get(selectedTopic, 'slug')
    if (isFetching || !slug) {
      return this._renderLoadingElements()
    }
    return this._renderTopic(slug)
  }
}

function mapStateToProps(state) {
  return {
    entities: state[reduxStateFields.entities] || {},
    selectedTopic: state[reduxStateFields.selectedTopic] || {}
  }
}

export { TopicLandingPage }
export default connect(mapStateToProps, { fetchAFullTopic: actions.fetchAFullTopic })(TopicLandingPage)
<commit_msg>Add topic banner placeholder<commit_after>import { connect } from 'react-redux'
import { SITE_META, SITE_NAME } from '../constants/index'
import Banner from '../components/topic/banner'
import Description from '../components/topic/description'
import Helmet from 'react-helmet'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import Related from '../components/topic/related'
import styled from 'styled-components'
import SystemError from '../components/SystemError'
import TopicHeader from '../components/topic/header'
// @twreporter
import twreporterRedux from '@twreporter/redux'
// lodash
import forEach from 'lodash/forEach'
import get from 'lodash/get'
import merge from 'lodash/merge'

const { actions, reduxStateFields, utils } = twreporterRedux

const _  = {
  forEach,
  get,
  merge
}

const Container = styled.div`
  position: relative;
`

const BannerPlaceholder = styled.div`
  height: 100vh;
  background: rgba(0, 0, 0, 0.48);
`

class TopicLandingPage extends Component {
  static defaultProps = {
    entities: {},
    selectedTopic: {}
  }

  static propTypes = {
    // from redux store
    entities: PropTypes.object,
    selectedTopic: PropTypes.object,
    // react-router `match` object
    match: PropTypes.object.isRequired
  }

  componentDidMount() {
    const { fetchAFullTopic, match } = this.props
    const slug = _.get(match, 'params.slug')
    fetchAFullTopic(slug)
  }

  _renderLoadingElements() {
    /* TODO: Add loading mockup or spinner */
    return (
      <Container>
        <TopicHeader />
        <BannerPlaceholder />
      </Container>
    )
  }

  _renderTopic(slug) {
    const { entities } = this.props
    const postEntities = _.get(entities, reduxStateFields.postsInEntities, {})
    const topicEntities = _.get(entities, reduxStateFields.topicsInEntities, {})
    const topic = _.get(utils.denormalizeTopics(slug, topicEntities, postEntities), '0')
    if (!topic) {
      console.error('There is no topic in store corresponding with the given slug:', slug) // eslint-disable-line no-console
      return <SystemError error={{ status: 404 }} />
    }
    const {
      relateds_background,
      relateds_format,
      title_position,
      og_image,
      leading_image,
      leading_video,
      leading_image_portrait,
      relateds,
      headline,
      subtitle,
      title
    } = topic
    const topicDescription = _.get(topic, 'description.api_data', [])
    const teamDescription = _.get(topic, 'team_description.api_data', [])
    const ogDescription =  _.get(topic, 'og_description', '') || SITE_META.DESC
    const ogTitle = _.get(topic, 'og_title', '') || _.get(topic, 'title', '')
    const publishedDate = _.get(topic, 'published_date', '')

    const canonical = `${SITE_META.URL}topics/${slug}`
    const fullTitle = ogTitle + SITE_NAME.SEPARATOR + SITE_NAME.FULL
    return (
      <Container>
        <Helmet
          title={fullTitle}
          link={[
            { rel: 'canonical', href: canonical }
          ]}
          meta={[
            { name: 'description', content: ogDescription },
            { name: 'twitter:title', content: fullTitle },
            { name: 'twitter:description', content: ogDescription },
            { name: 'twitter:image', content: og_image },
            { name: 'twitter:card', content: 'summary_large_image' },
            { property: 'og:title', content: fullTitle },
            { property: 'og:description', content: ogDescription },
            { property: 'og:image', content: og_image },
            { property: 'og:type', content: 'website' },
            { property: 'og:url', content: canonical },
            { property: 'og:rich_attachment', content: 'true' }
          ]}
        />
        <Banner
          theme={title_position}
          headline={headline}
          title={title}
          subtitle={subtitle}
          publishedDate={publishedDate}
          leadingVideo={leading_video}
          leadingImage={leading_image}
          leadingImagePortrait={leading_image_portrait}
          ogImage={og_image}
        />
        <TopicHeader />
        <Description
          topicDescription={topicDescription}
          teamDescription={teamDescription}
        />
        <Related
          items={relateds}
          format={relateds_format}
          background={relateds_background}
        />
      </Container>
    )
  }

  render() {
    const { selectedTopic } = this.props
    const error = _.get(selectedTopic, 'error')
    if (error) {
      return (
        <SystemError error={error} />
      )
    }
    const isFetching = _.get(selectedTopic, 'isFetching', false)
    const slug = _.get(selectedTopic, 'slug')
    if (isFetching || !slug) {
      return this._renderLoadingElements()
    }
    return this._renderTopic(slug)
  }
}

function mapStateToProps(state) {
  return {
    entities: state[reduxStateFields.entities] || {},
    selectedTopic: state[reduxStateFields.selectedTopic] || {}
  }
}

export { TopicLandingPage }
export default connect(mapStateToProps, { fetchAFullTopic: actions.fetchAFullTopic })(TopicLandingPage)
<|endoftext|>


<commit_before>/**
 * @fileOverview Manages the form interaction with remote servers.
 **/

/**
 * The callbacks assign the state of the application.
 *
 * This application can be placed into the following states:
 * 1. Pending Login Check: The app is currently requesting the CSRF
 *    token from the remote server. Callback=pendingLogin
 * 2. Failure to login: The user is not currently authenticated with the
 *    remote server. In this state the user is prompted to login.
 *    Callback=loginFailure
 * 3. Pending post: The user can make the post at this point.
 *    Callback=pendingPost
 * 4. Completed post: The remote server has returned a URL. This app should
 *    display it and fire the URL event.
 *    Callback=postCompleted
 */
var callbacks = {

  /**
   * Initialize the whole application.
   */
  pendingLogin: function() {

    // Save to local storage the app to redirect to after succesful log in
    ls.setItem("Login:redirect_to_app", window.location.href);

    // Set the nav bar to the proper domain
    privlyNetworkService.initializeNavigation();

    // Initialize message pathway to the extension.
    messaging.initialize();

    // Watch for the preview iframe's messages so it can be resized
    window.addEventListener('message', resizeIframePostedMessage, false);

    // Add listeners to show loading animation while making ajax requests
    $(document).ajaxStart(function() {
      $('#loadingDiv').show();
    });
    $(document).ajaxStop(function() {
      $('#loadingDiv').hide();
    });

    privlyNetworkService.initPrivlyService(
      privlyNetworkService.contentServerDomain(),
      callbacks.pendingPost,
      callbacks.loginFailure,
      callbacks.loginFailure);
  },

  /**
   * Prompt the user to sign into their server. This assumes the remote
   * server's sign in endpoint is at "/users/sign_in".
   */
  loginFailure: function() {
    $("#messages").hide();
    $("#login_message").show();
    $("#refresh_link").click(function(){location.reload(true);});
    privlyNetworkService.showLoggedOutNav();
  },

  /**
   * Tell the user they can create their post by updating the UI.
   */
  pendingPost: function() {

    privlyNetworkService.showLoggedInNav();

    privlyNetworkService.sameOriginGetRequest(
      privlyNetworkService.contentServerDomain() + "/posts",
      callbacks.postCompleted);
    $("#save").prop('disabled', false);
    $("#messages").toggle();
    $("#form").toggle();
  },

  /**
   * Parse the JSON date format and return the difference in time
   * @param {json} string Represents the date
   * @param {bool} mode Sets if the date is in the past or in the future
   */
  parseDate: function(string, mode) {

    var date = new Date(string);
    var current = new Date();

    var timeDiff;
    if (mode) {
      timeDiff = Math.abs(current.getTime() - date.getTime());
    } else {
      timeDiff = Math.abs(date.getTime() - current.getTime());
    }

    var minutes_raw = Math.floor(timeDiff / (1000 * 60));
    var hours_raw = Math.floor(timeDiff / (1000 * 3600));
    var days = Math.floor(timeDiff / (1000 * 3600 * 24));

    var hours = hours_raw - (days * 24);
    var minutes = minutes_raw - (hours_raw * 60);

    if(days > 1) {
      days = days + " days ";
    } else if(days > 0) {
      days = days + " day ";
    } else {
      days = "";
    }

    hours = hours > 0 ? hours + "h " : "";

    var end;
    if(minutes == 0 && hours == 0 && days == 0) {
      minutes = "";
      end = "Just now";
    } else {
      end = (mode ? "m ago" : "m from now");
    }

    return " " + days + hours + minutes + end;
  },

  /**
   * Display the table of posts stored at the server.
   */
  postCompleted: function(response) {

    var tableBody = document.getElementById("table_body");
    for(var i = 0; i < response.json.length; i++) {

      var app = response.json[i].privly_application;
      var href = response.json[i].privly_URL;

      // Assumes web and checks for other platforms
      var localHref = "/apps/";
      var platform = privlyNetworkService.platformName();
      if ( platform === "FIREFOX" ) {
        localHref = "/content/privly-applications/";
      } else if(platform == "CHROME") {
        localHref = "/privly-applications/";
      }
      localHref += app + "/show.html?privlyOriginalURL=" +
        encodeURIComponent(href);

      var tr = document.createElement('tr');

      var td1 = document.createElement('td');

      var td1b = document.createElement('button');
      td1b.setAttribute("type", "submit");
      td1b.setAttribute("class", "btn btn-default preview_link");
      td1b.setAttribute("data-canonical-href", localHref);
      td1b.textContent = "Preview " + app;
      td1b.style.width = "150px";
      td1b.style.height = "33px";
      td1.appendChild(td1b);

      var td1b2 = document.createElement('button');
      td1b2.setAttribute("type", "submit");
      td1b2.setAttribute("class", "btn btn-info open_link");
      td1b2.setAttribute("data-canonical-href", localHref);
      td1b2.textContent = "Open";
      td1b2.style.height = "33px";
      td1.appendChild(td1b2);

      tr.appendChild(td1);

      // For the next three columns hide the Json date format,
      // and create an <i> child in which the difference in time will be shown
      var td2 = document.createElement('td');
      td2.textContent = response.json[i].created_at;
      td2.className += " myHide";
      var i1 = document.createElement('i');
      i1.textContent = callbacks.parseDate(response.json[i].created_at, true);
      td2.appendChild(i1);
      tr.appendChild(td2);

      var td3 = document.createElement('td');
      td3.textContent = response.json[i].burn_after_date;
      td3.className += " myHide";
      var i2 = document.createElement('i');
      i2.textContent = callbacks.parseDate(response.json[i].burn_after_date, false);
      td3.appendChild(i2);
      tr.appendChild(td3);

      var td4 = document.createElement('td');
      td4.textContent = response.json[i].updated_at;
      td4.className += " myHide";
      var i3 = document.createElement('i');
      i3.textContent = callbacks.parseDate(response.json[i].updated_at, true);
      td4.appendChild(i3);
      tr.appendChild(td4);

      tableBody.appendChild(tr)

    }

    dataTable = $('#posts').dataTable({"bPaginate": false, "bFilter": false});

    // Add 'cell-border' class when the window has a width smaller than 768px
    $(window).resize(function() {
      if($(window).width() < 768) {
        $('#posts').addClass("cell-border");
      } else {
        $('#posts').removeClass("cell-border");
      }
    });

    $('button.preview_link').on('click', function(evt) {

      $('html, body').animate({ scrollTop: 0 }, 'slow');

      $('#iframe_col').show('slow', function() {
        $(this).css('display', 'inherit');
      });

      var iFrame = document.createElement('iframe');

      // Styling and display attributes that mirror those
      // of the privly.js content script
      iFrame.setAttribute("frameborder","0");
      iFrame.setAttribute("vspace","0");
      iFrame.setAttribute("hspace","0");
      iFrame.setAttribute("width","100%");
      iFrame.setAttribute("marginwidth","0");
      iFrame.setAttribute("marginheight","0");
      iFrame.setAttribute("height","1px");
      iFrame.setAttribute("frameborder","0");
      iFrame.setAttribute("style","width: 100%; height: 32px; " +
        "overflow: hidden;");
      iFrame.setAttribute("scrolling","no");
      iFrame.setAttribute("overflow","hidden");
      iFrame.setAttribute("data-privly-accept-resize","true");

      // The href of the original link as dictated by the remote server
      var canonicalHref = $(this).attr("data-canonical-href");
      iFrame.setAttribute("data-canonical-href", canonicalHref);

      //Set the source URL
      iFrame.setAttribute("src", canonicalHref);

      //The id and the name are the same so that the iframe can be
      //uniquely identified and resized by resizeIframePostedMessage()
      iFrame.setAttribute("id", "ifrm0");
      iFrame.setAttribute("name", "ifrm0");

      // Clear the old iframe and insert the new one
      $(".privly_iframe").empty();
      $(".privly_iframe").append(iFrame);
    });

    $('button.open_link').on('click', function() {
      window.open($(this).attr("data-canonical-href"), '_blank');
    });

    $('#destroy_link').on('click', function() {
      var url = privlyParameters.getApplicationUrl($("iframe").attr("data-canonical-href"));
      var dataURL =  privlyParameters.getParameterHash(url).privlyDataURL;
      privlyNetworkService.sameOriginDeleteRequest(
        dataURL,
        function(response) {
            if( response.jqXHR.status === 200 ) {
              var tr = $(this).closest('tr');
              tr.hide();
              $('#iframe_col').hide('slow');
            }
        }, {});
    });

    $('#hide_preview').on('click', function() {
    $('#iframe_col').hide('slow');
    });
  }
}

/**
 * Message handlers for integration with extension framworks.
 */
var messaging = {

  /**
   * Attach the message listeners to the interface between the extension
   * and the injectable application.
   */
  initialize: function() {
      privlyExtension.initialContent = messaging.initialContent;
      privlyExtension.messageSecret = messaging.messageSecret;

      // Initialize message pathway to the extension.
      privlyExtension.firePrivlyMessageSecretEvent();
  },

  /**
   * Listener for the initial content that should be dropped into the form.
   * This may be sent by a browser extension.
   *
   * @param {json} data A json document containing the initial content for
   * the form.
   */
  initialContent: function(data) {},

  /**
   * Request the initial content from the extension. This callback is executed
   * after the extension successfully messages the secret message back to the
   * application.
   *
   * @param {json} data A json document that is ignored by this function.
   */
  messageSecret: function(data) {}

}

/**
 * Resize eligible iframes to the proper height based on their contents.
 *
 * @param {message} e The message posted by an iframe.
 */
function resizeIframePostedMessage(e) {
  var messageComponents = e.data.split(",");
  if( e.origin !== window.location.origin ||
    messageComponents.length < 2 ||
    messageComponents[0] === ""
    ) {
    return;
  }
  var iframe = document.getElementById(messageComponents[0]);
  if(iframe !== null) {
    iframe.style.height = messageComponents[1] + "px";
  }
}

/**
 * Sends the currently displayed URL to the extension or mobile framework
 * running the applicaiton so it can be submitted to a host page webform.
 */
function postUrl() {
  privlyExtension.firePrivlyURLEvent(
    document.getElementById("ifrm0").getAttribute("data-canonical-href"));
}

// Initialize the application
document.addEventListener('DOMContentLoaded',
  function() {

    // Don't start the script if it is running in a Headless
    // browser
    if( document.getElementById("logout_link") )
      callbacks.pendingLogin();
  }
);
<commit_msg>Conditionally rename deprecated ZeroBin app<commit_after>/**
 * @fileOverview Manages the form interaction with remote servers.
 **/

/**
 * The callbacks assign the state of the application.
 *
 * This application can be placed into the following states:
 * 1. Pending Login Check: The app is currently requesting the CSRF
 *    token from the remote server. Callback=pendingLogin
 * 2. Failure to login: The user is not currently authenticated with the
 *    remote server. In this state the user is prompted to login.
 *    Callback=loginFailure
 * 3. Pending post: The user can make the post at this point.
 *    Callback=pendingPost
 * 4. Completed post: The remote server has returned a URL. This app should
 *    display it and fire the URL event.
 *    Callback=postCompleted
 */
var callbacks = {

  /**
   * Initialize the whole application.
   */
  pendingLogin: function() {

    // Save to local storage the app to redirect to after succesful log in
    ls.setItem("Login:redirect_to_app", window.location.href);

    // Set the nav bar to the proper domain
    privlyNetworkService.initializeNavigation();

    // Initialize message pathway to the extension.
    messaging.initialize();

    // Watch for the preview iframe's messages so it can be resized
    window.addEventListener('message', resizeIframePostedMessage, false);

    // Add listeners to show loading animation while making ajax requests
    $(document).ajaxStart(function() {
      $('#loadingDiv').show();
    });
    $(document).ajaxStop(function() {
      $('#loadingDiv').hide();
    });

    privlyNetworkService.initPrivlyService(
      privlyNetworkService.contentServerDomain(),
      callbacks.pendingPost,
      callbacks.loginFailure,
      callbacks.loginFailure);
  },

  /**
   * Prompt the user to sign into their server. This assumes the remote
   * server's sign in endpoint is at "/users/sign_in".
   */
  loginFailure: function() {
    $("#messages").hide();
    $("#login_message").show();
    $("#refresh_link").click(function(){location.reload(true);});
    privlyNetworkService.showLoggedOutNav();
  },

  /**
   * Tell the user they can create their post by updating the UI.
   */
  pendingPost: function() {

    privlyNetworkService.showLoggedInNav();

    privlyNetworkService.sameOriginGetRequest(
      privlyNetworkService.contentServerDomain() + "/posts",
      callbacks.postCompleted);
    $("#save").prop('disabled', false);
    $("#messages").toggle();
    $("#form").toggle();
  },

  /**
   * Parse the JSON date format and return the difference in time
   * @param {json} string Represents the date
   * @param {bool} mode Sets if the date is in the past or in the future
   */
  parseDate: function(string, mode) {

    var date = new Date(string);
    var current = new Date();

    var timeDiff;
    if (mode) {
      timeDiff = Math.abs(current.getTime() - date.getTime());
    } else {
      timeDiff = Math.abs(date.getTime() - current.getTime());
    }

    var minutes_raw = Math.floor(timeDiff / (1000 * 60));
    var hours_raw = Math.floor(timeDiff / (1000 * 3600));
    var days = Math.floor(timeDiff / (1000 * 3600 * 24));

    var hours = hours_raw - (days * 24);
    var minutes = minutes_raw - (hours_raw * 60);

    if(days > 1) {
      days = days + " days ";
    } else if(days > 0) {
      days = days + " day ";
    } else {
      days = "";
    }

    hours = hours > 0 ? hours + "h " : "";

    var end;
    if(minutes == 0 && hours == 0 && days == 0) {
      minutes = "";
      end = "Just now";
    } else {
      end = (mode ? "m ago" : "m from now");
    }

    return " " + days + hours + minutes + end;
  },

  /**
   * Display the table of posts stored at the server.
   */
  postCompleted: function(response) {

    var tableBody = document.getElementById("table_body");
    for(var i = 0; i < response.json.length; i++) {

      var href = response.json[i].privly_URL;
      var app = response.json[i].privly_application;

      // Rename deperecated apps
      if ( app === "ZeroBin" ) {
        app = "Message";
      }

      // Assumes web and checks for other platforms
      var localHref = "/apps/";
      var platform = privlyNetworkService.platformName();
      if ( platform === "FIREFOX" ) {
        localHref = "/content/privly-applications/";
      } else if(platform == "CHROME") {
        localHref = "/privly-applications/";
      }
      localHref += app + "/show.html?privlyOriginalURL=" +
        encodeURIComponent(href);

      var tr = document.createElement('tr');

      var td1 = document.createElement('td');

      var td1b = document.createElement('button');
      td1b.setAttribute("type", "submit");
      td1b.setAttribute("class", "btn btn-default preview_link");
      td1b.setAttribute("data-canonical-href", localHref);
      td1b.textContent = "Preview " + app;
      td1b.style.width = "150px";
      td1b.style.height = "33px";
      td1.appendChild(td1b);

      var td1b2 = document.createElement('button');
      td1b2.setAttribute("type", "submit");
      td1b2.setAttribute("class", "btn btn-info open_link");
      td1b2.setAttribute("data-canonical-href", localHref);
      td1b2.textContent = "Open";
      td1b2.style.height = "33px";
      td1.appendChild(td1b2);

      tr.appendChild(td1);

      // For the next three columns hide the Json date format,
      // and create an <i> child in which the difference in time will be shown
      var td2 = document.createElement('td');
      td2.textContent = response.json[i].created_at;
      td2.className += " myHide";
      var i1 = document.createElement('i');
      i1.textContent = callbacks.parseDate(response.json[i].created_at, true);
      td2.appendChild(i1);
      tr.appendChild(td2);

      var td3 = document.createElement('td');
      td3.textContent = response.json[i].burn_after_date;
      td3.className += " myHide";
      var i2 = document.createElement('i');
      i2.textContent = callbacks.parseDate(response.json[i].burn_after_date, false);
      td3.appendChild(i2);
      tr.appendChild(td3);

      var td4 = document.createElement('td');
      td4.textContent = response.json[i].updated_at;
      td4.className += " myHide";
      var i3 = document.createElement('i');
      i3.textContent = callbacks.parseDate(response.json[i].updated_at, true);
      td4.appendChild(i3);
      tr.appendChild(td4);

      tableBody.appendChild(tr)

    }

    dataTable = $('#posts').dataTable({"bPaginate": false, "bFilter": false});

    // Add 'cell-border' class when the window has a width smaller than 768px
    $(window).resize(function() {
      if($(window).width() < 768) {
        $('#posts').addClass("cell-border");
      } else {
        $('#posts').removeClass("cell-border");
      }
    });

    $('button.preview_link').on('click', function(evt) {

      $('html, body').animate({ scrollTop: 0 }, 'slow');

      $('#iframe_col').show('slow', function() {
        $(this).css('display', 'inherit');
      });

      var iFrame = document.createElement('iframe');

      // Styling and display attributes that mirror those
      // of the privly.js content script
      iFrame.setAttribute("frameborder","0");
      iFrame.setAttribute("vspace","0");
      iFrame.setAttribute("hspace","0");
      iFrame.setAttribute("width","100%");
      iFrame.setAttribute("marginwidth","0");
      iFrame.setAttribute("marginheight","0");
      iFrame.setAttribute("height","1px");
      iFrame.setAttribute("frameborder","0");
      iFrame.setAttribute("style","width: 100%; height: 32px; " +
        "overflow: hidden;");
      iFrame.setAttribute("scrolling","no");
      iFrame.setAttribute("overflow","hidden");
      iFrame.setAttribute("data-privly-accept-resize","true");

      // The href of the original link as dictated by the remote server
      var canonicalHref = $(this).attr("data-canonical-href");
      iFrame.setAttribute("data-canonical-href", canonicalHref);

      //Set the source URL
      iFrame.setAttribute("src", canonicalHref);

      //The id and the name are the same so that the iframe can be
      //uniquely identified and resized by resizeIframePostedMessage()
      iFrame.setAttribute("id", "ifrm0");
      iFrame.setAttribute("name", "ifrm0");

      // Clear the old iframe and insert the new one
      $(".privly_iframe").empty();
      $(".privly_iframe").append(iFrame);
    });

    $('button.open_link').on('click', function() {
      window.open($(this).attr("data-canonical-href"), '_blank');
    });

    $('#destroy_link').on('click', function() {
      var url = privlyParameters.getApplicationUrl($("iframe").attr("data-canonical-href"));
      var dataURL =  privlyParameters.getParameterHash(url).privlyDataURL;
      privlyNetworkService.sameOriginDeleteRequest(
        dataURL,
        function(response) {
            if( response.jqXHR.status === 200 ) {
              var tr = $(this).closest('tr');
              tr.hide();
              $('#iframe_col').hide('slow');
            }
        }, {});
    });

    $('#hide_preview').on('click', function() {
    $('#iframe_col').hide('slow');
    });
  }
}

/**
 * Message handlers for integration with extension framworks.
 */
var messaging = {

  /**
   * Attach the message listeners to the interface between the extension
   * and the injectable application.
   */
  initialize: function() {
      privlyExtension.initialContent = messaging.initialContent;
      privlyExtension.messageSecret = messaging.messageSecret;

      // Initialize message pathway to the extension.
      privlyExtension.firePrivlyMessageSecretEvent();
  },

  /**
   * Listener for the initial content that should be dropped into the form.
   * This may be sent by a browser extension.
   *
   * @param {json} data A json document containing the initial content for
   * the form.
   */
  initialContent: function(data) {},

  /**
   * Request the initial content from the extension. This callback is executed
   * after the extension successfully messages the secret message back to the
   * application.
   *
   * @param {json} data A json document that is ignored by this function.
   */
  messageSecret: function(data) {}

}

/**
 * Resize eligible iframes to the proper height based on their contents.
 *
 * @param {message} e The message posted by an iframe.
 */
function resizeIframePostedMessage(e) {
  var messageComponents = e.data.split(",");
  if( e.origin !== window.location.origin ||
    messageComponents.length < 2 ||
    messageComponents[0] === ""
    ) {
    return;
  }
  var iframe = document.getElementById(messageComponents[0]);
  if(iframe !== null) {
    iframe.style.height = messageComponents[1] + "px";
  }
}

/**
 * Sends the currently displayed URL to the extension or mobile framework
 * running the applicaiton so it can be submitted to a host page webform.
 */
function postUrl() {
  privlyExtension.firePrivlyURLEvent(
    document.getElementById("ifrm0").getAttribute("data-canonical-href"));
}

// Initialize the application
document.addEventListener('DOMContentLoaded',
  function() {

    // Don't start the script if it is running in a Headless
    // browser
    if( document.getElementById("logout_link") )
      callbacks.pendingLogin();
  }
);
<|endoftext|>


<commit_before>   function importArtifacts() {

      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();

           var tutInfoString = result[0];
           tut           = JSON.parse( tutInfoString );

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

        try {
           result = javaImportPIFileFunction(tut.name,tut.zipURL);
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };

   function cleanUp() {
      alert("inside tutorials cleanup");
      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();

           var tutInfoString = result[0];
           tut = JSON.parse( tutInfoString );
           alert(tutInfoString);

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

        try {
           result = javaUnDeployResourcesFunction( 'TESTNODE_demond','default', tut.appName);
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );

        }//catch

        try {
        	alert(tut.projects);
           result = javaDeleteProjectsFromWorkspaceFunction( [ tut.name ,tut.projects ] );
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };

   function deployArtifacts() {

      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();

           var tutInfoString = result[0];
           tut           = JSON.parse( tutInfoString );

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

        try {
           result = javaDeployBARFunction( 'TESTNODE_demond','default', tut.barFile );
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };

   function backToGallery() {

      var result=null;

        try {
           result = javaBackToGalleryFunction();
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

   };

   function openExternalBrowser(externalURL) {

      var result = null;

      try {
           result = javaOpenURLInExternalBrowserFunction( externalURL );
      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

   };

   function openHelpSystem(helpURL) {

      var result = null;

      try {
           result = javaOpenURLInHelpSystemFunction( helpURL);
      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

   };

   function viewDetails() {

      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();

           var tutInfoString = result[0];
           tut           = JSON.parse( tutInfoString );

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

        try {
           result = javaBackToDetailsFunction(tut.detailsURL);
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };
<commit_msg>alerts<commit_after>   function importArtifacts() {

      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();
           alert("(TUTORIAL)Importing the artifacts from : " + result);

           var tutInfoString = result[0];
           tut           = JSON.parse( tutInfoString );

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

        try {
           result = javaImportPIFileFunction(tut.name,tut.zipURL);
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };

   function cleanUp() {
      alert("inside tutorials cleanup");
      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();

           var tutInfoString = result[0];
           tut = JSON.parse( tutInfoString );
           alert(tutInfoString);

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

//        try {
//           result = javaUnDeployResourcesFunction( 'TESTNODE_demond','default', tut.appName);
//        }//try
//        catch(e){
//          alert( 'a java error occurred: ' + e.message );
//
//        }//catch

        try {
        	alert(tut.projects);
           result = javaDeleteProjectsFromWorkspaceFunction( [ tut.name ,tut.projects ] );
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };

   function deployArtifacts() {

      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();

           var tutInfoString = result[0];
           tut           = JSON.parse( tutInfoString );

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

        try {
           result = javaDeployBARFunction( 'TESTNODE_demond','default', tut.barFile );
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };

   function backToGallery() {

      var result=null;

        try {
           result = javaBackToGalleryFunction();
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

   };

   function openExternalBrowser(externalURL) {

      var result = null;

      try {
           result = javaOpenURLInExternalBrowserFunction( externalURL );
      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

   };

   function openHelpSystem(helpURL) {

      var result = null;

      try {
           result = javaOpenURLInHelpSystemFunction( helpURL);
      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

   };

   function viewDetails() {

      var result = null;
      var tut = null;
      try {

           result = javaGetSelectedTutorialFunction();

           var tutInfoString = result[0];
           tut           = JSON.parse( tutInfoString );

      }//try
      catch(e){
          alert( 'a java error occurred: ' + e.message );
      }//catch

      if (tut !== undefined){

        try {
           result = javaBackToDetailsFunction(tut.detailsURL);
        }//try
        catch(e){
          alert( 'a java error occurred: ' + e.message );
        }//catch

      }//if

   };
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';

import LoginButton from '../../components/User/LoginButton';

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import * as actions from './userActions';

/**
 * Redux
 */

const mapStateToProps = (state) => ({
  isLoggedIn: state.user.isLoggedIn,
});

const mapDispatchToProps = (dispatch) => ({
  actions: bindActionCreators(actions, dispatch),
});

/**
 * LoginButton component
 */
@connect(mapStateToProps, mapDispatchToProps)
export default class LoginButtonContainer extends Component {

  static get propTypes() {
    return {
      isLoggedIn: PropTypes.bool,
      actions: PropTypes.object,
    };
  }

  constructor(props, context) {
    super(props, context);
    this.state = {};

    this.logIn = this.logIn.bind(this);
    this.logOut = this.logOut.bind(this);
  }

  /**
   * logIn
   */
  logIn() {
    this.props.actions.logIn();
  }

   /**
   * logOut
   */
  logOut() {
    this.props.actions.logOut();
  }

  /**
   * render
   * @return {ReactElement} markup
   */
  render() {
    return (
      <LoginButton isLoggedIn={this.props.isLoggedIn} onLogIn={this.logIn} onLogOut={this.logOut} />
    );
  }
}
<commit_msg>Revert "JM likes actions"<commit_after>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';

import LoginButton from '../../components/User/LoginButton';
import { logIn, logOut } from './userActions';

/**
 * Redux
 */

const mapStateToProps = (state) => ({
  isLoggedIn: state.user.isLoggedIn,
});

/**
 * LoginButton component
 */
@connect(mapStateToProps, { logIn, logOut })
export default class LoginButtonContainer extends Component { // eslint-disable-line

  static get propTypes() {
    return {
      isLoggedIn: PropTypes.bool,
      logIn: PropTypes.func,
      logOut: PropTypes.func,
    };
  }

  /**
   * render
   * @return {ReactElement} markup
   */
  render() {
    return (
      <LoginButton
        isLoggedIn={this.props.isLoggedIn}
        onLogIn={this.props.logIn}
        onLogOut={this.props.logOut}
      />
    );
  }
}
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2015-2019 Mailvelope GmbH
 * Licensed under the GNU Affero General Public License version 3
 */

import mvelo from '../lib/lib-mvelo';
import {getHash, mapError} from '../lib/util';
import * as gmail from '../modules/gmail';
import * as sub from './sub.controller';
import {getPreferredKeyringId} from '../modules/keyring';

export default class GmailController extends sub.SubController {
  constructor(port) {
    super(port);
    if (!port) {
      this.mainType = 'gmailInt';
      this.id = getHash();
    }
    this.editorControl = null;
    this.keyringId = getPreferredKeyringId();
    this.currentAction = null;
    // register event handlers
    this.on('gmail-unauthorize', this.unauthorize);
    this.on('open-editor', this.onOpenEditor);
    this.on('secure-reply', this.onSecureReply);
    this.on('secure-forward', this.onSecureForward);
  }

  activateComponent() {
    mvelo.tabs.activate({id: this.tabId});
  }

  unauthorize() {
    gmail.unauthorize();
  }

  /**
   * Opens a new editor control and gets the recipients to encrypt plaintext
   * input to their public keys.
   * @param  {String} options.text   The plaintext input to encrypt
   */

  openEditor(options) {
    if (this.editorControl) {
      this.editorControl.activateComponent();
      return;
    }
    this.editorControl = sub.factory.get('editor');
    return this.editorControl.encrypt({
      integration: true,
      predefinedText: options.text,
      quotedMail: options.quotedMail,
      quotedMailIndent: options.quotedMailIndent === undefined ? true : options.quotedMailIndent,
      quotedMailHeader: options.quotedMailHeader,
      subject: options.subject,
      getRecipients: () => options.recipients ? options.recipients.map(email => ({email})) : [],
      userEmail: options.userEmail,
      attachments: options.attachments,
      keepAttachments: options.keepAttachments || false
    });
  }

  async onOpenEditor(options, accessToken) {
    try {
      options.recipientsTo = options.recipientsTo || [];
      options.recipientsCc = options.recipientsCc || [];
      options.recipients = [...options.recipientsTo, ...options.recipientsCc];
      const {armored, encFiles, subject, recipients} = await this.openEditor(options);
      // send email via GMAIL api
      const userEmail = options.userEmail;
      let to = recipients.map(({email}) => email);
      let cc = [];
      if (options.recipientsCc.length) {
        cc = to.filter(email => options.recipientsCc.includes(email));
        to = to.filter(email => !cc.includes(email));
      }
      const mail = gmail.buildMail({message: armored, attachments: encFiles, subject, sender: userEmail, to, cc});
      const scopes = [gmail.GMAIL_SCOPE_READONLY, gmail.GMAIL_SCOPE_SEND];
      if (!accessToken) {
        accessToken = await gmail.getAccessToken(userEmail, scopes);
      }
      if (!accessToken) {
        this.editorControl.openAuthorizeDialog(scopes);
      } else {
        const sendOptions = {
          email: userEmail,
          message: mail,
          accessToken
        };
        if (options.threadId) {
          sendOptions.threadId = options.threadId;
        }
        const {error} = await gmail.sendMessageMeta(sendOptions);
        if (!error) {
          this.editorControl.ports.editor.emit('show-notification', {
            message: 'gmail_integration_sent_success',
            type: 'success',
            autoHide: true,
            hideDelay: 2000,
            closeOnHide: true,
            dismissable: false
          });
        } else {
          this.editorControl.ports.editor.emit('error-message', {
            error: {
              code: error.code,
              message: error.message,
              autoHide: false,
              dismissable: false
            }
          });
        }
        this.editorControl = null;
      }
    } catch (err) {
      if (err.code == 'EDITOR_DIALOG_CANCEL') {
        this.editorControl = null;
        return;
      }
      this.editorControl.ports.editor.emit('error-message', {error: mapError(err)});
    }
  }

  async onSecureReply({msgId, all, userEmail}) {
    const scopes = [gmail.GMAIL_SCOPE_READONLY, gmail.GMAIL_SCOPE_SEND];
    const accessToken = await gmail.getAccessToken(userEmail, scopes);
    if (!accessToken) {
      if (!this.tabId) {
        const {id} = await mvelo.tabs.getActive();
        this.tabId = id;
      }
      this.currentAction = {type: 'reply', msgId, all, userEmail};
      gmail.openAuthorizeDialog({email: userEmail, scopes, ctrlId: this.id});
      return;
    }
    const {threadId, internalDate, payload} = await gmail.getMessage({msgId, email: userEmail, accessToken});
    const messageText = await gmail.extractMailBody({payload, userEmail, msgId, accessToken});
    const subject = gmail.extractMailHeader(payload, 'Subject');
    const recipientsTo = [];
    const recipientsCc = [];
    const sender = gmail.extractMailFromAddress(gmail.extractMailHeader(payload, 'From'));
    recipientsTo.push(sender);
    if (all) {
      const to = gmail.extractMailHeader(payload, 'To').split(',');
      to.map(address => gmail.extractMailFromAddress(address)).filter(email => email !== '').forEach(email => recipientsTo.push(email));
      const cc = gmail.extractMailHeader(payload, 'Cc').split(',');
      if (cc) {
        cc.map(address => gmail.extractMailFromAddress(address)).filter(email => email !== '').forEach(email => recipientsCc.push(email));
      }
    }
    const quotedMailHeader = `On ${new Date(parseInt(internalDate, 10)).toUTCString()}, <${gmail.extractMailFromAddress(sender)}> wrote:`;
    const options = {
      userEmail,
      subject: `Re: ${subject}`,
      recipientsTo,
      recipientsCc,
      threadId,
      // recipients: [...recipientsTo, ...recipientsCc],
      quotedMailHeader,
      quotedMail: messageText || '',
    };
    this.onOpenEditor(options, accessToken);
  }

  async onSecureForward({msgId, userEmail}) {
    const scopes = [gmail.GMAIL_SCOPE_READONLY, gmail.GMAIL_SCOPE_SEND];
    const accessToken = await gmail.getAccessToken(userEmail, scopes);
    if (!accessToken) {
      if (!this.tabId) {
        const {id} = await mvelo.tabs.getActive();
        this.tabId = id;
      }
      this.currentAction = {type: 'forward', msgId, userEmail};
      gmail.openAuthorizeDialog({email: userEmail, scopes, ctrlId: this.id});
      return;
    }
    const {threadId, internalDate, payload} = await gmail.getMessage({msgId, email: userEmail, accessToken});
    const messageText = await gmail.extractMailBody({payload, userEmail, msgId, accessToken});
    const subject = gmail.extractMailHeader(payload, 'Subject');
    // const sentDate = this.extractMailHeader(payload, 'Date');
    const sender = gmail.extractMailHeader(payload, 'From');
    const to = gmail.extractMailHeader(payload, 'To');
    const cc = gmail.extractMailHeader(payload, 'Cc');
    const quotedMailHeader = `---------- Forwarded message ---------
From: <${gmail.extractMailFromAddress(sender)}>
Date: ${new Date(parseInt(internalDate, 10)).toUTCString()}
Subject: ${subject}
To: ${to.split(',').map(address => `<${gmail.extractMailFromAddress(address)}>`).join(', ')}
${cc && `Cc: ${to.split(',').map(address => `<${gmail.extractMailFromAddress(address)}>`).join(', ')}`}
`;
    const attachments = await gmail.getMailAttachments({payload, userEmail, msgId, accessToken});
    const options = {
      userEmail,
      subject: `Fwd: ${subject}`,
      threadId,
      quotedMail: messageText || '',
      quotedMailIndent: false,
      quotedMailHeader,
      attachments,
      keepAttachments: true
    };
    this.onOpenEditor(options, accessToken);
  }

  async onAuthorize({email, scopes}) {
    try {
      await gmail.authorize(email, scopes);
      if (this.currentAction) {
        if (this.currentAction.type === 'reply') {
          this.onSecureReply(this.currentAction);
        } else if (this.currentAction.type === 'forward') {
          this.onSecureForward(this.currentAction);
        }
        this.currentAction = null;
      }
    } catch (e) {
      console.log(e);
    }
    this.activateComponent();
  }
}
<commit_msg>Fix bug in gmail integration editor does not refresh access token before sending<commit_after>/**
 * Copyright (C) 2015-2019 Mailvelope GmbH
 * Licensed under the GNU Affero General Public License version 3
 */

import mvelo from '../lib/lib-mvelo';
import {getHash, mapError} from '../lib/util';
import * as gmail from '../modules/gmail';
import * as sub from './sub.controller';
import {getPreferredKeyringId} from '../modules/keyring';

export default class GmailController extends sub.SubController {
  constructor(port) {
    super(port);
    if (!port) {
      this.mainType = 'gmailInt';
      this.id = getHash();
    }
    this.editorControl = null;
    this.keyringId = getPreferredKeyringId();
    this.currentAction = null;
    // register event handlers
    this.on('gmail-unauthorize', this.unauthorize);
    this.on('open-editor', this.onOpenEditor);
    this.on('secure-reply', this.onSecureReply);
    this.on('secure-forward', this.onSecureForward);
  }

  activateComponent() {
    mvelo.tabs.activate({id: this.tabId});
  }

  unauthorize() {
    gmail.unauthorize();
  }

  /**
   * Opens a new editor control and gets the recipients to encrypt plaintext
   * input to their public keys.
   * @param  {String} options.text   The plaintext input to encrypt
   */

  openEditor(options) {
    if (this.editorControl) {
      this.editorControl.activateComponent();
      return;
    }
    this.editorControl = sub.factory.get('editor');
    return this.editorControl.encrypt({
      integration: true,
      predefinedText: options.text,
      quotedMail: options.quotedMail,
      quotedMailIndent: options.quotedMailIndent === undefined ? true : options.quotedMailIndent,
      quotedMailHeader: options.quotedMailHeader,
      subject: options.subject,
      getRecipients: () => options.recipients ? options.recipients.map(email => ({email})) : [],
      userEmail: options.userEmail,
      attachments: options.attachments,
      keepAttachments: options.keepAttachments || false
    });
  }

  async onOpenEditor(options) {
    try {
      options.recipientsTo = options.recipientsTo || [];
      options.recipientsCc = options.recipientsCc || [];
      options.recipients = [...options.recipientsTo, ...options.recipientsCc];
      const {armored, encFiles, subject, recipients} = await this.openEditor(options);
      // send email via GMAIL api
      const userEmail = options.userEmail;
      let to = recipients.map(({email}) => email);
      let cc = [];
      if (options.recipientsCc.length) {
        cc = to.filter(email => options.recipientsCc.includes(email));
        to = to.filter(email => !cc.includes(email));
      }
      const mail = gmail.buildMail({message: armored, attachments: encFiles, subject, sender: userEmail, to, cc});
      const scopes = [gmail.GMAIL_SCOPE_READONLY, gmail.GMAIL_SCOPE_SEND];
      const accessToken = await gmail.getAccessToken(userEmail, scopes);
      if (!accessToken) {
        this.editorControl.openAuthorizeDialog(scopes);
      } else {
        const sendOptions = {
          email: userEmail,
          message: mail,
          accessToken
        };
        if (options.threadId) {
          sendOptions.threadId = options.threadId;
        }
        const {error} = await gmail.sendMessageMeta(sendOptions);
        if (!error) {
          this.editorControl.ports.editor.emit('show-notification', {
            message: 'gmail_integration_sent_success',
            type: 'success',
            autoHide: true,
            hideDelay: 2000,
            closeOnHide: true,
            dismissable: false
          });
        } else {
          this.editorControl.ports.editor.emit('error-message', {
            error: {
              code: error.code,
              message: error.message,
              autoHide: false,
              dismissable: true
            }
          });
        }
        this.editorControl = null;
      }
    } catch (err) {
      if (err.code == 'EDITOR_DIALOG_CANCEL') {
        this.editorControl = null;
        return;
      }
      this.editorControl.ports.editor.emit('error-message', {error: mapError(err)});
    }
  }

  async onSecureReply({msgId, all, userEmail}) {
    const scopes = [gmail.GMAIL_SCOPE_READONLY, gmail.GMAIL_SCOPE_SEND];
    const accessToken = await gmail.getAccessToken(userEmail, scopes);
    if (!accessToken) {
      if (!this.tabId) {
        const {id} = await mvelo.tabs.getActive();
        this.tabId = id;
      }
      this.currentAction = {type: 'reply', msgId, all, userEmail};
      gmail.openAuthorizeDialog({email: userEmail, scopes, ctrlId: this.id});
      return;
    }
    const {threadId, internalDate, payload} = await gmail.getMessage({msgId, email: userEmail, accessToken});
    const messageText = await gmail.extractMailBody({payload, userEmail, msgId, accessToken});
    const subject = gmail.extractMailHeader(payload, 'Subject');
    const recipientsTo = [];
    const recipientsCc = [];
    const sender = gmail.extractMailFromAddress(gmail.extractMailHeader(payload, 'From'));
    recipientsTo.push(sender);
    if (all) {
      const to = gmail.extractMailHeader(payload, 'To').split(',');
      to.map(address => gmail.extractMailFromAddress(address)).filter(email => email !== '').forEach(email => recipientsTo.push(email));
      const cc = gmail.extractMailHeader(payload, 'Cc').split(',');
      if (cc) {
        cc.map(address => gmail.extractMailFromAddress(address)).filter(email => email !== '').forEach(email => recipientsCc.push(email));
      }
    }
    const quotedMailHeader = `On ${new Date(parseInt(internalDate, 10)).toUTCString()}, <${gmail.extractMailFromAddress(sender)}> wrote:`;
    const options = {
      userEmail,
      subject: `Re: ${subject}`,
      recipientsTo,
      recipientsCc,
      threadId,
      // recipients: [...recipientsTo, ...recipientsCc],
      quotedMailHeader,
      quotedMail: messageText || '',
    };
    this.onOpenEditor(options);
  }

  async onSecureForward({msgId, userEmail}) {
    const scopes = [gmail.GMAIL_SCOPE_READONLY, gmail.GMAIL_SCOPE_SEND];
    const accessToken = await gmail.getAccessToken(userEmail, scopes);
    if (!accessToken) {
      if (!this.tabId) {
        const {id} = await mvelo.tabs.getActive();
        this.tabId = id;
      }
      this.currentAction = {type: 'forward', msgId, userEmail};
      gmail.openAuthorizeDialog({email: userEmail, scopes, ctrlId: this.id});
      return;
    }
    const {threadId, internalDate, payload} = await gmail.getMessage({msgId, email: userEmail, accessToken});
    const messageText = await gmail.extractMailBody({payload, userEmail, msgId, accessToken});
    const subject = gmail.extractMailHeader(payload, 'Subject');
    // const sentDate = this.extractMailHeader(payload, 'Date');
    const sender = gmail.extractMailHeader(payload, 'From');
    const to = gmail.extractMailHeader(payload, 'To');
    const cc = gmail.extractMailHeader(payload, 'Cc');
    const quotedMailHeader = `---------- Forwarded message ---------
From: <${gmail.extractMailFromAddress(sender)}>
Date: ${new Date(parseInt(internalDate, 10)).toUTCString()}
Subject: ${subject}
To: ${to.split(',').map(address => `<${gmail.extractMailFromAddress(address)}>`).join(', ')}
${cc && `Cc: ${to.split(',').map(address => `<${gmail.extractMailFromAddress(address)}>`).join(', ')}`}
`;
    const attachments = await gmail.getMailAttachments({payload, userEmail, msgId, accessToken});
    const options = {
      userEmail,
      subject: `Fwd: ${subject}`,
      threadId,
      quotedMail: messageText || '',
      quotedMailIndent: false,
      quotedMailHeader,
      attachments,
      keepAttachments: true
    };
    this.onOpenEditor(options);
  }

  async onAuthorize({email, scopes}) {
    try {
      await gmail.authorize(email, scopes);
      if (this.currentAction) {
        if (this.currentAction.type === 'reply') {
          this.onSecureReply(this.currentAction);
        } else if (this.currentAction.type === 'forward') {
          this.onSecureForward(this.currentAction);
        }
        this.currentAction = null;
      }
    } catch (e) {
      console.log(e);
    }
    this.activateComponent();
  }
}
<|endoftext|>


<commit_before>/**
 * @author Kris Occhipinti <A.K.A. Metalx1000>/ http://filmsbykris.com/
 * @code https://github.com/metalx1000/metal_bullets
 * @license http://www.gnu.org/licenses/gpl-3.0.html
 */

/////////////////Audio/////////////////////////////

//music
var Load_Music = function ( sources, volume ) {
    this.source = document.createElement( 'source' );
    this.vol = volume;

    this.audio = document.createElement( 'audio' );

        console.log("Loading Music...");
        for ( var i = 0; i < sources.length; i ++ ) {

                    this.source.src = sources[ i ];
                    this.audio.volume=this.vol;

                    this.audio.appendChild( this.source );
                    this.audio.play();
        }

    this.play = function () {
       this.audio.play();
    }

    this.pause = function(){
        this.audio.pause();
    }

    this.load = function(sources){
                    console.log("Loading Music...");
        for ( var i = 0; i < sources.length; i ++ ) {
                    this.source.src = sources[ i ];

                    this. audio.appendChild( this.source );
                    this.audio.src = this.source.src;
                    this.audio.load();
                    this.audio.play();
        }
        console.log("Loading Music...");
    }
}

//sounds
var Sound = function ( sources, radius, volume ) {

                var audio = document.createElement( 'audio' );

                for ( var i = 0; i < sources.length; i ++ ) {

                    var source = document.createElement( 'source' );
                    source.src = sources[ i ];

                    audio.appendChild( source );

                }

//                this.position = new THREE.Vector3();

                this.play = function () {

                    audio.play();

                }

                this.update = function ( camera ) {

                    var distance = this.position.distanceTo( camera.position );

                    if ( distance <= radius ) {

                        audio.volume = volume * ( 1 - distance / radius );

                    } else {

                        audio.volume = 0;

                    }

                }

}

//Fullscreen and Mouse Cursor Grab
function go_fullscreen()
{
            var instructions = document;

            // http://www.html5rocks.com/en/tutorials/pointerlock/intro/

            var havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;

            if ( havePointerLock ) {

                var element = document.body;
                instructions.addEventListener( 'click', function ( event ) {

//                    instructions.style.display = 'none';

                    // Ask the browser to lock the pointer
                    element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;

                    if ( /Firefox/i.test( navigator.userAgent ) ) {

                        var fullscreenchange = function ( event ) {

                            if ( document.fullscreenElement === element || document.mozFullscreenElement === element || document.mozFullScreenElement === element ) {

                                document.removeEventListener( 'fullscreenchange', fullscreenchange );
                                document.removeEventListener( 'mozfullscreenchange', fullscreenchange );

                                element.requestPointerLock();
                            }

                        }

                        document.addEventListener( 'fullscreenchange', fullscreenchange, false );
                        document.addEventListener( 'mozfullscreenchange', fullscreenchange, false );

                        element.requestFullscreen = element.requestFullscreen || element.mozRequestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen;

                        element.requestFullscreen();

                    } else {

                        element.requestPointerLock();

                    }

                }, false );

            } else {

                instructions.innerHTML = 'Your browser doesn\'t seem to support Pointer Lock API';

            }
}
<commit_msg>Added Volume Control for Music<commit_after>/**
 * @author Kris Occhipinti <A.K.A. Metalx1000>/ http://filmsbykris.com/
 * @code https://github.com/metalx1000/metal_bullets
 * @license http://www.gnu.org/licenses/gpl-3.0.html
 */

/////////////////Audio/////////////////////////////

//music
var Load_Music = function ( sources, volume ) {
    this.source = document.createElement( 'source' );
    this.vol = volume;

    this.audio = document.createElement( 'audio' );

        console.log("Loading Music...");
        for ( var i = 0; i < sources.length; i ++ ) {

                    this.source.src = sources[ i ];
                    this.audio.volume=this.vol;

                    this.audio.appendChild( this.source );
                    this.audio.play();
        }

    this.play = function () {
       this.audio.play();
    }

    this.pause = function(){
        this.audio.pause();
    }

    this.set_vol = function(vol){
        if(vol > 1 || vol < 0){
            console.log("volume must be between 0 and 1");
        }else{
            this.vol = vol;
            this.audio.volume=this.vol;
            console.log("Volume is set to " + this.vol * 100 + "%")
        }
    }

    this.load = function(sources){
                    console.log("Loading Music...");
        for ( var i = 0; i < sources.length; i ++ ) {
                    this.source.src = sources[ i ];

                    this. audio.appendChild( this.source );
                    this.audio.src = this.source.src;
                    this.audio.load();
                    this.audio.play();
        }
        console.log("Loading Music...");
    }
}

//sounds
var Sound = function ( sources, radius, volume ) {

                var audio = document.createElement( 'audio' );

                for ( var i = 0; i < sources.length; i ++ ) {

                    var source = document.createElement( 'source' );
                    source.src = sources[ i ];

                    audio.appendChild( source );

                }

//                this.position = new THREE.Vector3();

                this.play = function () {

                    audio.play();

                }

                this.update = function ( camera ) {

                    var distance = this.position.distanceTo( camera.position );

                    if ( distance <= radius ) {

                        audio.volume = volume * ( 1 - distance / radius );

                    } else {

                        audio.volume = 0;

                    }

                }

}

//Fullscreen and Mouse Cursor Grab
function go_fullscreen()
{
            var instructions = document;

            // http://www.html5rocks.com/en/tutorials/pointerlock/intro/

            var havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;

            if ( havePointerLock ) {

                var element = document.body;
                instructions.addEventListener( 'click', function ( event ) {

//                    instructions.style.display = 'none';

                    // Ask the browser to lock the pointer
                    element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;

                    if ( /Firefox/i.test( navigator.userAgent ) ) {

                        var fullscreenchange = function ( event ) {

                            if ( document.fullscreenElement === element || document.mozFullscreenElement === element || document.mozFullScreenElement === element ) {

                                document.removeEventListener( 'fullscreenchange', fullscreenchange );
                                document.removeEventListener( 'mozfullscreenchange', fullscreenchange );

                                element.requestPointerLock();
                            }

                        }

                        document.addEventListener( 'fullscreenchange', fullscreenchange, false );
                        document.addEventListener( 'mozfullscreenchange', fullscreenchange, false );

                        element.requestFullscreen = element.requestFullscreen || element.mozRequestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen;

                        element.requestFullscreen();

                    } else {

                        element.requestPointerLock();

                    }

                }, false );

            } else {

                instructions.innerHTML = 'Your browser doesn\'t seem to support Pointer Lock API';

            }
}
<|endoftext|>


<commit_before>'use strict';

var helpers = require('../helpers/index');

var resolve = helpers.options.resolve;

var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];

/**
 * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
 * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
 * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
 */
function listenArrayEvents(array, listener) {
	if (array._chartjs) {
		array._chartjs.listeners.push(listener);
		return;
	}

	Object.defineProperty(array, '_chartjs', {
		configurable: true,
		enumerable: false,
		value: {
			listeners: [listener]
		}
	});

	arrayEvents.forEach(function(key) {
		var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
		var base = array[key];

		Object.defineProperty(array, key, {
			configurable: true,
			enumerable: false,
			value: function() {
				var args = Array.prototype.slice.call(arguments);
				var res = base.apply(this, args);

				helpers.each(array._chartjs.listeners, function(object) {
					if (typeof object[method] === 'function') {
						object[method].apply(object, args);
					}
				});

				return res;
			}
		});
	});
}

/**
 * Removes the given array event listener and cleanup extra attached properties (such as
 * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
 */
function unlistenArrayEvents(array, listener) {
	var stub = array._chartjs;
	if (!stub) {
		return;
	}

	var listeners = stub.listeners;
	var index = listeners.indexOf(listener);
	if (index !== -1) {
		listeners.splice(index, 1);
	}

	if (listeners.length > 0) {
		return;
	}

	arrayEvents.forEach(function(key) {
		delete array[key];
	});

	delete array._chartjs;
}

// Base class for all dataset controllers (line, bar, etc)
var DatasetController = function(chart, datasetIndex) {
	this.initialize(chart, datasetIndex);
};

helpers.extend(DatasetController.prototype, {

	/**
	 * Element type used to generate a meta dataset (e.g. Chart.element.Line).
	 * @type {Chart.core.element}
	 */
	datasetElementType: null,

	/**
	 * Element type used to generate a meta data (e.g. Chart.element.Point).
	 * @type {Chart.core.element}
	 */
	dataElementType: null,

	initialize: function(chart, datasetIndex) {
		var me = this;
		me.chart = chart;
		me.index = datasetIndex;
		me.linkScales();
		me.addElements();
	},

	updateIndex: function(datasetIndex) {
		this.index = datasetIndex;
	},

	linkScales: function() {
		var me = this;
		var meta = me.getMeta();
		var dataset = me.getDataset();

		if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) {
			meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
		}
		if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) {
			meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
		}
	},

	getDataset: function() {
		return this.chart.data.datasets[this.index];
	},

	getMeta: function() {
		return this.chart.getDatasetMeta(this.index);
	},

	getScaleForId: function(scaleID) {
		return this.chart.scales[scaleID];
	},

	/**
	 * @private
	 */
	_getValueScaleId: function() {
		return this.getMeta().yAxisID;
	},

	/**
	 * @private
	 */
	_getIndexScaleId: function() {
		return this.getMeta().xAxisID;
	},

	/**
	 * @private
	 */
	_getValueScale: function() {
		return this.getScaleForId(this._getValueScaleId());
	},

	/**
	 * @private
	 */
	_getIndexScale: function() {
		return this.getScaleForId(this._getIndexScaleId());
	},

	reset: function() {
		this.update(true);
	},

	/**
	 * @private
	 */
	destroy: function() {
		if (this._data) {
			unlistenArrayEvents(this._data, this);
		}
	},

	createMetaDataset: function() {
		var me = this;
		var type = me.datasetElementType;
		return type && new type({
			_chart: me.chart,
			_datasetIndex: me.index
		});
	},

	createMetaData: function(index) {
		var me = this;
		var type = me.dataElementType;
		return type && new type({
			_chart: me.chart,
			_datasetIndex: me.index,
			_index: index
		});
	},

	addElements: function() {
		var me = this;
		var meta = me.getMeta();
		var data = me.getDataset().data || [];
		var metaData = meta.data;
		var i, ilen;

		for (i = 0, ilen = data.length; i < ilen; ++i) {
			metaData[i] = metaData[i] || me.createMetaData(i);
		}

		meta.dataset = meta.dataset || me.createMetaDataset();
	},

	addElementAndReset: function(index) {
		var element = this.createMetaData(index);
		this.getMeta().data.splice(index, 0, element);
		this.updateElement(element, index, true);
	},

	buildOrUpdateElements: function() {
		var me = this;
		var dataset = me.getDataset();
		var data = dataset.data || (dataset.data = []);

		// In order to correctly handle data addition/deletion animation (an thus simulate
		// real-time charts), we need to monitor these data modifications and synchronize
		// the internal meta data accordingly.
		if (me._data !== data) {
			if (me._data) {
				// This case happens when the user replaced the data array instance.
				unlistenArrayEvents(me._data, me);
			}

			listenArrayEvents(data, me);
			me._data = data;
		}

		// Re-sync meta data in case the user replaced the data array or if we missed
		// any updates and so make sure that we handle number of datapoints changing.
		me.resyncElements();
	},

	update: helpers.noop,

	transition: function(easingValue) {
		var meta = this.getMeta();
		var elements = meta.data || [];
		var ilen = elements.length;
		var i = 0;

		for (; i < ilen; ++i) {
			elements[i].transition(easingValue);
		}

		if (meta.dataset) {
			meta.dataset.transition(easingValue);
		}
	},

	draw: function() {
		var meta = this.getMeta();
		var elements = meta.data || [];
		var ilen = elements.length;
		var i = 0;

		if (meta.dataset) {
			meta.dataset.draw();
		}

		for (; i < ilen; ++i) {
			elements[i].draw();
		}
	},

	removeHoverStyle: function(element) {
		helpers.merge(element._model, element.$previousStyle || {});
		delete element.$previousStyle;
	},

	setHoverStyle: function(element) {
		var dataset = this.chart.data.datasets[element._datasetIndex];
		var index = element._index;
		var custom = element.custom || {};
		var model = element._model;
		var getHoverColor = helpers.getHoverColor;

		element.$previousStyle = {
			backgroundColor: model.backgroundColor,
			borderColor: model.borderColor,
			borderWidth: model.borderWidth
		};

		model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index);
		model.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index);
		model.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index);
	},

	/**
	 * @private
	 */
	resyncElements: function() {
		var me = this;
		var meta = me.getMeta();
		var data = me.getDataset().data;
		var numMeta = meta.data.length;
		var numData = data.length;

		if (numData < numMeta) {
			meta.data.splice(numData, numMeta - numData);
		} else if (numData > numMeta) {
			me.insertElements(numMeta, numData - numMeta);
		}
	},

	/**
	 * @private
	 */
	insertElements: function(start, count) {
		for (var i = 0; i < count; ++i) {
			this.addElementAndReset(start + i);
		}
	},

	/**
	 * @private
	 */
	onDataPush: function() {
		this.insertElements(this.getDataset().data.length - 1, arguments.length);
	},

	/**
	 * @private
	 */
	onDataPop: function() {
		this.getMeta().data.pop();
	},

	/**
	 * @private
	 */
	onDataShift: function() {
		this.getMeta().data.shift();
	},

	/**
	 * @private
	 */
	onDataSplice: function(start, count) {
		this.getMeta().data.splice(start, count);
		this.insertElements(start, arguments.length - 2);
	},

	/**
	 * @private
	 */
	onDataUnshift: function() {
		this.insertElements(0, arguments.length);
	}
});

DatasetController.extend = helpers.inherits;

module.exports = DatasetController;
<commit_msg>Supply correct start param for insertElements in onDataPush (#6008)<commit_after>'use strict';

var helpers = require('../helpers/index');

var resolve = helpers.options.resolve;

var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];

/**
 * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
 * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
 * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
 */
function listenArrayEvents(array, listener) {
	if (array._chartjs) {
		array._chartjs.listeners.push(listener);
		return;
	}

	Object.defineProperty(array, '_chartjs', {
		configurable: true,
		enumerable: false,
		value: {
			listeners: [listener]
		}
	});

	arrayEvents.forEach(function(key) {
		var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
		var base = array[key];

		Object.defineProperty(array, key, {
			configurable: true,
			enumerable: false,
			value: function() {
				var args = Array.prototype.slice.call(arguments);
				var res = base.apply(this, args);

				helpers.each(array._chartjs.listeners, function(object) {
					if (typeof object[method] === 'function') {
						object[method].apply(object, args);
					}
				});

				return res;
			}
		});
	});
}

/**
 * Removes the given array event listener and cleanup extra attached properties (such as
 * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
 */
function unlistenArrayEvents(array, listener) {
	var stub = array._chartjs;
	if (!stub) {
		return;
	}

	var listeners = stub.listeners;
	var index = listeners.indexOf(listener);
	if (index !== -1) {
		listeners.splice(index, 1);
	}

	if (listeners.length > 0) {
		return;
	}

	arrayEvents.forEach(function(key) {
		delete array[key];
	});

	delete array._chartjs;
}

// Base class for all dataset controllers (line, bar, etc)
var DatasetController = function(chart, datasetIndex) {
	this.initialize(chart, datasetIndex);
};

helpers.extend(DatasetController.prototype, {

	/**
	 * Element type used to generate a meta dataset (e.g. Chart.element.Line).
	 * @type {Chart.core.element}
	 */
	datasetElementType: null,

	/**
	 * Element type used to generate a meta data (e.g. Chart.element.Point).
	 * @type {Chart.core.element}
	 */
	dataElementType: null,

	initialize: function(chart, datasetIndex) {
		var me = this;
		me.chart = chart;
		me.index = datasetIndex;
		me.linkScales();
		me.addElements();
	},

	updateIndex: function(datasetIndex) {
		this.index = datasetIndex;
	},

	linkScales: function() {
		var me = this;
		var meta = me.getMeta();
		var dataset = me.getDataset();

		if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) {
			meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
		}
		if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) {
			meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
		}
	},

	getDataset: function() {
		return this.chart.data.datasets[this.index];
	},

	getMeta: function() {
		return this.chart.getDatasetMeta(this.index);
	},

	getScaleForId: function(scaleID) {
		return this.chart.scales[scaleID];
	},

	/**
	 * @private
	 */
	_getValueScaleId: function() {
		return this.getMeta().yAxisID;
	},

	/**
	 * @private
	 */
	_getIndexScaleId: function() {
		return this.getMeta().xAxisID;
	},

	/**
	 * @private
	 */
	_getValueScale: function() {
		return this.getScaleForId(this._getValueScaleId());
	},

	/**
	 * @private
	 */
	_getIndexScale: function() {
		return this.getScaleForId(this._getIndexScaleId());
	},

	reset: function() {
		this.update(true);
	},

	/**
	 * @private
	 */
	destroy: function() {
		if (this._data) {
			unlistenArrayEvents(this._data, this);
		}
	},

	createMetaDataset: function() {
		var me = this;
		var type = me.datasetElementType;
		return type && new type({
			_chart: me.chart,
			_datasetIndex: me.index
		});
	},

	createMetaData: function(index) {
		var me = this;
		var type = me.dataElementType;
		return type && new type({
			_chart: me.chart,
			_datasetIndex: me.index,
			_index: index
		});
	},

	addElements: function() {
		var me = this;
		var meta = me.getMeta();
		var data = me.getDataset().data || [];
		var metaData = meta.data;
		var i, ilen;

		for (i = 0, ilen = data.length; i < ilen; ++i) {
			metaData[i] = metaData[i] || me.createMetaData(i);
		}

		meta.dataset = meta.dataset || me.createMetaDataset();
	},

	addElementAndReset: function(index) {
		var element = this.createMetaData(index);
		this.getMeta().data.splice(index, 0, element);
		this.updateElement(element, index, true);
	},

	buildOrUpdateElements: function() {
		var me = this;
		var dataset = me.getDataset();
		var data = dataset.data || (dataset.data = []);

		// In order to correctly handle data addition/deletion animation (an thus simulate
		// real-time charts), we need to monitor these data modifications and synchronize
		// the internal meta data accordingly.
		if (me._data !== data) {
			if (me._data) {
				// This case happens when the user replaced the data array instance.
				unlistenArrayEvents(me._data, me);
			}

			listenArrayEvents(data, me);
			me._data = data;
		}

		// Re-sync meta data in case the user replaced the data array or if we missed
		// any updates and so make sure that we handle number of datapoints changing.
		me.resyncElements();
	},

	update: helpers.noop,

	transition: function(easingValue) {
		var meta = this.getMeta();
		var elements = meta.data || [];
		var ilen = elements.length;
		var i = 0;

		for (; i < ilen; ++i) {
			elements[i].transition(easingValue);
		}

		if (meta.dataset) {
			meta.dataset.transition(easingValue);
		}
	},

	draw: function() {
		var meta = this.getMeta();
		var elements = meta.data || [];
		var ilen = elements.length;
		var i = 0;

		if (meta.dataset) {
			meta.dataset.draw();
		}

		for (; i < ilen; ++i) {
			elements[i].draw();
		}
	},

	removeHoverStyle: function(element) {
		helpers.merge(element._model, element.$previousStyle || {});
		delete element.$previousStyle;
	},

	setHoverStyle: function(element) {
		var dataset = this.chart.data.datasets[element._datasetIndex];
		var index = element._index;
		var custom = element.custom || {};
		var model = element._model;
		var getHoverColor = helpers.getHoverColor;

		element.$previousStyle = {
			backgroundColor: model.backgroundColor,
			borderColor: model.borderColor,
			borderWidth: model.borderWidth
		};

		model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index);
		model.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index);
		model.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index);
	},

	/**
	 * @private
	 */
	resyncElements: function() {
		var me = this;
		var meta = me.getMeta();
		var data = me.getDataset().data;
		var numMeta = meta.data.length;
		var numData = data.length;

		if (numData < numMeta) {
			meta.data.splice(numData, numMeta - numData);
		} else if (numData > numMeta) {
			me.insertElements(numMeta, numData - numMeta);
		}
	},

	/**
	 * @private
	 */
	insertElements: function(start, count) {
		for (var i = 0; i < count; ++i) {
			this.addElementAndReset(start + i);
		}
	},

	/**
	 * @private
	 */
	onDataPush: function() {
		var count = arguments.length;
		this.insertElements(this.getDataset().data.length - count, count);
	},

	/**
	 * @private
	 */
	onDataPop: function() {
		this.getMeta().data.pop();
	},

	/**
	 * @private
	 */
	onDataShift: function() {
		this.getMeta().data.shift();
	},

	/**
	 * @private
	 */
	onDataSplice: function(start, count) {
		this.getMeta().data.splice(start, count);
		this.insertElements(start, arguments.length - 2);
	},

	/**
	 * @private
	 */
	onDataUnshift: function() {
		this.insertElements(0, arguments.length);
	}
});

DatasetController.extend = helpers.inherits;

module.exports = DatasetController;
<|endoftext|>


<commit_before>;(function (window, document, undefined)
{ 'use strict';

    var peer = new Peer({ key: 'w19j6rp47wx9a4i' });
})(window, document);
<commit_msg>Adding initialization of PeerJS conneciton.<commit_after>;(function (window, document, undefined)
{ 'use strict';

    var SHARE_URL_ID = 'share-url';
    var PEERJS_API_KEY = 'w19j6rp47wx9a4i';

    var peer = new Peer({ key: PEERJS_API_KEY });

    peer.on('open', function (id)
    {
        document.getElementById(SHARE_URL_ID).value = window.location.href;
    });
})(window, document);
<|endoftext|>