<commit_before>import { connect } from 'react-redux'
import { List } from '@twreporter/react-components/lib/listing-page'
import categoryConst from '../constants/category'
import dataLoaderConst from '../constants/data-loaders'
import Helmet from 'react-helmet'
import loggerFactory from '../logger'
import Pagination from '../components/Pagination'
import PropTypes from 'prop-types'
import querystring from 'querystring'
import React, { PureComponent } from 'react'
import SystemError from '../components/SystemError'
import siteMeta from '../constants/site-meta'
import twreporterRedux from '@twreporter/redux'

// utils
import cloneUtils from '../utils/shallow-clone-entity'

// lodash
import forEach from 'lodash/forEach'
import get from 'lodash/get'

const _ = {
  forEach,
  get,
}

const { actions, reduxStateFields, utils } = twreporterRedux
const { fetchPostsByCategoryListId } = actions
const logger = loggerFactory.getLogger()

class Category extends PureComponent {
  componentDidMount() {
    this.fetchPostsWithCatch()
  }

  componentDidUpdate(prevProps) {
    if (this.props.catId !== prevProps.catId ||
      this.props.page !== prevProps.page
    ) {
      this.fetchPostsWithCatch()
    }
  }

  fetchPostsWithCatch() {
    const {
      catId,
      fetchPostsByCategoryListId,
      nPerPage,
      page,
    } = this.props

    fetchPostsByCategoryListId(catId, nPerPage, page)
      .catch((failAction) => {
        logger.errorReport({
          report: _.get(failAction, 'payload.error'),
          message: `Error to fetch posts (category id: '${catId}', page: ${page}, nPerPage: ${nPerPage}).`
        })
      })
  }

  render() {
    const {
      catLabel,
      error,
      isFetching,
      page,
      pathname,
      posts,
      totalPages,
    } = this.props

    // Error handling
    if (error) {
      return (
        <SystemError error={error} />
      )
    }

    const title = catLabel + siteMeta.name.separator + siteMeta.name.full
    const canonical = `${siteMeta.urlOrigin}${pathname}`

    return (

        <Helmet
          title={title}
          link={[
            { rel: 'canonical', href: canonical }
          ]}
          meta={[
            { name: 'description', content: siteMeta.desc },
            { name: 'twitter:title', content: title },
            { name: 'twitter:description', content: siteMeta.desc },
            { name: 'twitter:image', content: siteMeta.ogImage.url },
            { property: 'og:title', content: title },
            { property: 'og:description', content: siteMeta.desc },
            { property: 'og:image', content: siteMeta.ogImage.url },
            { property: 'og:image:width', content: siteMeta.ogImage.width },
            { property: 'og:image:height', content: siteMeta.ogImage.height },
            { property: 'og:type', content: 'website' },
            { property: 'og:url', content: canonical }
          ]}
        />
        <List
          data={posts}
          catName={catLabel}
          isFetching={isFetching}
          showSpinner={true}
        />
        <Pagination
          currentPage={page}
          totalPages={totalPages}
        />

    )
  }
}

/**
 *  @typedef {import('@twreporter/redux/lib/typedef').ReduxState} ReduxState
 */

/**
 *  @typedef {import('../utils/shallow-clone-entity').MetaOfPost} MetaOfPost
 */

/**
 *  @param {Object} [location={}] - react-router location object
 *  @return {number} current page
 */
function pageProp(location={}) {
  const defaultPage = 1
  const search = _.get(location, 'search', '')
  const searchWithoutPrefix = typeof search === 'string' ? search.replace(/^\?/, '') : search
  const pageStr = _.get(querystring.parse(searchWithoutPrefix), 'page', '1')
  let page = parseInt(Array.isArray(pageStr) ? pageStr[0] : pageStr, 10)

  if (isNaN(page)) {
    page = defaultPage
  }

  return page
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @return {number}
 */
function totalPagesProp(state, listId, nPerPage) {
  const total = _.get(state, [reduxStateFields.lists, listId, 'total'], 0)
  return Math.ceil(total / nPerPage)
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @return {boolean}
 */
function isFetchingProp(state, listId) {
  return _.get(state, [reduxStateFields.lists, listId, 'isFetching'])
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @return {Object} error object
 */
function errorProp(state, listId) {
  return _.get(state, [reduxStateFields.lists, listId, 'error'])
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @param {number} page - current page
 *  @return {MetaOfPost[]}
 */
function postsProp(state, listId, page) {
  const { entities, postsInEntities, lists } = reduxStateFields
  const postEntities = _.get(state, [entities, postsInEntities, 'byId'])
  const listObj = _.get(state, [ lists, listId ])
  const itemsRange = _.get(listObj, ['pages', page])
  const postIds = _.get(listObj, 'items', [])
  const postIdsForCurPage = Array.isArray(itemsRange) && Array.isArray(postIds) ?
    postIds.slice(itemsRange[0], itemsRange[1] + 1) : []
  const posts = []
  _.forEach(postIdsForCurPage, postId => {
    const post = _.get(postEntities, postId)
    if (post) {
      posts.push(cloneUtils.shallowCloneMetaOfPost(post))
    }
  })
  return posts
}

/**
 *  @typedef {Object} CategoryProps
 *  @property {string} catId - category list id
 *  @property {string} catLabel - category label
 *  @property {Object} error - error object
 *  @property {boolean} isFetching - if it is requesting api or not
 *  @property {number} page - current page for pagination
 *  @property {number} nPerPage - number per page
 *  @property {string} pathname - URL path
 *  @property {MetaOfPost[]} posts - array of posts
 *  @property {number} totalPages - total page for pagination
 */

/**
 *  @param {ReduxState} state
 *  @param {Object} props
 *  @param {Object} props.location - react-router location object
 *  @param {string} props.location.pathname
 *  @param {Object} props.match - react-router match object
 *  @param {Object} props.match.params
 *  @param {string} props.match.params.category
 *  @return {CategoryProps}
 */
function mapStateToProps(state, props) {
  const location = _.get(props, 'location')
  const pathSegment = _.get(props, 'match.params.category')
  const catId = categoryConst.ids[pathSegment]
  const catLabel = categoryConst.labels[pathSegment]
  const pathname = _.get(location, 'pathname', `/categories/${pathSegment}`)

  const page = pageProp(location)
  const nPerPage = dataLoaderConst.categoryListPage.nPerPage

  return {
    catId,
    catLabel,
    error: errorProp(state, catId),
    isFetching: isFetchingProp(state, catId),
    nPerPage,
    page,
    pathname,
    posts: postsProp(state, catId, page),
    totalPages: totalPagesProp(state, catId, nPerPage),
  }
}

Category.defaultProps = {
  catId: '',
  catLabel: '',
  error: null,
  isFetching: false,
  posts: [],
  totalPages: 0,
  nPerPage: dataLoaderConst.categoryListPage.nPerPage,
}

Category.propTypes = {
  catId: PropTypes.string,
  catLabel: PropTypes.string,
  error: PropTypes.object,
  fetchPostsByCategoryListId: PropTypes.func.isRequired,
  isFetching: PropTypes.bool,
  nPerPage: PropTypes.number,
  page: PropTypes.number.isRequired,
  pathname: PropTypes.string.isRequired,

  //TODO: define metaOfPost
  // posts: PropTypes.arrayOf(propTypesConst.metaOfPost),
  posts: PropTypes.array,
  totalPages: PropTypes.number,
}

export { Category }
export default connect(mapStateToProps, { fetchPostsByCategoryListId })(Category)

<commit_msg>refactor: update src/containers/Category.js<commit_after>import { connect } from 'react-redux'
import { List } from '@twreporter/react-components/lib/listing-page'
import categoryConst from '../constants/category'
import dataLoaderConst from '../constants/data-loaders'
import Helmet from 'react-helmet'
import loggerFactory from '../logger'
import Pagination from '../components/Pagination'
import PropTypes from 'prop-types'
import querystring from 'querystring'
import React, { PureComponent } from 'react'
import SystemError from '../components/SystemError'
import siteMeta from '../constants/site-meta'
import twreporterRedux from '@twreporter/redux'

// utils
import cloneUtils from '../utils/shallow-clone-entity'

// lodash
import forEach from 'lodash/forEach'
import get from 'lodash/get'

const _ = {
  forEach,
  get,
}

const { actions, reduxStateFields, utils } = twreporterRedux
const { fetchPostsByCategoryListId } = actions
const logger = loggerFactory.getLogger()

class Category extends PureComponent {
  componentDidMount() {
    this.fetchPostsWithCatch()
  }

  componentDidUpdate(prevProps) {
    if (this.props.catId !== prevProps.catId ||
      this.props.page !== prevProps.page
    ) {
      this.fetchPostsWithCatch()
    }
  }

  fetchPostsWithCatch() {
    const {
      catId,
      fetchPostsByCategoryListId,
      nPerPage,
      page,
    } = this.props

    fetchPostsByCategoryListId(catId, nPerPage, page)
      .catch((failAction) => {
        logger.errorReport({
          report: _.get(failAction, 'payload.error'),
          message: `Error to fetch posts (category id: '${catId}', page: ${page}, nPerPage: ${nPerPage}).`
        })
      })
  }

  render() {
    const {
      catLabel,
      error,
      isFetching,
      page,
      pathname,
      posts,
      totalPages,
    } = this.props

    // Error handling
    if (error) {
      return (
        <SystemError error={error} />
      )
    }

    const title = catLabel + siteMeta.name.separator + siteMeta.name.full
    const canonical = `${siteMeta.urlOrigin}${pathname}`

    return (

        <Helmet
          title={title}
          link={[
            { rel: 'canonical', href: canonical }
          ]}
          meta={[
            { name: 'description', content: siteMeta.desc },
            { name: 'twitter:title', content: title },
            { name: 'twitter:description', content: siteMeta.desc },
            { name: 'twitter:image', content: siteMeta.ogImage.url },
            { property: 'og:title', content: title },
            { property: 'og:description', content: siteMeta.desc },
            { property: 'og:image', content: siteMeta.ogImage.url },
            { property: 'og:image:width', content: siteMeta.ogImage.width },
            { property: 'og:image:height', content: siteMeta.ogImage.height },
            { property: 'og:type', content: 'website' },
            { property: 'og:url', content: canonical }
          ]}
        />
        <List
          data={posts}
          catName={catLabel}
          isFetching={isFetching}
          showSpinner={true}
        />
        <Pagination
          currentPage={page}
          totalPages={totalPages}
        />

    )
  }
}

/**
 *  @typedef {import('@twreporter/redux/lib/typedef').ReduxState} ReduxState
 */

/**
 *  @typedef {import('../utils/shallow-clone-entity').MetaOfPost} MetaOfPost
 */

/**
 *  @param {Object} [location={}] - react-router location object
 *  @return {number} current page
 */
function pageProp(location={}) {
  const defaultPage = 1
  const search = _.get(location, 'search', '')
  const searchWithoutPrefix = typeof search === 'string' ? search.replace(/^\?/, '') : search
  const pageStr = _.get(querystring.parse(searchWithoutPrefix), 'page', '1')
  let page = parseInt(Array.isArray(pageStr) ? pageStr[0] : pageStr, 10)

  if (isNaN(page) || page < defaultPage) {
    page = defaultPage
  }

  return page
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @return {number}
 */
function totalPagesProp(state, listId, nPerPage) {
  const total = _.get(state, [reduxStateFields.lists, listId, 'total'], 0)
  return Math.ceil(total / nPerPage)
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @return {boolean}
 */
function isFetchingProp(state, listId) {
  return _.get(state, [reduxStateFields.lists, listId, 'isFetching'])
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @return {Object} error object
 */
function errorProp(state, listId) {
  return _.get(state, [reduxStateFields.lists, listId, 'error'])
}

/**
 *  @param {ReduxState} state
 *  @param {string} listId - category list id
 *  @param {number} page - current page
 *  @return {MetaOfPost[]}
 */
function postsProp(state, listId, page) {
  const { entities, postsInEntities, lists } = reduxStateFields
  const postEntities = _.get(state, [entities, postsInEntities, 'byId'])
  const listObj = _.get(state, [ lists, listId ])
  const itemsRange = _.get(listObj, ['pages', page])
  const postIds = _.get(listObj, 'items', [])
  const postIdsForCurPage = Array.isArray(itemsRange) && Array.isArray(postIds) ?
    postIds.slice(itemsRange[0], itemsRange[1] + 1) : []
  const posts = []
  _.forEach(postIdsForCurPage, postId => {
    const post = _.get(postEntities, postId)
    if (post) {
      posts.push(cloneUtils.shallowCloneMetaOfPost(post))
    }
  })
  return posts
}

/**
 *  @typedef {Object} CategoryProps
 *  @property {string} catId - category list id
 *  @property {string} catLabel - category label
 *  @property {Object} error - error object
 *  @property {boolean} isFetching - if it is requesting api or not
 *  @property {number} page - current page for pagination
 *  @property {number} nPerPage - number per page
 *  @property {string} pathname - URL path
 *  @property {MetaOfPost[]} posts - array of posts
 *  @property {number} totalPages - total page for pagination
 */

/**
 *  @param {ReduxState} state
 *  @param {Object} props
 *  @param {Object} props.location - react-router location object
 *  @param {string} props.location.pathname
 *  @param {Object} props.match - react-router match object
 *  @param {Object} props.match.params
 *  @param {string} props.match.params.category
 *  @return {CategoryProps}
 */
function mapStateToProps(state, props) {
  const location = _.get(props, 'location')
  const pathSegment = _.get(props, 'match.params.category')
  const catId = categoryConst.ids[pathSegment]
  const catLabel = categoryConst.labels[pathSegment]
  const pathname = _.get(location, 'pathname', `/categories/${pathSegment}`)

  const page = pageProp(location)
  const nPerPage = dataLoaderConst.categoryListPage.nPerPage

  return {
    catId,
    catLabel,
    error: errorProp(state, catId),
    isFetching: isFetchingProp(state, catId),
    nPerPage,
    page,
    pathname,
    posts: postsProp(state, catId, page),
    totalPages: totalPagesProp(state, catId, nPerPage),
  }
}

Category.defaultProps = {
  catId: '',
  catLabel: '',
  error: null,
  isFetching: false,
  posts: [],
  totalPages: 0,
  nPerPage: dataLoaderConst.categoryListPage.nPerPage,
}

Category.propTypes = {
  catId: PropTypes.string,
  catLabel: PropTypes.string,
  error: PropTypes.object,
  fetchPostsByCategoryListId: PropTypes.func.isRequired,
  isFetching: PropTypes.bool,
  nPerPage: PropTypes.number,
  page: PropTypes.number.isRequired,
  pathname: PropTypes.string.isRequired,

  //TODO: define metaOfPost
  // posts: PropTypes.arrayOf(propTypesConst.metaOfPost),
  posts: PropTypes.array,
  totalPages: PropTypes.number,
}

export { Category }
export default connect(mapStateToProps, { fetchPostsByCategoryListId })(Category)

<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Form, FormGroup, Input, Card, CardText, CardBlock,
  CardTitle, CardSubtitle, Row, Col } from 'reactstrap';
import PropTypes from 'prop-types';
import NewsStore from '../stores/NewsStore';
import NewsActions from '../actions/NewsActions';

class ArticlesView extends Component {

  constructor() {
    super();
    this.state = {
      allItems: [],
    };
    this.onChange = this.onChange.bind(this);
  }

  getInitialState() {
    return { allItems: null };
  }

  componentDidMount() {
    const { params } = this.props;
    NewsStore.addChangeListener(this.onChange);
    NewsActions.getNews(params.id);
  }

  componentWillUnmount() {
    NewsStore.removeChangeListener(this.onChange);
  }

  onChange() {
    this.setState({ allItems: NewsStore.getAll() });
  }

  getItemsState() {
    return {
      allItems: NewsStore.getAll(),
    };
  }

  handleSort(event) {
    const { params } = this.props;
    event.preventDefault();
    const val = event.target.value;
    NewsActions.getNews(`${params.id}&sortBy=${val}`);
  }
   /**
   * @return {object}
   */

  render() {
    const { params } = this.props;
    const sort = params.sort.split(',');
    const option = sort.map((type, index) => <option value={type} key={index}> {type} </option>);
    return (

{params.id}

            <Form className="order">
              <FormGroup>
                <Input type="select" name="select" id="exampleSelect" onChange={this.handleSort.bind(this)}>
                  <option>Sort News By</option>
                  {option}
                </Input>
              </FormGroup>
            </Form>

        <Row>
          {this.state.allItems.map(news => (
            <Col xs="3" sm="3" className="news-frame">
              <Card className="headline">
                <CardBlock>
                  <CardTitle className="title">{news.meta}</CardTitle>
                  <CardSubtitle className="subtitle">{news.header}</CardSubtitle>
                </CardBlock>

                <CardBlock>
                  <CardText>{news.description}</CardText>
                  Read More
                </CardBlock>
              </Card>
            </Col>
         ))}
          {this.state.allItems.map((news) => {
            const cssStyle = {
              height: '350px',
              background: `url(${news.image}) center center`,
              width: '100%',
              backgroundSize: 'cover',

            };
            return (
              <Col xs="3" sm="3" className="news-frame">
                <Card className="headline">
                  <CardBlock>
                    <CardTitle className="title">{news.meta}</CardTitle>
                    <CardSubtitle className="subtitle">{news.header}</CardSubtitle>
                  </CardBlock>

                  <CardBlock>
                    <CardText>{news.description}</CardText>
                    Read More
                  </CardBlock>
                </Card>
              </Col>
            );
          })}
        </Row>

    );
  }

}

ArticlesView.propTypes = {
  params: PropTypes.object,
};

export default ArticlesView;
<commit_msg>refactor code<commit_after>import React, { Component } from 'react';
import { Form, FormGroup, Input, Card, CardText, CardBlock,
  CardTitle, CardSubtitle, Row, Col } from 'reactstrap';
import PropTypes from 'prop-types';
import NewsStore from '../stores/NewsStore';
import NewsActions from '../actions/NewsActions';

class ArticlesView extends Component {

  constructor() {
    super();
    this.state = {
      allItems: [],
    };
    this.onChange = this.onChange.bind(this);
  }

  getInitialState() {
    return { allItems: null };
  }

  componentDidMount() {
    const { params } = this.props;
    NewsStore.addChangeListener(this.onChange);
    NewsActions.getNews(params.id);
  }

  componentWillUnmount() {
    NewsStore.removeChangeListener(this.onChange);
  }

  onChange() {
    this.setState({ allItems: NewsStore.getAll() });
  }

  getItemsState() {
    return {
      allItems: NewsStore.getAll(),
    };
  }

  handleSort(event) {
    const { params } = this.props;
    event.preventDefault();
    const val = event.target.value;
    NewsActions.getNews(`${params.id}&sortBy=${val}`);
  }
   /**
   * @return {object}
   */

  render() {
    const { params } = this.props;
    const sort = params.sort.split(',');
    const option = sort.map((type, index) => <option value={type} key={index}> {type} </option>);
    return (

{params.id}

            <Form className="order">
              <FormGroup>
                <Input type="select" name="select" id="exampleSelect" onChange={this.handleSort.bind(this)}>
                  <option>Sort News By</option>
                  {option}
                </Input>
              </FormGroup>
            </Form>

        <Row>
          {this.state.allItems.map(news => (
            <Col xs="3" sm="3" className="news-frame">
              <Card className="headline">

                <CardBlock className="news-title">
                  <CardTitle className="title">{news.meta}</CardTitle>
                  <CardSubtitle className="subtitle">{news.header}</CardSubtitle>
                </CardBlock>
                <CardBlock>
                  <CardText>{news.description}</CardText>
                  Read More
                </CardBlock>
              </Card>
            </Col>
         ))}
          {this.state.allItems.map((news) => {
            const cssStyle = {
              height: '350px',
              background: `url(${news.image}) center center`,
              width: '100%',
              backgroundSize: 'cover',

            };
            return (
              <Col xs="3" sm="3" className="news-frame">
                <Card className="headline">
                  <CardBlock>
                    <CardTitle className="title">{news.meta}</CardTitle>
                    <CardSubtitle className="subtitle">{news.header}</CardSubtitle>
                  </CardBlock>

                  <CardBlock>
                    <CardText>{news.description}</CardText>
                    Read More
                  </CardBlock>
                </Card>
              </Col>
            );
          })}
        </Row>

    );
  }

}

ArticlesView.propTypes = {
  params: PropTypes.object,
};

export default ArticlesView;
<|endoftext|>


<commit_before>goog.provide("prism.theme.builder.model.style.GradientStyle");

goog.require("prism.theme.builder.model.style.Style");

/**
 * @constructor
 * @author daginno
 *
 * @param {*}
 *            value
 * @extends {prism.theme.builder.model.style.Style}
 */
prism.theme.builder.model.style.GradientStyle = function(color1, stop1, color2,
		stop2) {
	prism.theme.builder.model.style.Style.call(this, null);
	this.color1 = color1;
	this.stop1 = stop1;
	this.color2 = color2;
	this.stop2 = stop2;
}
goog.inherits(prism.theme.builder.model.style.GradientStyle,
		prism.theme.builder.model.style.Style);

/**
 * @override
 * @see prism.theme.builder.model.style.IStyle#toCSS()
 * @return {String}
 */
prism.theme.builder.model.style.GradientStyle.prototype.toCSS = function() {
	var value = "(" + this.color1 + " " + this.stop1 + ", " + this.color2 + " " + this.stop2 + ")";
	return "background-image: -webkit-linear-gradient" + value + ";\n" +
	 "background-image: -moz-linear-gradient" + value + ";\n"+
	 "background-image: -ms-linear-gradient" + value + ";\n" +
	 "background-image: -o-linear-gradient" + value + ";\n" +
	 "background-image: linear-gradient" + value + "\n";
}<commit_msg>fixed author<commit_after>goog.provide("prism.theme.builder.model.style.GradientStyle");

goog.require("prism.theme.builder.model.style.Style");

/**
 * @constructor
 * @author Sandra https://github.com/SandraShklyaeva
 *
 * @param {*}
 *            value
 * @extends {prism.theme.builder.model.style.Style}
 */
prism.theme.builder.model.style.GradientStyle = function(color1, stop1, color2,
		stop2) {
	prism.theme.builder.model.style.Style.call(this, null);
	this.color1 = color1;
	this.stop1 = stop1;
	this.color2 = color2;
	this.stop2 = stop2;
}
goog.inherits(prism.theme.builder.model.style.GradientStyle,
		prism.theme.builder.model.style.Style);

/**
 * @override
 * @see prism.theme.builder.model.style.IStyle#toCSS()
 * @return {String}
 */
prism.theme.builder.model.style.GradientStyle.prototype.toCSS = function() {
	var value = "(" + this.color1 + " " + this.stop1 + ", " + this.color2 + " " + this.stop2 + ")";
	return "background-image: -webkit-linear-gradient" + value + ";\n" +
	 "background-image: -moz-linear-gradient" + value + ";\n"+
	 "background-image: -ms-linear-gradient" + value + ";\n" +
	 "background-image: -o-linear-gradient" + value + ";\n" +
	 "background-image: linear-gradient" + value + "\n";
}<|endoftext|>


<commit_before>(function () {

    //*@public
    /**
        In order to provide some convenience and debugging tools we track
        the applications running at any given time. Here we collection them
        for reference later. When _enyo.Application_s are destroyed they know
        to remove themselves from this table.
    */
    var applications = enyo.applications = {};

    //*@protected
    /**
        Used internally to maintain registration of applications with
        the framework.
    */
    var register = function (app) {
        applications[app._instance_name] = app;
    };

    //*@protected
    /**
        Used internally to unregister applications that have been destroyed.
    */
    var unregister = function (app) {
        var kind = app.kindName;
        var kinds = applications[kind] || [];
        var idx = kinds.indexOf(app);
        if (!~idx) {
            kinds.splice(idx, 1);
        }
    };

    //*@protected
    /**
        Used internally used to determine namespaces from pathnames.
    */
    var namespaceFrom = function (path) {
        var parts;
        var ns;
        // if it isn't a string or has no length we can't do anything
        if ("string" !== typeof path || "" === path) return undefined;
        // attempt to split the string to separate the path components
        parts = path.split(".");
        // if it only has one element then we know there isn't a namespace
        if (1 === parts.length) return undefined;
        ns = parts.shift();
        // we assume we have a namespace now
        return ns;
    };

    //*@public
    /**
        An _enyo.Application_ can be used to coordinate execution of
        a given collection of _enyo_ objects. There can be one or more
        _enyo.Applications_ running (with some limitation such as which is
        rendered into the _document.body_ - no limitation if they are each
        rendered into separate DOM nodes or nested). It also provides the
        ability to namespace and automatically initialize any _controllers_
        of the application.

        Typically the namespace that the _enyo.Application_ is subclassed
        into will be used as the namespace of any singleton controllers
        implemented at initialization.

        For example, if you subclass _enyo.Application_ as the following:

        enyo.kind({
            name: "MyApp.Application",
            kind: "enyo.Application",
            controllers: [
                {name: "contactsController", kind: "MyApp.ContactsController"}
            ]
        })

        it will instantiate the singleton _contactsController_ as
        _MyApp.contactsController_. Any bindings of the application object
        or any other object in-or-outside-of the application can reference
        this controller by that path as long as the application's _start_
        method has been called.

        You can explicitly include a separate namespace for a controller in
        its name property if necessary. The path is not restricted to existing
        namespaces and can be as deep as needed, for example:

        {name: "My.Controllers.Namespace.That.Is.Stupidly.Deep.controller"...}
    */
    enyo.kind({

        // ...........................
        // PUBLIC PROPERTIES

        //*@public
        name: "enyo.Application",

        //*@public
        kind: "enyo.ViewController",

        //*@public
        autoStart: true,

        //*@public
        renderOnStart: true,

        //*@public
        controllers: null,

        //*@public
        initBindings: false,

        //*@public
        concat: ["controllers"],

        // ...........................
        // PROTECTED PROPERTIES

        //*@protected
        _instance_name: "",

        // ...........................
        // COMPUTED PROPERTIES

        //*@public
        /**
            Computed property that returns the string representation
            of the namespace assigned to this application object's
            kind-name (not instance). For example:

            enyo.kind({
                name: "MyApp.Application",
                kind: "enyo.Application"
            })

            would return a namespace of "MyApp".
        */
        namespace: enyo.Computed(function () {
            return namespaceFrom(this._instance_name || this.kindName);
        }, {cached: true}),

        // ...........................
        // PUBLIC METHODS

        //*@public
        /**
            If the _autoStart_ flag is set to true this will automatically
            be executed when the constructor is called. Otherwise it can
            be executed whenever the application should begin execution.
        */
        start: function () {
            // we register kind of early in the process in case any controllers
            // or other initialization assumes it will be there...
            register(this);
            // once the controllers have been initialized we can go ahead and
            // hookup any bindings that were supplied to the application
            this.initBindings = true;
            this.setup();
            if (true === this.renderOnStart) {
                this.render();
            }
        },

        // ...........................
        // PROTECTED METHODS

        //*@protected
        constructor: function (props) {
            if (props && enyo.exists(props.name)) {
                enyo.setPath(props.name, this);
                this._instance_name = props.name;
                delete props.name;
            }
            this.inherited(arguments);
        },

        //*@protected
        constructed: function () {
            this.inherited(arguments);
            if (true === this.autoStart) this.start();
        },

        //*@protected
        createView: function () {
            var ctor = this.get("_view_kind");
            this.set("view", new ctor({app: this, _bubble_target: this}));
        },

        //*@protected
        postInitialization: function () {
            this.inherited(arguments);
            this.setupControllers();
        },

        //*@protected
        setupControllers: function () {

            /**
                controller options

                can be global
                    - with/without namespace
                    - this means it is not an application specific instance
                      of the controller

                can be app-specific instance
                    - only referenceable within the context of the application
                    - ignores namespace and uses base-name from the application-instance's
                      controllers property
                    - must have unique name
            */

            var kinds = this.controllers || [];
            var controllers = this.controllers = {};

            enyo.forEach(kinds, function (kind) {
                // we need the name of the instance whether the controller is global
                // or app-specific
                var name = kind.name;
                // there is the optional global flag that indicates if the controller
                // is to be instanced outside the scope of the application
                var global = Boolean(kind.global);
                var ctor;
                var inst;
                // cleanup
                delete kind.global;
                delete kind.name;
                // if the definition does not supply a controller kind we add one
                if (!("kind" in kind)) kind.kind = "enyo.Controller";
                // create a kind constructor for the controller with all of the given
                // properties
                ctor = enyo.kind(kind);
                inst = new ctor({owner: this, app: this});
                // if the controller is not a global controller we create it as part
                // of our applications controller store
                if (false === global) {
                    controllers[name] = inst;
                } else {
                    enyo.setPath(name, inst);
                }
            }, this);
        },

        //*@protected
        destroy: function () {
            this.inherited(arguments);
            this.destroyControllers();
            unregister(this);
        },

        //*@protected
        destroyControllers: function () {
            var constrollers = this.controllers;
            var controller;
            var name;
            for (name in controllers) {
                if (!controllers.hasOwnProperty(name)) continue;
                controller = controllers[name];
                if (controller.owner && this === controller.owner) {
                    controller.destroy();
                }
                delete controllers[name];
            }
            delete this.controllers;
        }

        // ...........................
        // OBSERVERS

    });

}());
<commit_msg>slight cleanup<commit_after>(function () {

    //*@public
    /**
        In order to provide some convenience and debugging tools we track
        the applications running at any given time. Here we collection them
        for reference later. When _enyo.Application_s are destroyed they know
        to remove themselves from this table.
    */
    var applications = enyo.applications = {};

    //*@protected
    /**
        Used internally to maintain registration of applications with
        the framework.
    */
    var register = function (app) {
        applications[app._instance_name] = app;
    };

    //*@protected
    /**
        Used internally to unregister applications that have been destroyed.
    */
    var unregister = function (app) {
        var kind = app.kindName;
        var kinds = applications[kind] || [];
        var idx = kinds.indexOf(app);
        if (!~idx) {
            kinds.splice(idx, 1);
        }
    };

    //*@public
    /**
        An _enyo.Application_ can be used to coordinate execution of
        a given collection of _enyo_ objects. There can be one or more
        _enyo.Applications_ running (with some limitation such as which is
        rendered into the _document.body_ - no limitation if they are each
        rendered into separate DOM nodes or nested). It also provides the
        ability to namespace and automatically initialize any _controllers_
        of the application.
    */
    enyo.kind({

        // ...........................
        // PUBLIC PROPERTIES

        //*@public
        name: "enyo.Application",

        //*@public
        kind: "enyo.ViewController",

        //*@public
        autoStart: true,

        //*@public
        renderOnStart: true,

        //*@public
        controllers: null,

        //*@public
        initBindings: false,

        //*@public
        concat: ["controllers"],

        // ...........................
        // PROTECTED PROPERTIES

        //*@protected
        _instance_name: "",

        // ...........................
        // COMPUTED PROPERTIES

        // ...........................
        // PUBLIC METHODS

        //*@public
        /**
            If the _autoStart_ flag is set to true this will automatically
            be executed when the constructor is called. Otherwise it can
            be executed whenever the application should begin execution.
        */
        start: function () {
            // we register kind of early in the process in case any controllers
            // or other initialization assumes it will be there...
            register(this);
            // once the controllers have been initialized we can go ahead and
            // hookup any bindings that were supplied to the application
            this.initBindings = true;
            this.setup();
            if (true === this.renderOnStart) {
                this.render();
            }
        },

        // ...........................
        // PROTECTED METHODS

        //*@protected
        constructor: function (props) {
            if (props && enyo.exists(props.name)) {
                enyo.setPath(props.name, this);
                this._instance_name = props.name;
                delete props.name;
            }
            this.inherited(arguments);
        },

        //*@protected
        constructed: function () {
            this.inherited(arguments);
            if (true === this.autoStart) this.start();
        },

        //*@protected
        createView: function () {
            var ctor = this.get("_view_kind");
            this.set("view", new ctor({app: this, _bubble_target: this}));
        },

        //*@protected
        postInitialization: function () {
            this.inherited(arguments);
            this.setupControllers();
        },

        //*@protected
        setupControllers: function () {
            var kinds = this.controllers || [];
            var controllers = this.controllers = {};
            enyo.forEach(kinds, function (kind) {
                // we need the name of the instance whether the controller is global
                // or app-specific
                var name = kind.name;
                // there is the optional global flag that indicates if the controller
                // is to be instanced outside the scope of the application
                var global = Boolean(kind.global);
                var ctor;
                var inst;
                // cleanup
                delete kind.global;
                delete kind.name;
                // if the definition does not supply a controller kind we add one
                if (!("kind" in kind)) kind.kind = "enyo.Controller";
                // create a kind constructor for the controller with all of the given
                // properties
                ctor = enyo.kind(kind);
                inst = new ctor({owner: this, app: this});
                // if the controller is not a global controller we create it as part
                // of our applications controller store
                if (false === global) {
                    controllers[name] = inst;
                } else {
                    enyo.setPath(name, inst);
                }
            }, this);
        },

        //*@protected
        destroy: function () {
            this.inherited(arguments);
            this.destroyControllers();
            unregister(this);
        },

        //*@protected
        destroyControllers: function () {
            var constrollers = this.controllers;
            var controller;
            var name;
            for (name in controllers) {
                if (!controllers.hasOwnProperty(name)) continue;
                controller = controllers[name];
                if (controller.owner && this === controller.owner) {
                    controller.destroy();
                }
                delete controllers[name];
            }
            delete this.controllers;
        }

        // ...........................
        // OBSERVERS

    });

}());
<|endoftext|>


<commit_before>(function( window, $ ) {
  var $window, $doc;

  $window = $(window);
  $doc = $( document.documentElement );

  var ns = window.componentNamespace = window.componentNamespace || "FG";
  window[ns] = window[ns] || {};

  Function.prototype.bind = Function.prototype.bind || function( context ) {
    var self = this;

    return function() {
      self.apply( context, arguments );
    };
  };

  var Tau = window[ns].Tau = function( element, options ) {
    var startIndex, reducedStepSize;

    this.element = element;
    this.options = options || {};
    this.$element = $( element );
    this.$initial = this.$element.find( "img" );
    this.$loading = this.$element.find( ".loading" );
    this.index = 0;

    // if the frame count is defined on the first image use that
    this.frames = parseInt( this.$initial.attr("data-frames"), 10 );

    // if the frame count is not defined assume that we are using existing images
    this.frames = this.frames || this.$initial.length;

    // grab the user specified step size for when the browser is less-abled
    reducedStepSize = parseInt( this.$initial.attr("data-reduced-step-size"), 10 ) || 4;

    // TODO sort out a better qualification for the full set of images?
    this.stepSize = window.requestAnimationFrame ? 1 : reducedStepSize;

    // grab the user specified auto start delay
    this.autoRotateStartDelay =
      parseInt( this.$initial.attr("data-auto-rotate-delay"), 10 ) || Tau.autoRotateStartDelay;

    this.mouseMoveBinding = this.rotateEvent.bind(this);
    this.touchMoveBinding = this.rotateEvent.bind(this);

    this.path = new Tau.Path();

    // make sure the initial image stays visible after enhance
    this.$initial.first().addClass( "focused" );

    // hide all other images
    this.$element.addClass( "tau-enhanced" );

    // create a rendering spot to force decoding in IE and prevent blinking
    //
    this.$render = $( "

" )
      .css( "position", "absolute" )
      .css( "left", "0" )
      .css( "top", "0" )
      .prependTo( this.element );

    if( this.options.canvas !== false ){
      this.canvas = $( "<canvas/>").prependTo( this.element )[0];

      if(this.canvas.getContext ){
        this.canvasCtx = this.canvas.getContext("2d");
        this.$element.addClass( "tau-canvas" );
      }
    }

    // create the rest of the images
    this.createImages();

    // set the initial index and image
    this.goto( 0 );

    // start the automatic rotation
    setTimeout(this.autoRotate.bind(this), this.autoRotateStartDelay);

    // setup the event bindings for touch drag and mouse drag rotation
    this.bind();
  };

  Tau.autoRotateTraversalTime = 4500;
  Tau.autoRotateStartDelay = 100;
  Tau.verticalScrollRatio = 4;
  // Tau.decelTimeStep = Tau.autoRotateDelay / 2;
  // Tau.decel = Tau.decelTimeStep / 8;
  Tau.maxVelocity = 60;

  Tau.prototype.change = function( delta ) {
    this.goto( this.index + delta );
  };

  Tau.prototype.goto = function( index ) {
    var $next, normalizedIndex, imageCount = this.$images.length;

    index = index % imageCount;

    // stay within the bounds of the array
    normalizedIndex = (imageCount + index) % imageCount;

    // set the next image that's going to be shown/focused
    $next = this.$images.eq( normalizedIndex );

    // skip this action if the desired image isn't loaded yet
    // TODO do something fancier here instead of just throwing up hands
    if( !$next[0].tauImageLoaded ) {
      this.showLoading();
      return;
    }

    // hide any image that happens to be visible (initial image when canvas)
    if( this.$current ) {
      this.$current.removeClass( "focused" );
    }

    // record the current focused image and make it visible
    this.$current = $next;

    // record the updated index only after advancing is possible
    this.index = normalizedIndex;

    if( this.canvasCtx ) {
      var next = $next[0];

      var width = next.width;
      var height = next.height;
      var parentWidth = this.element.clientWidth;
      var calcHeight = (parentWidth/width) * height;

      if( !this.canvasDimensionSet ) {
        this.canvas.width = parentWidth;
        this.canvas.height = calcHeight;
        this.canvasDimensionSet = true;
      }

      this.canvasCtx.drawImage($next[0], 0, 0, parentWidth, calcHeight);
    } else {
      // show the new focused image
      this.$current.addClass( "focused" );
    }
  };

  // TODO transplant the attributes from the initial image
  Tau.prototype.createImages = function() {
    var src, frames, html, $new, boundImageLoaded;

    // if there are no image elements, raise an exception
    if( this.$initial.length < 1 ){
      throw new Error( "At least one image required" );
    }

    // if there is only one image element, assume it's a template
    if( this.$initial.length == 1 ) {
      // avoid doing rebinding in a tight loop
      boundImageLoaded = this.imageLoaded.bind( this );

      this.markImageLoaded( this.$initial[0] );

      src = this.$initial.attr( "data-src-template" );

      for( var i = this.stepSize + 1; i <= this.frames; i+= this.stepSize ) {
        html = "";

        $new = $( html );

        // record when each image has loaded
        $new.bind( "load", boundImageLoaded );

        this.$element.append( $new );
        this.$render.append( html );
      }

      this.loadedCount = 0;
    } else {

      // mark the initial image as loaded
      this.$initial.each(function(i, e){
        this.markImageLoaded(e);
      }.bind(this));
    }

    // take all the child images and use them as frames of the rotation
    this.$images = this.$element.children().filter( "img" );
  };

  Tau.prototype.imageLoaded = function( event ) {
    this.markImageLoaded( event.target );
    this.loadedCount++;

    if( this.loadedCount >= this.frames - 1) {
      this.hideLoading();
    }
  };

  Tau.prototype.markImageLoaded = function( element ) {
    element.tauImageLoaded = true;
  };

  Tau.prototype.bind = function() {
    this.$element.bind( "mousedown touchstart", this.track.bind(this) );
  };

  Tau.prototype.autoRotate = function() {
    // already rotating
    if( this.autoInterval ) {
      return;
    }

    this.autoInterval = setInterval(function() {
      this.change( 1 );
    }.bind(this),  this.autoRotateDelay() * this.stepSize);
  };

  Tau.prototype.autoRotateDelay = function(){
    return Tau.autoRotateTraversalTime / this.frames;
  };

  Tau.prototype.stopAutoRotate = function() {
    clearInterval( this.autoInterval );
    this.autoInterval = undefined;
  };

  Tau.prototype.track = function( event ) {
    var point;

    // prevent dragging behavior for mousedown
    if( event.type === "mousedown"  ){
      event.preventDefault();
    }

    if( this.tracking ) {
      return;
    }

    $doc.one( "mouseup", this.release.bind(this) );
    $doc.one( "touchend", this.release.bind(this) );

    this.tracking = true;

    // clean out the path since we'll need a new one for decel
    this.path.reset();

    // show the cursor as grabbing
    this.cursorGrab();

    // calculate/store how many pixels makes for an image switch
    this.rotateThreshold = $doc[0].clientWidth / this.frames;

    // record the x for threshold calculations
    point = this.getPoint( event );
    this.downX = point.x;
    this.downY = point.y;
    this.downIndex = this.index;

    $doc.bind( "mousemove", this.mouseMoveBinding );
    $doc.bind( "touchmove", this.touchMoveBinding );
  };

  Tau.prototype.slow = function() {
    // if the path gets broken during the decel just stop
    if( !this.path.isSufficient() ) {
      this.clearSlowInterval();
      return;
    }

    this.rotate({
      x: this.path.last().x + this.velocity,
      y: this.path.last().y
    });

    if( this.velocity > 0 ){
      this.velocity = this.velocity - this.decelVal();

      if( this.velocity <= 0 ){
        this.clearSlowInterval();
      }
    } else {
      this.velocity = this.velocity + this.decelVal();

      if( this.velocity >= 0 ){
        this.clearSlowInterval();
      }
    }
  };

  Tau.prototype.decelVal = function(){
    return this.decelTimeStep() / 8;
  };

  Tau.prototype.clearSlowInterval = function() {
    clearInterval(this.slowInterval);
    this.velocity = 0;
    this.slowInterval = undefined;
  };

  Tau.prototype.decel = function() {
    var velocity, sign;

    // if we don't have two points of mouse or touch tracking this won't work
    if( !this.path.isSufficient() ) {
      return;
    }

    // determine the starting velocity based on the traced path
    velocity = this.path.velocity( this.decelTimeStep() );

    // borrowed from http://stackoverflow.com/questions/7624920/number-sign-in-javascript
    sign = velocity > 0 ? 1 : velocity < 0 ? -1 : 0;

    // keep a lid on how fast the rotation spins out
    if( Math.abs(velocity) > Tau.maxVelocity ){
      velocity = sign * Tau.maxVelocity;
    }

    this.velocity = velocity;
    this.slowInterval = setInterval(this.slow.bind(this), this.decelTimeStep());
  };

  Tau.prototype.decelTimeStep = function(){
    return this.autoRotateDelay() / 2;
  };

  Tau.prototype.release = function( event ) {
    this.decel();

    this.cursorRelease();

    // TODO sort out why shoestring borks when unbinding with a string split list
    $doc.unbind( "mousemove", this.mouseMoveBinding );
    $doc.unbind( "touchmove", this.touchMoveBinding );

    this.tracking = false;
  };

  Tau.prototype.cursorGrab = function() {
    $doc.addClass( "grabbing" );
  };

  Tau.prototype.cursorRelease = function() {
    $doc.removeClass( "grabbing" );
  };

  Tau.prototype.showLoading = function() {
    this.$loading.attr( "style" , "display: block" );
  };

  Tau.prototype.hideLoading = function() {
    this.$loading.attr( "style" , "display: none" );
  };

  Tau.prototype.getPoint = function( event ) {
    var touch = event.touches || (event.originalEvent && event.originalEvent.touches);

    if( touch ){
      return {
        x: touch[0].pageX,
        y: touch[0].pageY
      };
    }

    return {
      x: event.pageX || event.clientX,
      y: event.pageY || event.clientY
    };
  };

  Tau.prototype.rotateEvent = function( event ) {
    // NOTE it might be better to prevent when the rotation returns anything BUT false
    //      so that slow drags still get the scroll prevented
    if( this.rotate(this.getPoint(event)) ){
      event.preventDefault();
    }
  };

  Tau.prototype.rotate = function( point ) {
    var deltaX, deltaY;

    deltaX = point.x - this.downX;
    deltaY = point.y - this.downY;

    // if the movement on the Y dominates X then skip and allow scroll
    if( Math.abs(deltaY) / Math.abs(deltaX) >= Tau.verticalScrollRatio ) {
      return false;
    }

    // NOTE works better on mousedown, here allows autorotate to continue
    this.stopAutoRotate();

    // since we're rotating record the point for decel
    this.path.record( point );

    // NOTE to reverse the spin direction add the delta/thresh to the downIndex
    if( Math.abs(deltaX) >= this.rotateThreshold ) {
      this.goto( this.downIndex - Math.round(deltaX / this.rotateThreshold) );
      return true;
    }
  };
})(this, jQuery);
<commit_msg>comment on canvas dimenion setting<commit_after>(function( window, $ ) {
  var $window, $doc;

  $window = $(window);
  $doc = $( document.documentElement );

  var ns = window.componentNamespace = window.componentNamespace || "FG";
  window[ns] = window[ns] || {};

  Function.prototype.bind = Function.prototype.bind || function( context ) {
    var self = this;

    return function() {
      self.apply( context, arguments );
    };
  };

  var Tau = window[ns].Tau = function( element, options ) {
    var startIndex, reducedStepSize;

    this.element = element;
    this.options = options || {};
    this.$element = $( element );
    this.$initial = this.$element.find( "img" );
    this.$loading = this.$element.find( ".loading" );
    this.index = 0;

    // if the frame count is defined on the first image use that
    this.frames = parseInt( this.$initial.attr("data-frames"), 10 );

    // if the frame count is not defined assume that we are using existing images
    this.frames = this.frames || this.$initial.length;

    // grab the user specified step size for when the browser is less-abled
    reducedStepSize = parseInt( this.$initial.attr("data-reduced-step-size"), 10 ) || 4;

    // TODO sort out a better qualification for the full set of images?
    this.stepSize = window.requestAnimationFrame ? 1 : reducedStepSize;

    // grab the user specified auto start delay
    this.autoRotateStartDelay =
      parseInt( this.$initial.attr("data-auto-rotate-delay"), 10 ) || Tau.autoRotateStartDelay;

    this.mouseMoveBinding = this.rotateEvent.bind(this);
    this.touchMoveBinding = this.rotateEvent.bind(this);

    this.path = new Tau.Path();

    // make sure the initial image stays visible after enhance
    this.$initial.first().addClass( "focused" );

    // hide all other images
    this.$element.addClass( "tau-enhanced" );

    // create a rendering spot to force decoding in IE and prevent blinking
    //
    this.$render = $( "

" )
      .css( "position", "absolute" )
      .css( "left", "0" )
      .css( "top", "0" )
      .prependTo( this.element );

    if( this.options.canvas !== false ){
      this.canvas = $( "<canvas/>").prependTo( this.element )[0];

      if(this.canvas.getContext ){
        this.canvasCtx = this.canvas.getContext("2d");
        this.$element.addClass( "tau-canvas" );
      }
    }

    // create the rest of the images
    this.createImages();

    // set the initial index and image
    this.goto( 0 );

    // start the automatic rotation
    setTimeout(this.autoRotate.bind(this), this.autoRotateStartDelay);

    // setup the event bindings for touch drag and mouse drag rotation
    this.bind();
  };

  Tau.autoRotateTraversalTime = 4500;
  Tau.autoRotateStartDelay = 100;
  Tau.verticalScrollRatio = 4;
  // Tau.decelTimeStep = Tau.autoRotateDelay / 2;
  // Tau.decel = Tau.decelTimeStep / 8;
  Tau.maxVelocity = 60;

  Tau.prototype.change = function( delta ) {
    this.goto( this.index + delta );
  };

  Tau.prototype.goto = function( index ) {
    var $next, normalizedIndex, imageCount = this.$images.length;

    index = index % imageCount;

    // stay within the bounds of the array
    normalizedIndex = (imageCount + index) % imageCount;

    // set the next image that's going to be shown/focused
    $next = this.$images.eq( normalizedIndex );

    // skip this action if the desired image isn't loaded yet
    // TODO do something fancier here instead of just throwing up hands
    if( !$next[0].tauImageLoaded ) {
      this.showLoading();
      return;
    }

    // hide any image that happens to be visible (initial image when canvas)
    if( this.$current ) {
      this.$current.removeClass( "focused" );
    }

    // record the current focused image and make it visible
    this.$current = $next;

    // record the updated index only after advancing is possible
    this.index = normalizedIndex;

    if( this.canvasCtx ) {
      var next = $next[0];

      var width = next.width;
      var height = next.height;
      var parentWidth = this.element.clientWidth;
      var calcHeight = (parentWidth/width) * height;

      // TODO doing this here because it's "late binding" on the values
      // could as well be done once the first image loads
      if( !this.canvasDimensionSet ) {
        this.canvas.width = parentWidth;
        this.canvas.height = calcHeight;
        this.canvasDimensionSet = true;
      }

      this.canvasCtx.drawImage($next[0], 0, 0, parentWidth, calcHeight);
    } else {
      // show the new focused image
      this.$current.addClass( "focused" );
    }
  };

  // TODO transplant the attributes from the initial image
  Tau.prototype.createImages = function() {
    var src, frames, html, $new, boundImageLoaded;

    // if there are no image elements, raise an exception
    if( this.$initial.length < 1 ){
      throw new Error( "At least one image required" );
    }

    // if there is only one image element, assume it's a template
    if( this.$initial.length == 1 ) {
      // avoid doing rebinding in a tight loop
      boundImageLoaded = this.imageLoaded.bind( this );

      this.markImageLoaded( this.$initial[0] );

      src = this.$initial.attr( "data-src-template" );

      for( var i = this.stepSize + 1; i <= this.frames; i+= this.stepSize ) {
        html = "";

        $new = $( html );

        // record when each image has loaded
        $new.bind( "load", boundImageLoaded );

        this.$element.append( $new );
        this.$render.append( html );
      }

      this.loadedCount = 0;
    } else {

      // mark the initial image as loaded
      this.$initial.each(function(i, e){
        this.markImageLoaded(e);
      }.bind(this));
    }

    // take all the child images and use them as frames of the rotation
    this.$images = this.$element.children().filter( "img" );
  };

  Tau.prototype.imageLoaded = function( event ) {
    this.markImageLoaded( event.target );
    this.loadedCount++;

    if( this.loadedCount >= this.frames - 1) {
      this.hideLoading();
    }
  };

  Tau.prototype.markImageLoaded = function( element ) {
    element.tauImageLoaded = true;
  };

  Tau.prototype.bind = function() {
    this.$element.bind( "mousedown touchstart", this.track.bind(this) );
  };

  Tau.prototype.autoRotate = function() {
    // already rotating
    if( this.autoInterval ) {
      return;
    }

    this.autoInterval = setInterval(function() {
      this.change( 1 );
    }.bind(this),  this.autoRotateDelay() * this.stepSize);
  };

  Tau.prototype.autoRotateDelay = function(){
    return Tau.autoRotateTraversalTime / this.frames;
  };

  Tau.prototype.stopAutoRotate = function() {
    clearInterval( this.autoInterval );
    this.autoInterval = undefined;
  };

  Tau.prototype.track = function( event ) {
    var point;

    // prevent dragging behavior for mousedown
    if( event.type === "mousedown"  ){
      event.preventDefault();
    }

    if( this.tracking ) {
      return;
    }

    $doc.one( "mouseup", this.release.bind(this) );
    $doc.one( "touchend", this.release.bind(this) );

    this.tracking = true;

    // clean out the path since we'll need a new one for decel
    this.path.reset();

    // show the cursor as grabbing
    this.cursorGrab();

    // calculate/store how many pixels makes for an image switch
    this.rotateThreshold = $doc[0].clientWidth / this.frames;

    // record the x for threshold calculations
    point = this.getPoint( event );
    this.downX = point.x;
    this.downY = point.y;
    this.downIndex = this.index;

    $doc.bind( "mousemove", this.mouseMoveBinding );
    $doc.bind( "touchmove", this.touchMoveBinding );
  };

  Tau.prototype.slow = function() {
    // if the path gets broken during the decel just stop
    if( !this.path.isSufficient() ) {
      this.clearSlowInterval();
      return;
    }

    this.rotate({
      x: this.path.last().x + this.velocity,
      y: this.path.last().y
    });

    if( this.velocity > 0 ){
      this.velocity = this.velocity - this.decelVal();

      if( this.velocity <= 0 ){
        this.clearSlowInterval();
      }
    } else {
      this.velocity = this.velocity + this.decelVal();

      if( this.velocity >= 0 ){
        this.clearSlowInterval();
      }
    }
  };

  Tau.prototype.decelVal = function(){
    return this.decelTimeStep() / 8;
  };

  Tau.prototype.clearSlowInterval = function() {
    clearInterval(this.slowInterval);
    this.velocity = 0;
    this.slowInterval = undefined;
  };

  Tau.prototype.decel = function() {
    var velocity, sign;

    // if we don't have two points of mouse or touch tracking this won't work
    if( !this.path.isSufficient() ) {
      return;
    }

    // determine the starting velocity based on the traced path
    velocity = this.path.velocity( this.decelTimeStep() );

    // borrowed from http://stackoverflow.com/questions/7624920/number-sign-in-javascript
    sign = velocity > 0 ? 1 : velocity < 0 ? -1 : 0;

    // keep a lid on how fast the rotation spins out
    if( Math.abs(velocity) > Tau.maxVelocity ){
      velocity = sign * Tau.maxVelocity;
    }

    this.velocity = velocity;
    this.slowInterval = setInterval(this.slow.bind(this), this.decelTimeStep());
  };

  Tau.prototype.decelTimeStep = function(){
    return this.autoRotateDelay() / 2;
  };

  Tau.prototype.release = function( event ) {
    this.decel();

    this.cursorRelease();

    // TODO sort out why shoestring borks when unbinding with a string split list
    $doc.unbind( "mousemove", this.mouseMoveBinding );
    $doc.unbind( "touchmove", this.touchMoveBinding );

    this.tracking = false;
  };

  Tau.prototype.cursorGrab = function() {
    $doc.addClass( "grabbing" );
  };

  Tau.prototype.cursorRelease = function() {
    $doc.removeClass( "grabbing" );
  };

  Tau.prototype.showLoading = function() {
    this.$loading.attr( "style" , "display: block" );
  };

  Tau.prototype.hideLoading = function() {
    this.$loading.attr( "style" , "display: none" );
  };

  Tau.prototype.getPoint = function( event ) {
    var touch = event.touches || (event.originalEvent && event.originalEvent.touches);

    if( touch ){
      return {
        x: touch[0].pageX,
        y: touch[0].pageY
      };
    }

    return {
      x: event.pageX || event.clientX,
      y: event.pageY || event.clientY
    };
  };

  Tau.prototype.rotateEvent = function( event ) {
    // NOTE it might be better to prevent when the rotation returns anything BUT false
    //      so that slow drags still get the scroll prevented
    if( this.rotate(this.getPoint(event)) ){
      event.preventDefault();
    }
  };

  Tau.prototype.rotate = function( point ) {
    var deltaX, deltaY;

    deltaX = point.x - this.downX;
    deltaY = point.y - this.downY;

    // if the movement on the Y dominates X then skip and allow scroll
    if( Math.abs(deltaY) / Math.abs(deltaX) >= Tau.verticalScrollRatio ) {
      return false;
    }

    // NOTE works better on mousedown, here allows autorotate to continue
    this.stopAutoRotate();

    // since we're rotating record the point for decel
    this.path.record( point );

    // NOTE to reverse the spin direction add the delta/thresh to the downIndex
    if( Math.abs(deltaX) >= this.rotateThreshold ) {
      this.goto( this.downIndex - Math.round(deltaX / this.rotateThreshold) );
      return true;
    }
  };
})(this, jQuery);
<|endoftext|>


<commit_before>$(document).ready(function(){
  var oldScrollY = 0;
  var scrolled = 0;
  var id = "";			// id
  var timeScroll = 1000; //

  window.onscroll = function(event){
	  oldScrollY = scrolled;
	  scrolled = $(window).scrollTop();
	  if ($('html, body').is(':animated')) { // <-   ,
      return;								//
    };
  var dY = scrolled - oldScrollY;
  switch(id) {
  case "":
		if(dY > 1) {
		$('html, body').animate({scrollTop:$("#centerBlock").offset().top}, timeScroll);
		id = "centerBlock";
		}
		break;
  case "centerBlock":
		if(dY > 1) {
		$('html, body').animate({scrollTop:$("#Block1").offset().top}, timeScroll);
		id = "Block1";
		}
		else if (dY < 0) { $('html, body').animate({scrollTop:0}, timeScroll);
		id = "";
        }
		break;
  case "Block1":
		if(dY > 1) {
		  $('html, body').animate({scrollTop:$("#Block2").offset().top}, timeScroll)
		  id = "Block2";
		}
		else if (dY < 0) {$('html, body').animate({scrollTop:$("#centerBlock").offset().top}, timeScroll);
		id = "centerBlock";
		}
		break;
  case "Block2":
		if(dY < 0) {
		$('html, body').animate({scrollTop:$("#Block1").offset().top}, timeScroll);
		id = "Block1";
		}
		else if(dY > 1) {
		  $('html, body').animate({scrollTop:$("#footer").offset().top}, 500)
		  id = "footer";
		}
		break;
  case "footer":
		if(dY < 0) {
		  $('html, body').animate({scrollTop:$("#Block2").offset().top}, 500);
		  id = "Block2";
		}
		break;
  }
  };
});<commit_msg>13.11.17 10:03<commit_after>$(document).ready(function(){
  if (window.innerWidth < 600) {return}
  var oldScrollY = 0;
  var scrolled = 0;
  var id = "";			// id
  var timeScroll = 1000; //

  window.onscroll = function(event){
	  oldScrollY = scrolled;
	  scrolled = $(window).scrollTop();
	  if ($('html, body').is(':animated')) { // <-   ,
      return;								//
    };
  var dY = scrolled - oldScrollY;
  switch(id) {
  case "":
		if(dY > 1) {
		$('html, body').animate({scrollTop:$("#centerBlock").offset().top}, timeScroll);
		id = "centerBlock";
		}
		break;
  case "centerBlock":
		if(dY > 1) {
		$('html, body').animate({scrollTop:$("#Block1").offset().top}, timeScroll);
		id = "Block1";
		}
		else if (dY < 0) { $('html, body').animate({scrollTop:0}, timeScroll);
		id = "";
        }
		break;
  case "Block1":
		if(dY > 1) {
		  $('html, body').animate({scrollTop:$("#Block2").offset().top}, timeScroll)
		  id = "Block2";
		}
		else if (dY < 0) {$('html, body').animate({scrollTop:$("#centerBlock").offset().top}, timeScroll);
		id = "centerBlock";
		}
		break;
  case "Block2":
		if(dY < 0) {
		$('html, body').animate({scrollTop:$("#Block1").offset().top}, timeScroll);
		id = "Block1";
		}
		else if(dY > 1) {
		  $('html, body').animate({scrollTop:$("#footer").offset().top}, 500)
		  id = "footer";
		}
		break;
  case "footer":
		if(dY < 0) {
		  $('html, body').animate({scrollTop:$("#Block2").offset().top}, 500);
		  id = "Block2";
		}
		break;
  }
  };
});<|endoftext|>


<commit_before>var rAppid;

/** ECMA SCRIPT COMPLIANT**/
if(!String.prototype.trim){
    String.prototype.trim = function () {
        return this.replace(/^\s+|\s+$/g, '');
    };
}

(function (exports, inherit, requirejs, define, underscore, XMLHttpRequest, flow, document) {

    if (!requirejs) {
        throw "require.js is needed";
    }

    if (!define) {
        throw "define is needed";
    }

    if (!underscore) {
        throw "underscore is needed"
    }

    if (!flow) {
        throw "flow.js is needed";
    }

    /***
     * marks a function to be executed asycn
     * @return {*}
     */
    Function.prototype.async = function () {
        this._async = true;
        return this;
    };

    // global requirejs setup
    requirejs.config({
        paths: {
            "xaml": "js/plugins/xaml",
            "json": "js/plugins/json"
        }
    });

    var xamlApplication = /^(xaml!)?(.+?)(\.xml)?$/;

    var Rewrite = function (from, to) {
            this.$from = from;
            this.$to = to;
        },
        defaultNamespaceMap = {
            "http://www.w3.org/1999/xhtml": "js.html"
        },
        defaultRewriteMap = [
            new Rewrite(/^js\/html\/(a)$/, "js/html/a"),
            new Rewrite(/^js\/html\/(input)$/, "js/html/Input"),
            new Rewrite(/^js\/html\/(select)$/, "js/html/Select"),
            new Rewrite(/^js\/html\/(textarea)$/, "js/html/TextArea"),
            new Rewrite(/^js\/html\/(option)$/, "js/html/Option"),
            new Rewrite(/^js\/html\/(.+)$/, "js/html/DomElement")
        ];

    var _rAppid = {

        createApplicationContext: function(applicationDomain, mainClass, config, callback) {

            config = config || {};

            var internalCreateApplicationContext = function (config) {

                config.xamlClasses = config.xamlClasses || [];
                config.namespaceMap = config.namespaceMap || defaultNamespaceMap;
                config.rewriteMap = config.rewriteMap || defaultRewriteMap;

                define("flow", function () {
                    return flow;
                });

                define("flow.js", function () {
                    return flow;
                });

                define("inherit", function () {
                    return inherit;
                });

                define("underscore", function() {
                    return underscore;
                });

                underscore.extend(config, {
                    paths: {
                        "xaml": "js/plugins/xaml",
                        "json": "js/plugins/json"
                    }
                });

                // and add it to config object, so it can used from xaml.js
                config.applicationDomain = applicationDomain;

                var requirejsContext = requirejs.config(config);

                var applicationContext = new ApplicationContext(requirejsContext, config);
                //applicationContext.document = document;

                define("rAppid", function () {
                    return applicationContext;
                });

                if (mainClass) {
                    //TODO: have a look at xamlClasses
                    var parts = xamlApplication.exec(mainClass);
                    if (parts) {
                        // mainClass is xaml
                        mainClass = "xaml!" + parts[2];
                    } else {
                        // mainClass is javascript factory
                        mainClass = mainClass.replace(/\./g, "/");
                    }

                    requirejsContext(["require"], function () {
                        requirejsContext([mainClass], function (applicationFactory) {
                            applicationContext.$applicationFactory = applicationFactory;
                            callback(null, applicationContext);
                        });
                    });

                } else {
                    callback(null, applicationContext);
                }

            };

            if (Object.prototype.toString.call(config) == '[object String]') {
                requirejs(["json!" + config], function (config) {
                    internalCreateApplicationContext(config);
                });
            } else {
                internalCreateApplicationContext(config);
            }

        },

        bootStrap: function (mainClass, config, callback) {
            _rAppid.createApplicationContext(null, mainClass, config, function(err, applicationContext){
                if (err || !applicationContext) {
                    callback(err || "ApplicationContext missing");
                } else {
                    applicationContext.createApplicationInstance(document, callback);
                }
            })
        },

        rewriteMapEntry: Rewrite,

        createQueryString: function(parameter) {
            var ret = [];

            for (var key in parameter) {
                if (parameter.hasOwnProperty(key)) {
                    ret.push(encodeURIComponent(key) + "=" + encodeURIComponent(parameter[key]));
                }
            }

            return ret.join("&");
        },

        ajax: function(url, options, callback) {

            var s = {
                url: url
            };

            underscore.extend(s, options, _rAppid.ajaxSettings);

            if (s.data && !underscore.isString(s.data)) {
                throw "data must be a string";
            }

            s.hasContent = !/^(?:GET|HEAD)$/.test(s.type);

            if (s.queryParameter && underscore.keys(s.queryParameter).length > 0) {
                // append query parameter to url
                s.url += /\?/.test(s.url) ? "&" : "?" + this.createQueryString(s.queryParameter);
            }

            if (s.data && s.hasContent && s.contentType !== false) {
                xhr.setRequestHeader("Content-Type", s.contentType);
            }

            // create new xhr
            var xhr = s.xhr();
            xhr.open(s.type, s.url, s.async);

            try {
                for (var header in s.headers) {
                    if (s.headers.hasOwnProperty(header)) {
                        xhr.setRequestHeader(header, s.headers[header]);
                    }
                }
            } catch (e) {} // FF3

            xhr.send();

            var xhrCallback = function(_, isAbort) {

                var wrappedXhr;

                if (xhrCallback && (isAbort || xhr.readyState === 4)) {
                    xhrCallback = undefined;

                    if (isAbort) {
                        // Abort it manually if needed
                        if (xhr.readyState !== 4) {
                            xhr.abort();
                        }
                    } else {
                        wrappedXhr = new rAppidXhr(xhr);
                    }

                    if (callback) {
                        callback(isAbort, wrappedXhr)
                    }
                }
            };

            if (!s.async || xhr.readyState === 4) {
                xhrCallback();
            } else {
                xhr.onreadystatechange = xhrCallback
            }

            return xhr;
        }
    };

    var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg; // IE leaves an \r character at EOL

    var rAppidXhr = inherit.Base.inherit({
        ctor: function(xhr) {
            this.xhr = xhr;
            this.status = xhr.status;
            this.$nativeResponseHeaders = xhr.getAllResponseHeaders();
            this.responses = {};

            var xml = xhr.responseXML;

            // Construct response list
            if (xml && xml.documentElement) {
                this.responses.xml = xml;
            }
            this.responses.text = xhr.responseText;

            try {
                this.statusText = xhr.statusText;
            } catch (e) {
                this.statusText = "";
            }
        },
        getResponseHeader: function(key) {
            var match;
            if (!this.$responseHeaders) {
                this.$responseHeaders = {};
                while (( match = rheaders.exec(this.$nativeResponseHeaders) )) {
                    this.$responseHeaders[match[1].toLowerCase()] = match[2];
                }
            }
            return this.$responseHeaders[key.toLowerCase()];
        }

    });

    _rAppid.ajaxSettings = {
        type: "GET",
        contentType: "application/x-www-form-urlencoded",
        async: true,
        // TODO: add ie7 support for local file requests via ActiveX
        xhr: function() {
            return new XMLHttpRequest();
        },
        headers: {
        }
    };

    var SystemManager = _rAppid.SystemManager = inherit.Base.inherit({
        ctor: function (requirejsContext, applicationContext, document) {
            this.$requirejsContext = requirejsContext;
            this.$applicationContext = applicationContext;
            this.$applicationFactory = null;
            this.$document = document;
        }
    });

    var ApplicationContext = _rAppid.ApplicationContext = SystemManager.inherit({

        ctor: function(requirejsContext, config) {
            this.callBase(requirejsContext);
            this.$config = config;
            this.$applicationContext = this;
        },

        createApplicationInstance: function(document, callback) {
            // create instance
            var applicationFactory = this.$applicationFactory;

            var systemManager = new SystemManager(this.$requirejsContext, this, document);

            this.$requirejsContext(["js/core/Application"], function(Application) {

                var application = new applicationFactory(null, false, systemManager, null, null);

                if (application instanceof Application) {

                    systemManager.$application = application;

                    application._initialize("auto");

                    // return rAppid instance
                    if (callback) {
                        callback(null, systemManager, application);
                    }

                } else {
                    var errMessage = "mainClass isn't an instance of js.core.Application";
                    if (callback) {
                        callback(errMessage);
                    } else {
                        throw(errMessage);
                    }
                }
            });

        },

        getFqClassName: function (namespace, className, useRewriteMap) {
            if (useRewriteMap == undefined || useRewriteMap == null) {
                useRewriteMap = true;
            }

            if (namespace && className) {
                namespace = (this.$config.namespaceMap[namespace] || namespace).replace(/\./g, '/');
                var fqClassName = [namespace, className].join("/");
            } else {
                fqClassName = (namespace || className).replace(/\./g, '/');
            }

            if (underscore.indexOf(this.$config.xamlClasses, fqClassName) !== -1) {
                fqClassName = 'xaml!'+ fqClassName;
            }

            if (useRewriteMap) {
                for (var i = 0; i < this.$config.rewriteMap.length; i++) {
                    var entry = this.$config.rewriteMap[i];
                    if (entry instanceof rAppid.rewriteMapEntry) {
                        if (entry.$from.test(fqClassName)) {
                            return fqClassName.replace(entry.$from, entry.$to);
                        }
                    }
                }
            }

            return fqClassName;
        },

        createInstance: function (fqClassName, args, className) {
            className = className || fqClassName;
            args = args || [];

            fqClassName = fqClassName.replace(/\./g, "/");

            var classDefinition = this.$requirejsContext(fqClassName);

            function construct(constructor, args) {
                function F() {
                    return constructor.apply(this, args);
                }

                F.prototype = constructor.prototype;
                return new F();
            }

            var ret;
            try {
                ret = construct(classDefinition, args);
                ret.className = className;
            } catch (e) {
                console.log("Cannot create instance of '" + fqClassName + "'");
            }

            return ret;
        },

        ajax: function(url, options, callback) {

            if (!(/^http.*$/.test(url)) && this.$config.applicationUrl) {
                url = this.$config.applicationUrl + '/' + url;
            }

            _rAppid.ajax(url, options, callback);
        }

    });

    rAppid = exports.rAppid = _rAppid;

})(typeof exports === "undefined" ? this : exports,
   typeof inherit === "undefined" ? require('inherit.js').inherit : inherit,
    typeof requirejs === "undefined" ? require('requirejs') : requirejs,
    typeof requirejs === "undefined" ? require('requirejs').define : define,
    typeof this._ === "undefined" ? require('underscore') : this._,
    typeof window === "undefined" ? require('xmlhttprequest').XMLHttpRequest : window.XMLHttpRequest,
    typeof flow === "undefined" ? require('flow.js').flow : flow,
    typeof document === "undefined" ? (new (require('xmldom').DOMParser)()) : document);
<commit_msg>added console log hack for IE<commit_after>var rAppid;

/** ECMA SCRIPT COMPLIANT**/
if(!String.prototype.trim){
    String.prototype.trim = function () {
        return this.replace(/^\s+|\s+$/g, '');
    };
}

if(!console){
    var console = {
        log : function(){},
        warn: function(){}
    }
}

(function (exports, inherit, requirejs, define, underscore, XMLHttpRequest, flow, document) {

    if (!requirejs) {
        throw "require.js is needed";
    }

    if (!define) {
        throw "define is needed";
    }

    if (!underscore) {
        throw "underscore is needed"
    }

    if (!flow) {
        throw "flow.js is needed";
    }

    /***
     * marks a function to be executed asycn
     * @return {*}
     */
    Function.prototype.async = function () {
        this._async = true;
        return this;
    };

    // global requirejs setup
    requirejs.config({
        paths: {
            "xaml": "js/plugins/xaml",
            "json": "js/plugins/json"
        }
    });

    var xamlApplication = /^(xaml!)?(.+?)(\.xml)?$/;

    var Rewrite = function (from, to) {
            this.$from = from;
            this.$to = to;
        },
        defaultNamespaceMap = {
            "http://www.w3.org/1999/xhtml": "js.html"
        },
        defaultRewriteMap = [
            new Rewrite(/^js\/html\/(a)$/, "js/html/a"),
            new Rewrite(/^js\/html\/(input)$/, "js/html/Input"),
            new Rewrite(/^js\/html\/(select)$/, "js/html/Select"),
            new Rewrite(/^js\/html\/(textarea)$/, "js/html/TextArea"),
            new Rewrite(/^js\/html\/(option)$/, "js/html/Option"),
            new Rewrite(/^js\/html\/(.+)$/, "js/html/DomElement")
        ];

    var _rAppid = {

        createApplicationContext: function(applicationDomain, mainClass, config, callback) {

            config = config || {};

            var internalCreateApplicationContext = function (config) {

                config.xamlClasses = config.xamlClasses || [];
                config.namespaceMap = config.namespaceMap || defaultNamespaceMap;
                config.rewriteMap = config.rewriteMap || defaultRewriteMap;

                define("flow", function () {
                    return flow;
                });

                define("flow.js", function () {
                    return flow;
                });

                define("inherit", function () {
                    return inherit;
                });

                define("underscore", function() {
                    return underscore;
                });

                underscore.extend(config, {
                    paths: {
                        "xaml": "js/plugins/xaml",
                        "json": "js/plugins/json"
                    }
                });

                // and add it to config object, so it can used from xaml.js
                config.applicationDomain = applicationDomain;

                var requirejsContext = requirejs.config(config);

                var applicationContext = new ApplicationContext(requirejsContext, config);
                //applicationContext.document = document;

                define("rAppid", function () {
                    return applicationContext;
                });

                if (mainClass) {
                    //TODO: have a look at xamlClasses
                    var parts = xamlApplication.exec(mainClass);
                    if (parts) {
                        // mainClass is xaml
                        mainClass = "xaml!" + parts[2];
                    } else {
                        // mainClass is javascript factory
                        mainClass = mainClass.replace(/\./g, "/");
                    }

                    requirejsContext(["require"], function () {
                        requirejsContext([mainClass], function (applicationFactory) {
                            applicationContext.$applicationFactory = applicationFactory;
                            callback(null, applicationContext);
                        });
                    });

                } else {
                    callback(null, applicationContext);
                }

            };

            if (Object.prototype.toString.call(config) == '[object String]') {
                requirejs(["json!" + config], function (config) {
                    internalCreateApplicationContext(config);
                });
            } else {
                internalCreateApplicationContext(config);
            }

        },

        bootStrap: function (mainClass, config, callback) {
            _rAppid.createApplicationContext(null, mainClass, config, function(err, applicationContext){
                if (err || !applicationContext) {
                    callback(err || "ApplicationContext missing");
                } else {
                    applicationContext.createApplicationInstance(document, callback);
                }
            })
        },

        rewriteMapEntry: Rewrite,

        createQueryString: function(parameter) {
            var ret = [];

            for (var key in parameter) {
                if (parameter.hasOwnProperty(key)) {
                    ret.push(encodeURIComponent(key) + "=" + encodeURIComponent(parameter[key]));
                }
            }

            return ret.join("&");
        },

        ajax: function(url, options, callback) {

            var s = {
                url: url
            };

            underscore.extend(s, options, _rAppid.ajaxSettings);

            if (s.data && !underscore.isString(s.data)) {
                throw "data must be a string";
            }

            s.hasContent = !/^(?:GET|HEAD)$/.test(s.type);

            if (s.queryParameter && underscore.keys(s.queryParameter).length > 0) {
                // append query parameter to url
                s.url += /\?/.test(s.url) ? "&" : "?" + this.createQueryString(s.queryParameter);
            }

            if (s.data && s.hasContent && s.contentType !== false) {
                xhr.setRequestHeader("Content-Type", s.contentType);
            }

            // create new xhr
            var xhr = s.xhr();
            xhr.open(s.type, s.url, s.async);

            try {
                for (var header in s.headers) {
                    if (s.headers.hasOwnProperty(header)) {
                        xhr.setRequestHeader(header, s.headers[header]);
                    }
                }
            } catch (e) {} // FF3

            xhr.send();

            var xhrCallback = function(_, isAbort) {

                var wrappedXhr;

                if (xhrCallback && (isAbort || xhr.readyState === 4)) {
                    xhrCallback = undefined;

                    if (isAbort) {
                        // Abort it manually if needed
                        if (xhr.readyState !== 4) {
                            xhr.abort();
                        }
                    } else {
                        wrappedXhr = new rAppidXhr(xhr);
                    }

                    if (callback) {
                        callback(isAbort, wrappedXhr)
                    }
                }
            };

            if (!s.async || xhr.readyState === 4) {
                xhrCallback();
            } else {
                xhr.onreadystatechange = xhrCallback
            }

            return xhr;
        }
    };

    var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg; // IE leaves an \r character at EOL

    var rAppidXhr = inherit.Base.inherit({
        ctor: function(xhr) {
            this.xhr = xhr;
            this.status = xhr.status;
            this.$nativeResponseHeaders = xhr.getAllResponseHeaders();
            this.responses = {};

            var xml = xhr.responseXML;

            // Construct response list
            if (xml && xml.documentElement) {
                this.responses.xml = xml;
            }
            this.responses.text = xhr.responseText;

            try {
                this.statusText = xhr.statusText;
            } catch (e) {
                this.statusText = "";
            }
        },
        getResponseHeader: function(key) {
            var match;
            if (!this.$responseHeaders) {
                this.$responseHeaders = {};
                while (( match = rheaders.exec(this.$nativeResponseHeaders) )) {
                    this.$responseHeaders[match[1].toLowerCase()] = match[2];
                }
            }
            return this.$responseHeaders[key.toLowerCase()];
        }

    });

    _rAppid.ajaxSettings = {
        type: "GET",
        contentType: "application/x-www-form-urlencoded",
        async: true,
        // TODO: add ie7 support for local file requests via ActiveX
        xhr: function() {
            return new XMLHttpRequest();
        },
        headers: {
        }
    };

    var SystemManager = _rAppid.SystemManager = inherit.Base.inherit({
        ctor: function (requirejsContext, applicationContext, document) {
            this.$requirejsContext = requirejsContext;
            this.$applicationContext = applicationContext;
            this.$applicationFactory = null;
            this.$document = document;
        }
    });

    var ApplicationContext = _rAppid.ApplicationContext = SystemManager.inherit({

        ctor: function(requirejsContext, config) {
            this.callBase(requirejsContext);
            this.$config = config;
            this.$applicationContext = this;
        },

        createApplicationInstance: function(document, callback) {
            // create instance
            var applicationFactory = this.$applicationFactory;

            var systemManager = new SystemManager(this.$requirejsContext, this, document);

            this.$requirejsContext(["js/core/Application"], function(Application) {

                var application = new applicationFactory(null, false, systemManager, null, null);

                if (application instanceof Application) {

                    systemManager.$application = application;

                    application._initialize("auto");

                    // return rAppid instance
                    if (callback) {
                        callback(null, systemManager, application);
                    }

                } else {
                    var errMessage = "mainClass isn't an instance of js.core.Application";
                    if (callback) {
                        callback(errMessage);
                    } else {
                        throw(errMessage);
                    }
                }
            });

        },

        getFqClassName: function (namespace, className, useRewriteMap) {
            if (useRewriteMap == undefined || useRewriteMap == null) {
                useRewriteMap = true;
            }

            if (namespace && className) {
                namespace = (this.$config.namespaceMap[namespace] || namespace).replace(/\./g, '/');
                var fqClassName = [namespace, className].join("/");
            } else {
                fqClassName = (namespace || className).replace(/\./g, '/');
            }

            if (underscore.indexOf(this.$config.xamlClasses, fqClassName) !== -1) {
                fqClassName = 'xaml!'+ fqClassName;
            }

            if (useRewriteMap) {
                for (var i = 0; i < this.$config.rewriteMap.length; i++) {
                    var entry = this.$config.rewriteMap[i];
                    if (entry instanceof rAppid.rewriteMapEntry) {
                        if (entry.$from.test(fqClassName)) {
                            return fqClassName.replace(entry.$from, entry.$to);
                        }
                    }
                }
            }

            return fqClassName;
        },

        createInstance: function (fqClassName, args, className) {
            className = className || fqClassName;
            args = args || [];

            fqClassName = fqClassName.replace(/\./g, "/");

            var classDefinition = this.$requirejsContext(fqClassName);

            function construct(constructor, args) {
                function F() {
                    return constructor.apply(this, args);
                }

                F.prototype = constructor.prototype;
                return new F();
            }

            var ret;
            try {
                ret = construct(classDefinition, args);
                ret.className = className;
            } catch (e) {
                console.log("Cannot create instance of '" + fqClassName + "'");
            }

            return ret;
        },

        ajax: function(url, options, callback) {

            if (!(/^http.*$/.test(url)) && this.$config.applicationUrl) {
                url = this.$config.applicationUrl + '/' + url;
            }

            _rAppid.ajax(url, options, callback);
        }

    });

    rAppid = exports.rAppid = _rAppid;

})(typeof exports === "undefined" ? this : exports,
   typeof inherit === "undefined" ? require('inherit.js').inherit : inherit,
    typeof requirejs === "undefined" ? require('requirejs') : requirejs,
    typeof requirejs === "undefined" ? require('requirejs').define : define,
    typeof this._ === "undefined" ? require('underscore') : this._,
    typeof window === "undefined" ? require('xmlhttprequest').XMLHttpRequest : window.XMLHttpRequest,
    typeof flow === "undefined" ? require('flow.js').flow : flow,
    typeof document === "undefined" ? (new (require('xmldom').DOMParser)()) : document);
<|endoftext|>