<commit_before>(function(root, undefined) {

	// Variablizing the strings for consistency
	// and to avoid harmful dot-notation look-ups with
	// javascript keywords
	var sNull      = 'Null',
		sUndefined = 'Undefined',
		sInfinity  = 'Infinity',
		sDate      = 'Date',
		sNaN       = 'NaN',
		sNumber    = 'Number',
		sString    = 'String',
		sObject    = 'Object',
		sArray     = 'Array',
		sRegExp    = 'RegExp',
		sBoolean   = 'Boolean',
		sFunction  = 'Function',
		sElement   = 'Element';

	// Utilizing the non-standard (but available in modern browsers) Global Object names
	// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
	// Provide a polyfill for items without names
	(function() {
		var globalObjects = [
				sDate,
				sNumber,
				sString,
				sObject,
				sArray,
				sRegExp,
				sBoolean,
				sFunction,
				sElement
			],
			idx = globalObjects.length,
			globalObject;
		while (idx--) {
			globalObject = globalObjects[idx];
			if (!root[globalObject].name) {
				root[globalObject].name = globalObject;
			}
		}
	}());

	/**
	 * Possible values
	 * @type {Object}
	 */
	var _types = {};
	_types[sNull]      = 0;
	_types[sUndefined] = 1;
	_types[sInfinity]  = 2;
	_types[sDate]      = 3;
	_types[sNaN]       = 4;
	_types[sNumber]    = 5;
	_types[sString]    = 6;
	_types[sObject]    = 7;
	_types[sArray]     = 8;
	_types[sRegExp]    = 9;
	_types[sBoolean]   = 10;
	_types[sFunction]  = 11;
	_types[sElement]   = 12;

	/**
	 * Cached reference to Object.prototype.toString
	 * for type checking
	 * @type {Function}
	 */
	var _toString = (function(toString) {
			return function(obj) {
				return toString.call(obj);
			};
		}(({}).toString)),

		/**
		 * Type checks
		 */
		_checkMap = (function(map) {

			var types = [
					// Only mapping items that need to be mapped.
					// Items not in this list are doing faster
					// (non-string) checks
					//
					// k = key, v = value
					{ k: sDate,     v: _types[sDate]     },
					{ k: sNumber,   v: _types[sNumber]   },
					{ k: sString,   v: _types[sString]   },
					{ k: sObject,   v: _types[sObject]   },
					{ k: sArray,    v: _types[sArray]    },
					{ k: sRegExp,   v: _types[sRegExp]   },
					{ k: sFunction, v: _types[sFunction] }
				],
				idx = types.length;
			while (idx--) {
				map['[object ' + types[idx].k + ']'] = types[idx].v;
			}

			return map;

		}({})),

		/**
		 * Changes arguments to an array
		 * @param  {Arguments} arraylike
		 * @return {Array}
		 */
		_toArray = function(arraylike) {
			var arr = [],
				idx = 0, length = arraylike.length;
			for (; idx < length; idx++) {
				arr[idx] = arraylike[idx];
			}
			return arr;
		};

	var _getConfigurationType = function(val) {
		if (val === null) { return _types[sNull]; }
		if (val === undefined) { return _types[sUndefined]; }

		// we have something, but don't know what
		if (val.name === undefined) {
			if (val !== +val) { return _types[sNaN]; } // NaN check
			return _types[sInfinity]; // Infinity check
		}

		return _types[val.name];
	};

	var _getParameterType = function(val) {
		if (val === null) { return _types[sNull]; }
		if (val === undefined) { return _types[sUndefined]; }
		if (val === true || val === false) { return _types[sBoolean]; }
		if (!!(val && val.nodeType === 1)) { return _types[sElement]; } // Element check from Underscore

		var typeString = _toString(val);
		if (_checkMap[typeString] === _types[sNumber]) {
			if (val !== +val) { return _types[sNaN]; } // NaN check
			if (!isFinite(val)) { return _types[sInfinity]; } // Finite check
			return _types[sNumber]; // definitely a number
		}

		return _checkMap[typeString];
	};

	var _convertConfigurationTypes = function(args) {
		var parameters = [],
			idx = 0, length = args.length,
			configItem;
		for (; idx < length; idx++) {
			configItem = args[idx];
			parameters.push(
				(configItem instanceof Custom) ? configItem : _getConfigurationType(configItem)
			);
		}
		return parameters;
	};

	var _convertParametersTypes = function(args) {
		var parameters = [],
			idx = 0, length = args.length;
		for (; idx < length; idx++) {
			parameters.push(_getParameterType(args[idx]));
		}
		return parameters;
	};

	var _doesMapMatchArgsTypes = function(map, argTypes, args) {
		var mapLength = map.length,
			argLength = argTypes.length;

		if (mapLength === 0 && argLength === 0) { return true; }
		if (mapLength !== argLength) { return false; }

		var idx = 0,
			mapItem;
		for (; idx < argLength; idx++) {
			mapItem = map[idx];

			if (mapItem instanceof Custom) {
				if (mapItem.check(args[idx])) {
					continue;
				} else {
					return false;
				}
			}

			if (argTypes[idx] !== mapItem) {
				return false;
			}
		}

		return true;
	};

	var _getArgumentMatch = function(mappings, args) {
		mappings = mappings || [];

		var argTypes = _convertParametersTypes(args),
			idx = 0, length = mappings.length;
		for (; idx < length; idx++) {
			if (_doesMapMatchArgsTypes(mappings[idx].params, argTypes, args)) {
				return mappings[idx];
			}
		}

		return null;
	};

	var _getLengthMatch = function(mappings, args) {
		mappings = mappings || [];

		var argLength = args.length,
			idx = 0, length = mappings.length;
		for (; idx < length; idx++) {
			if (mappings[idx].length === argLength) {
				return mappings[idx];
			}
		}

		return null;
	};

	var _matchAny = function(args, val) {
		var type = _getParameterType(val),
			idx = args.length,
			mapItem;

		while (idx--) {
			mapItem = args[idx];

			if (mapItem instanceof Custom) {
				if (mapItem.check(args[idx])) {
					return true;
				} else {
					return false;
				}
			}

			if (args[idx] === type) {
				return true;
			}
		}

		return false;
	};

	/**
	 * Custom type that validates a value
	 * @constructor
	 * @param {Function} check
	 */
	var Custom = function(check) {
		this.check = check;
	};

	var O = {
		truthy: new Custom(function(val) {
			return (!!val) === true;
		}),
		falsy: new Custom(function(val) {
			return (!!val) === false;
		}),
		any: function() {
			var args = _convertConfigurationTypes(arguments);
			return new Custom(function(val) {
				return _matchAny(args, val);
			});
		},
		except: function() {
			var args = _convertConfigurationTypes(arguments);
			return new Custom(function(val) {
				return !_matchAny(args, val);
			});
		}
	};

	/**
	 * @constructor
	 */
	var Overload = function() {
		if (!(this instanceof Overload)) { return new Overload(); }

		/**
		 * Methods mapped to argument types
		 * Lazily instanciated
		 * @type {Array}
		 */
		// this._argMaps;

		/**
		 * Methods mapped to argument lengths
		 * Lazily instanciated
		 * @type {Array}
		 */
		// this._lenMaps;

		/**
		 * A fallback function if none
		 * of the criteria match on a call
		 * @type {Function}
		 */
		// this._f;
	};

	Overload.defineType = function(name, check) {
		var custom = new Custom(check);
		return (O[name] = custom);
	};

	Overload.prototype = {

		/** @constructor */
		constructor: Overload,

		args: function() {
			var self = this,
				args = arguments;

			return {
				use: function(method) {
					var argMappings = self._argMaps || (self._argMaps = []);
					argMappings.push({
						params: _convertConfigurationTypes(args),
						method: method
					});
					return self;
				}
			};
		},

		length: function(num) {
			var self = this;
			return {
				use: function(method) {
					var lengthMappings = self._lenMaps || (self._lenMaps = []);
					lengthMappings.push({
						length: (num === undefined) ? method.length : num,
						method: method
					});
					return self;
				}
			};
		},

		err: function(args) {
			throw new Error('No methods matched arguments: ', args, this);
		},

		fallback: function(method) {
			this._f = method;
		},

		call: function() {
			var args = _toArray(arguments);
			return this._call(args.shift(), args);
		},

		apply: function(context, args) {
			return this._call(context, args);
		},

		bind: function(context) {
			var self = this;
			return function() {
				return self._call(context, arguments);
			}.bind(context);
		},

		expose: function() {
			var self = this;
			return function() {
				return self._call(this, arguments);
			};
		},

		_call: function(context, args) {
			args = args || [];

			// Any argument match, of course, already matches
			// the length match, so this should be done first
			var argMatch = _getArgumentMatch(this._argMaps, args);
			if (argMatch) {
				return argMatch.method.apply(context, args);
			}

			// Check for a length match
			var lengthMatch = _getLengthMatch(this._lenMaps, args);
			if (lengthMatch) {
				return lengthMatch.method.apply(context, args);
			}

			// Check for a fallback
			if (this._f) {
				return this._f.apply(context, args);
			}

			// Error
			return this.err(args);
		}
	};

	root.Overload = Overload;
	root.O = O;

}(this));<commit_msg>Replace toArray with a faster slice call<commit_after>(function(root, undefined) {

	// Variablizing the strings for consistency
	// and to avoid harmful dot-notation look-ups with
	// javascript keywords
	var sNull      = 'Null',
		sUndefined = 'Undefined',
		sInfinity  = 'Infinity',
		sDate      = 'Date',
		sNaN       = 'NaN',
		sNumber    = 'Number',
		sString    = 'String',
		sObject    = 'Object',
		sArray     = 'Array',
		sRegExp    = 'RegExp',
		sBoolean   = 'Boolean',
		sFunction  = 'Function',
		sElement   = 'Element';

	// Utilizing the non-standard (but available in modern browsers) Global Object names
	// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
	// Provide a polyfill for items without names
	(function() {
		var globalObjects = [
				sDate,
				sNumber,
				sString,
				sObject,
				sArray,
				sRegExp,
				sBoolean,
				sFunction,
				sElement
			],
			idx = globalObjects.length,
			globalObject;
		while (idx--) {
			globalObject = globalObjects[idx];
			if (!root[globalObject].name) {
				root[globalObject].name = globalObject;
			}
		}
	}());

	/**
	 * Possible values
	 * @type {Object}
	 */
	var _types = {};
	_types[sNull]      = 0;
	_types[sUndefined] = 1;
	_types[sInfinity]  = 2;
	_types[sDate]      = 3;
	_types[sNaN]       = 4;
	_types[sNumber]    = 5;
	_types[sString]    = 6;
	_types[sObject]    = 7;
	_types[sArray]     = 8;
	_types[sRegExp]    = 9;
	_types[sBoolean]   = 10;
	_types[sFunction]  = 11;
	_types[sElement]   = 12;

	/**
	 * Cached reference to Object.prototype.toString
	 * for type checking
	 * @type {Function}
	 */
	var _toString = (function(toString) {
			return function(obj) {
				return toString.call(obj);
			};
		}(({}).toString)),

		/**
		 * Type checks
		 */
		_checkMap = (function(map) {

			var types = [
					// Only mapping items that need to be mapped.
					// Items not in this list are doing faster
					// (non-string) checks
					//
					// k = key, v = value
					{ k: sDate,     v: _types[sDate]     },
					{ k: sNumber,   v: _types[sNumber]   },
					{ k: sString,   v: _types[sString]   },
					{ k: sObject,   v: _types[sObject]   },
					{ k: sArray,    v: _types[sArray]    },
					{ k: sRegExp,   v: _types[sRegExp]   },
					{ k: sFunction, v: _types[sFunction] }
				],
				idx = types.length;
			while (idx--) {
				map['[object ' + types[idx].k + ']'] = types[idx].v;
			}

			return map;

		}({})),

		/**
		 * Changes arguments to an array
		 * @param  {Arguments} arraylike
		 * @return {Array}
		 */
		_slice = (function(slice) {
			return function(arraylike) {
				return slice.call(arraylike);
			};
		}([].slice));
			}
			return arr;
		};

	var _getConfigurationType = function(val) {
		if (val === null) { return _types[sNull]; }
		if (val === undefined) { return _types[sUndefined]; }

		// we have something, but don't know what
		if (val.name === undefined) {
			if (val !== +val) { return _types[sNaN]; } // NaN check
			return _types[sInfinity]; // Infinity check
		}

		return _types[val.name];
	};

	var _getParameterType = function(val) {
		if (val === null) { return _types[sNull]; }
		if (val === undefined) { return _types[sUndefined]; }
		if (val === true || val === false) { return _types[sBoolean]; }
		if (!!(val && val.nodeType === 1)) { return _types[sElement]; } // Element check from Underscore

		var typeString = _toString(val);
		if (_checkMap[typeString] === _types[sNumber]) {
			if (val !== +val) { return _types[sNaN]; } // NaN check
			if (!isFinite(val)) { return _types[sInfinity]; } // Finite check
			return _types[sNumber]; // definitely a number
		}

		return _checkMap[typeString];
	};

	var _convertConfigurationTypes = function(args) {
		var parameters = [],
			idx = 0, length = args.length,
			configItem;
		for (; idx < length; idx++) {
			configItem = args[idx];
			parameters.push(
				(configItem instanceof Custom) ? configItem : _getConfigurationType(configItem)
			);
		}
		return parameters;
	};

	var _convertParametersTypes = function(args) {
		var parameters = [],
			idx = 0, length = args.length;
		for (; idx < length; idx++) {
			parameters.push(_getParameterType(args[idx]));
		}
		return parameters;
	};

	var _doesMapMatchArgsTypes = function(map, argTypes, args) {
		var mapLength = map.length,
			argLength = argTypes.length;

		if (mapLength === 0 && argLength === 0) { return true; }
		if (mapLength !== argLength) { return false; }

		var idx = 0,
			mapItem;
		for (; idx < argLength; idx++) {
			mapItem = map[idx];

			if (mapItem instanceof Custom) {
				if (mapItem.check(args[idx])) {
					continue;
				} else {
					return false;
				}
			}

			if (argTypes[idx] !== mapItem) {
				return false;
			}
		}

		return true;
	};

	var _getArgumentMatch = function(mappings, args) {
		mappings = mappings || [];

		var argTypes = _convertParametersTypes(args),
			idx = 0, length = mappings.length;
		for (; idx < length; idx++) {
			if (_doesMapMatchArgsTypes(mappings[idx].params, argTypes, args)) {
				return mappings[idx];
			}
		}

		return null;
	};

	var _getLengthMatch = function(mappings, args) {
		mappings = mappings || [];

		var argLength = args.length,
			idx = 0, length = mappings.length;
		for (; idx < length; idx++) {
			if (mappings[idx].length === argLength) {
				return mappings[idx];
			}
		}

		return null;
	};

	var _matchAny = function(args, val) {
		var type = _getParameterType(val),
			idx = args.length,
			mapItem;

		while (idx--) {
			mapItem = args[idx];

			if (mapItem instanceof Custom) {
				if (mapItem.check(args[idx])) {
					return true;
				} else {
					return false;
				}
			}

			if (args[idx] === type) {
				return true;
			}
		}

		return false;
	};

	/**
	 * Custom type that validates a value
	 * @constructor
	 * @param {Function} check
	 */
	var Custom = function(check) {
		this.check = check;
	};

	var O = {
		truthy: new Custom(function(val) {
			return (!!val) === true;
		}),
		falsy: new Custom(function(val) {
			return (!!val) === false;
		}),
		any: function() {
			var args = _convertConfigurationTypes(arguments);
			return new Custom(function(val) {
				return _matchAny(args, val);
			});
		},
		except: function() {
			var args = _convertConfigurationTypes(arguments);
			return new Custom(function(val) {
				return !_matchAny(args, val);
			});
		}
	};

	/**
	 * @constructor
	 */
	var Overload = function() {
		if (!(this instanceof Overload)) { return new Overload(); }

		/**
		 * Methods mapped to argument types
		 * Lazily instanciated
		 * @type {Array}
		 */
		// this._argMaps;

		/**
		 * Methods mapped to argument lengths
		 * Lazily instanciated
		 * @type {Array}
		 */
		// this._lenMaps;

		/**
		 * A fallback function if none
		 * of the criteria match on a call
		 * @type {Function}
		 */
		// this._f;
	};

	Overload.defineType = function(name, check) {
		var custom = new Custom(check);
		return (O[name] = custom);
	};

	Overload.prototype = {

		/** @constructor */
		constructor: Overload,

		args: function() {
			var self = this,
				args = arguments;

			return {
				use: function(method) {
					var argMappings = self._argMaps || (self._argMaps = []);
					argMappings.push({
						params: _convertConfigurationTypes(args),
						method: method
					});
					return self;
				}
			};
		},

		length: function(num) {
			var self = this;
			return {
				use: function(method) {
					var lengthMappings = self._lenMaps || (self._lenMaps = []);
					lengthMappings.push({
						length: (num === undefined) ? method.length : num,
						method: method
					});
					return self;
				}
			};
		},

		err: function(args) {
			throw new Error('No methods matched arguments: ', args, this);
		},

		fallback: function(method) {
			this._f = method;
		},

		call: function() {
			var args = _slice(arguments);
			return this._call(args.shift(), args);
		},

		apply: function(context, args) {
			return this._call(context, args);
		},

		bind: function(context) {
			var self = this;
			return function() {
				return self._call(context, arguments);
			}.bind(context);
		},

		expose: function() {
			var self = this;
			return function() {
				return self._call(this, arguments);
			};
		},

		_call: function(context, args) {
			args = args || [];

			// Any argument match, of course, already matches
			// the length match, so this should be done first
			var argMatch = _getArgumentMatch(this._argMaps, args);
			if (argMatch) {
				return argMatch.method.apply(context, args);
			}

			// Check for a length match
			var lengthMatch = _getLengthMatch(this._lenMaps, args);
			if (lengthMatch) {
				return lengthMatch.method.apply(context, args);
			}

			// Check for a fallback
			if (this._f) {
				return this._f.apply(context, args);
			}

			// Error
			return this.err(args);
		}
	};

	root.Overload = Overload;
	root.O = O;

}(this));<|endoftext|>


<commit_before>import React from 'react';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
import wedding from '../../../../../config/wedding.js';
import glob from 'styles/app';
import effects from 'styles/effects';
import local from './_styles';
import Map from '../../_partials/map/map';
import PageHeader from '../../_partials/page-header';
import EucThree from '../../svg/euc-3';
import EucFour from '../../svg/euc-4';
import PrettyAddress from '../../_partials/pretty-address';
import fxns from '../../../../utils/fxns';
import Scroll from 'react-scroll';

/**
  *
  * The details page
  *
  * @param  none
  *
  * @return {ReactComponent}
  */

const Events = Scroll.Events;
const scroll = Scroll.animateScroll;
const scrollSpy = Scroll.scrollSpy;

const wordDate = fxns.weddingWordDate();

class Details extends React.Component {
  componentDidMount () {
    scrollSpy.update();
    scroll.scrollToTop();
  }

  componentWillUnmount() {
    Events.scrollEvent.remove('begin');
    Events.scrollEvent.remove('end');
  }

  render() {
    const isIos = fxns.iOS(navigator);
    const sectionImageClass = isIos ? glob.iosBgImg : '';

    const directions = wedding.venue.directions.map((direction) =>

{direction}

    );

    const attire = wedding.attire.message.map((msg) =>

{msg}

    );

    const reception = wedding.reception.message.map((msg) =>

{msg}

    );

    const weddingDate = fxns.weddingDotDate();

    const venueAddress = PrettyAddress(wedding.venue.address);

    return (
      <div className={`${glob.pageDetails} ${effects.fade}`}>
        <PageHeader page="The Wedding" />

        <div className={`${glob.section}`}>
          <Row>
            <Col xs={12}>
              <div className={`${local.eucDate} ${local.eucBorderTop}`}>
                <EucFour color="$green" />

              <h2 className={`${local.date}`}>
                {weddingDate}

              <div className={`${local.eucDate} ${local.eucBorderBtm}`}>
                <EucThree color="$green" />

            </Col>
          </Row>

        <div className={`${glob.section} ${glob.sectionImage} ${sectionImageClass}`}>
          <Row>
            <Col xs={12} className={glob.verticalCol}>
              <div className={`${glob.card} ${glob.cardBordered} ${local.timeline}`}>
                <div className={`${glob.cardContent}`}>

{wordDate}

{wedding.venue.name}

                  {wedding.timeline.map((timelineEvent, index) => {
                    const ref = `timeline_${index}`;

                    return (
                      <Row className={local.event} key={ref}>
                        <Col xs={5}>

                            {timelineEvent.time.start}

                        </Col>
                        <Col xs={2} style={{ padding: '0 5px' }}>
                          <h3 className={`${local.eventDetail} ${local.dot}`}>
                            ·······

                        </Col>
                        <Col xs={5}>

                            {timelineEvent.eventName}

                        </Col>
                      </Row>
                    );
                  })}

            </Col>
          </Row>

        <div className={`${glob.section}`}>
          <Row>
            <Col xs={10} sm={4} className={glob.verticalCol}>

Ceremony & Reception at

{venueAddress}

{directions}

            </Col>
            <Col xs={10} sm={4} className={glob.verticalCol}>

                <Map type="venue" />

            </Col>
          </Row>

        <div className={`${glob.section} ${glob.sectionWhiteMed}`}>
          <h2 className={`${glob.headerLines}`}>Attire

          <Row>
            <Col xs={10} xsOffset={1} sm={4} smOffset={4}>

{wedding.attire.dressCode}

{attire}

            </Col>
          </Row>

        <div className={`${glob.section}`}>
          <h2 className={`${glob.headerLines} ${glob.black}`}>Reception

          <Row>
            <Col xs={6} sm={6}>

                local_dining

                {wedding.reception.meal.what}

            </Col>
            <Col xs={6} sm={6}>

                local_drink

                {wedding.reception.bar.what}

            </Col>
          </Row>
          <Row style={{ marginTop: '30px' }}>
            <Col xs={10} xsOffset={1} sm={4} smOffset={4}>
              {reception}
            </Col>
          </Row>

    );
  }
}

export default Details;
<commit_msg>Check back message<commit_after>import React from 'react';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
import wedding from '../../../../../config/wedding.js';
import glob from 'styles/app';
import effects from 'styles/effects';
import local from './_styles';
import Map from '../../_partials/map/map';
import PageHeader from '../../_partials/page-header';
import EucThree from '../../svg/euc-3';
import EucFour from '../../svg/euc-4';
import PrettyAddress from '../../_partials/pretty-address';
import fxns from '../../../../utils/fxns';
import Scroll from 'react-scroll';

/**
  *
  * The details page
  *
  * @param  none
  *
  * @return {ReactComponent}
  */

const Events = Scroll.Events;
const scroll = Scroll.animateScroll;
const scrollSpy = Scroll.scrollSpy;

const wordDate = fxns.weddingWordDate();

class Details extends React.Component {
  componentDidMount () {
    scrollSpy.update();
    scroll.scrollToTop();
  }

  componentWillUnmount() {
    Events.scrollEvent.remove('begin');
    Events.scrollEvent.remove('end');
  }

  render() {
    const isIos = fxns.iOS(navigator);
    const sectionImageClass = isIos ? glob.iosBgImg : '';

    const directions = wedding.venue.directions.map((direction) =>

{direction}

    );

    const attire = wedding.attire.message.map((msg) =>

{msg}

    );

    const reception = wedding.reception.message.map((msg) =>

{msg}

    );

    const weddingDate = fxns.weddingDotDate();

    const venueAddress = PrettyAddress(wedding.venue.address);

    return (
      <div className={`${glob.pageDetails} ${effects.fade}`}>
        <PageHeader page="The Wedding" />

        <div className={`${glob.section}`}>
          <Row>
            <Col xs={12}>
              <div className={`${local.eucDate} ${local.eucBorderTop}`}>
                <EucFour color="$green" />

              <h2 className={`${local.date}`}>
                {weddingDate}

              <div className={`${local.eucDate} ${local.eucBorderBtm}`}>
                <EucThree color="$green" />

            </Col>
          </Row>

        <div className={`${glob.section} ${glob.sectionImage} ${sectionImageClass}`}>
          <Row>
            <Col xs={12} className={glob.verticalCol}>
              <div className={`${glob.card} ${glob.cardBordered} ${local.timeline}`}>
                <div className={`${glob.cardContent}`}>

{wordDate}

{wedding.venue.name}

                  {wedding.timeline.map((timelineEvent, index) => {
                    const ref = `timeline_${index}`;

                    return (
                      <Row className={local.event} key={ref}>
                        <Col xs={5}>

                            {timelineEvent.time.start}

                        </Col>
                        <Col xs={2} style={{ padding: '0 5px' }}>
                          <h3 className={`${local.eventDetail} ${local.dot}`}>
                            ·······

                        </Col>
                        <Col xs={5}>

                            {timelineEvent.eventName}

                        </Col>
                      </Row>
                    );
                  })}

            </Col>
          </Row>

        <div className={`${glob.section}`}>
          <Row>
            <Col xs={10} sm={4} className={glob.verticalCol}>

Ceremony & Reception at

{venueAddress}

{directions}

            </Col>
            <Col xs={10} sm={4} className={glob.verticalCol}>

                <Map type="venue" />

            </Col>
          </Row>

        <div className={`${glob.section} ${glob.sectionWhiteMed}`}>
          <h2 className={`${glob.headerLines}`}>Attire

          <Row>
            <Col xs={10} xsOffset={1} sm={4} smOffset={4}>

{wedding.attire.dressCode}

{attire}

            </Col>
          </Row>

        <div className={`${glob.section}`}>
          <h2 className={`${glob.headerLines} ${glob.black}`}>Reception

          <Row>
            <Col xs={6} sm={6}>

                local_dining

                {wedding.reception.meal.what}

            </Col>
            <Col xs={6} sm={6}>

                local_drink

                {wedding.reception.bar.what}

            </Col>
          </Row>
          <Row style={{ marginTop: '30px' }}>
            <Col xs={10} xsOffset={1} sm={4} smOffset={4}>
              {reception}
            </Col>
          </Row>
          <Row>
            <Col xs={12}>

Check back for updates!

            </Col>
          </Row>

    );
  }
}

export default Details;
<|endoftext|>


<commit_before>(function(exports) {
    // General Purpose Utility Functions
    // ---------------------------------

    // Creates a namespace based on a string
    //   If separator is null, assumes . for separators
    //   If container is null, assumes default container (i.e. window)
    var namespace = function(name, separator, container){
      var ns = name.split(separator || '.'),
          o = container || exports,
          i, len;

      for (i = 0, len = ns.length; i < len; i++) {
        o = o[ns[i]] = o[ns[i]] || {};
      }

      return o;
    };

    namespace('P2P.Util');

    // P2P Version Number (keep in sync)
    P2P.Version = '1.0';

    // Utility Singleton
    P2P.Util = {
        namespace: namespace;

        // A logging function that appends each log entry to the #plog element in HTML
        // If a #plog element does not exist, it is appended to the body
        log: function() {
            var l = $('#plog');

            if (l.size === 0) {
                l = $('body').append('
Protocol status:

');
            }

            var copy = Array.prototype.slice.call(arguments).join(' ');
            l.append(copy + '
');
        }
    }
})(this);<commit_msg>Minor documentation update.<commit_after>(function(exports) {
    // General Purpose Utility Functions
    // ---------------------------------

    // Creates a namespace based on a string
    //   If separator is null, assumes . for separators
    //   If container is null, assumes default container (i.e. window)
    var namespace = function(name, separator, container){
      var ns = name.split(separator || '.'),
          o = container || exports,
          i, len;

      for (i = 0, len = ns.length; i < len; i++) {
        o = o[ns[i]] = o[ns[i]] || {};
      }

      return o;
    };

    namespace('P2P.Util');

    // P2P Version Number (keep in sync)
    P2P.Version = '1.0';

    // Utility Singleton
    // -----------------
    P2P.Util = {
        namespace: namespace;

        // A logging function that appends each log entry to the #plog element in HTML
        // If a #plog element does not exist, it is appended to the body
        log: function() {
            var l = $('#plog');

            if (l.size === 0) {
                l = $('body').append('
Protocol status:

');
            }

            var copy = Array.prototype.slice.call(arguments).join(' ');
            l.append(copy + '
');
        }
    }
})(this);<|endoftext|>


<commit_before>define([], function() {
    'use strict';

    return formulaFunction;

    function formulaFunction(formula, vertex, V) {

        try {

            // If the formula is an expression wrap and return it
            if (formula.indexOf('return') === -1) {
                formula = 'return (' + formula + ')';
            }

            return new Function(
                // Get property value and converted to string displayValue
                'prop',
                // Get actual raw property value
                'propRaw',
                // Vertex Json
                'vertex',
                // Inner function string
                formula)(
                    V.displayProp.bind(undefined, vertex),
                    V.prop.bind(undefined, vertex),
                    vertex);

        } catch(e) {
            console.warn('Unable to execute formula: ' + formula + ' Reason: ', e);
        }
    }
});
<commit_msg>Ignore function constructor from jshint<commit_after>define([], function() {
    'use strict';

    return formulaFunction;

    function formulaFunction(formula, vertex, V) {

        try {

            // If the formula is an expression wrap and return it
            if (formula.indexOf('return') === -1) {
                formula = 'return (' + formula + ')';
            }

            return new Function( // jshint ignore:line
                // Get property value and converted to string displayValue
                'prop',
                // Get actual raw property value
                'propRaw',
                // Vertex Json
                'vertex',
                // Inner function string
                formula)(
                    V.displayProp.bind(undefined, vertex),
                    V.prop.bind(undefined, vertex),
                    vertex);

        } catch(e) {
            console.warn('Unable to execute formula: ' + formula + ' Reason: ', e);
        }
    }
});
<|endoftext|>


<commit_before>// This script removes demo app files
import fse from "fs-extra";
import path from "path";
import colors from "colors";
import glob from "glob";

const TEMPLATE_FOLDER = path.resolve(__dirname, "./removeDemo");
const DEST_FOLDER = path.resolve(__dirname, "../source");
const PACKAGE_JSON = path.resolve(__dirname, "../package.json");
const PATHS_TO_REMOVE = [
  // pages and layouts
  "./source/pages/*",
  "./source/layouts/home.pug",
  "./source/layouts/page.pug",

  // modules
  "./source/modules/demo",
  "./source/modules/header-presentation",
  "./source/modules/header",
  "./source/modules/footer",
  "./source/modules/features-list",
  "./source/modules/features-list-item",
  "./source/modules/main-page",
  "./source/modules/quick-start",

  // static files
  "./source/static/icons/*",
  "./source/static/sprite/*",
  "./source/static/assets/favicons/*",
  "./source/static/assets/fonts/*",
  "./source/static/assets/images/*",
  "./source/static/assets/images/content/*"

  // this file
  // "/tools/removeDemo.js"
];

/* eslint-disable no-console */
function showError(title, err) {
  const errTitle = colors.red(`[${title.toUpperCase()}]`);
  return console.error(`${errTitle}:\n ${err}`);
}

function showMessage(title, message) {
  const messageTitle = colors.green(`[${title.toUpperCase()}]`);
  return console.log(`${messageTitle}: ${message}`);
}
/* eslint-enable no-console */

function removeFilesGlob(pathGlob, options = { messages: true }) {
  return glob(pathGlob, {}, (err, matches) => {
    if (err) showError("Error", err);

    return matches.map(matchedFile => {
      if (options.messages) {
        showMessage("Remove file", matchedFile);
      }
      return fse.remove(matchedFile);
    });
  });
}

function copyFiles(pathFrom, pathTo, options = { messages: true }) {
  return fse.copy(pathFrom, pathTo).then(err => {
    if (err) return showError("Error", err);

    if (options.messages) {
      showMessage("Copy file", `${pathFrom} -> ${pathTo}`);
    }
  });
}

// Remove entry from package.json
const removeEntryFromPackageJson = key =>
  fse
    .readJson(PACKAGE_JSON)
    .then(pkg => {
      delete pkg.scripts[key];
      return fse.writeJson(PACKAGE_JSON, pkg, {
        spaces: 2,
        EOL: "\n"
      });
    })
    .catch(err => showError("Error", err));

Promise.all(PATHS_TO_REMOVE.map(path => removeFilesGlob(path)))
  .then(() => copyFiles(TEMPLATE_FOLDER, DEST_FOLDER))
  .then(() => removeFilesGlob(TEMPLATE_FOLDER))
  .then(() => removeEntryFromPackageJson("cleanup"))
  .then(() => console.log(colors.green("Demo app removed."))) // eslint-disable-line no-console
  .catch(err => showError("Error", err));
<commit_msg>Fix paths in removeDemo<commit_after>// This script removes demo app files
import fse from "fs-extra";
import path from "path";
import colors from "colors";
import glob from "glob";

const TEMPLATE_FOLDER = path.resolve(__dirname, "./removeDemo");
const DEST_FOLDER = path.resolve(__dirname, "../source");
const PACKAGE_JSON = path.resolve(__dirname, "../package.json");
const PATHS_TO_REMOVE = [
  // pages and layouts
  "./source/pages/*",
  "./source/layouts/home.pug",

  // modules
  "./source/modules/demo",
  "./source/modules/header-presentation",
  "./source/modules/header",
  "./source/modules/footer",
  "./source/modules/features-list",
  "./source/modules/features-list-item",
  "./source/modules/main-page",
  "./source/modules/quick-start",

  // static files
  "./source/static/icons/*",
  "./source/static/sprite/*",
  "./source/static/assets/favicons/*",
  "./source/static/assets/fonts/*",
  "./source/static/assets/images/*",
  "./source/static/assets/images/content/*",

  // this file
  "./tools/removeDemo.js"
];

/* eslint-disable no-console */
function showError(title, err) {
  const errTitle = colors.red(`[${title.toUpperCase()}]`);
  return console.error(`${errTitle}:\n ${err}`);
}

function showMessage(title, message) {
  const messageTitle = colors.green(`[${title.toUpperCase()}]`);
  return console.log(`${messageTitle}: ${message}`);
}
/* eslint-enable no-console */

function removeFilesGlob(pathGlob, options = { messages: true }) {
  return glob(pathGlob, {}, (err, matches) => {
    if (err) showError("Error", err);

    return matches.map(matchedFile => {
      if (options.messages) {
        showMessage("Remove file", matchedFile);
      }
      return fse.remove(matchedFile);
    });
  });
}

function copyFiles(pathFrom, pathTo, options = { messages: true }) {
  return fse.copy(pathFrom, pathTo).then(err => {
    if (err) return showError("Error", err);

    if (options.messages) {
      showMessage("Copy file", `${pathFrom} -> ${pathTo}`);
    }
  });
}

// Remove entry from package.json
const removeEntryFromPackageJson = key =>
  fse
    .readJson(PACKAGE_JSON)
    .then(pkg => {
      delete pkg.scripts[key];
      return fse.writeJson(PACKAGE_JSON, pkg, {
        spaces: 2,
        EOL: "\n"
      });
    })
    .catch(err => showError("Error", err));

Promise.all(PATHS_TO_REMOVE.map(path => removeFilesGlob(path)))
  .then(() => copyFiles(TEMPLATE_FOLDER, DEST_FOLDER))
  .then(() => removeFilesGlob(TEMPLATE_FOLDER))
  .then(() => removeEntryFromPackageJson("cleanup"))
  .then(() => console.log(colors.green("Demo app removed."))) // eslint-disable-line no-console
  .catch(err => showError("Error", err));
<|endoftext|>


<commit_before>
var sys = require("sys");
var p = require("path");
var fs = require("fs");
var spawn = require("child_process").spawn;
var exec = require("child_process").exec;
var fileExtensionPattern;
var program, port;
// A program name which is "impossible" for anyone to choose, which represents no program.
var NO_PROGRAM = "__none__.coffee";

exports.run = run;

function run (args) {
  var arg, next, watch, extensions, executor;
  while (arg = args.shift()) {
    if (arg === "--help" || arg === "-h" || arg === "-?") {
      return help();
    } else if (arg === "--watch" || arg === "-w") {
      watch = args.shift();
    } else if (arg === "--port" || arg === "-p") {
      port = args.shift();
    } else if (arg === "--extensions" || arg === "-e") {
      extensions = args.shift();
    } else if (arg === "--exec" || arg === "-x") {
      executor = args.shift();
    } else if (arg.indexOf("-") && !args.length) {
      // Assume last arg is the program
      program = arg;
    }
  }
  if (!program) {
    //return help();
    var pwdFiles = fs.readdirSync('.');
    var autoRunFiles = ["app.js", "app.coffee", "manage.py"]
    for (var i = 0; i < autoRunFiles.length; i++) {
      if (pwdFiles.indexOf(autoRunFiles[i]) > -1) program=autoRunFiles[i];
    }
    if (!program) {
      program = NO_PROGRAM;
    }

  }
  if (!watch) {
    watch = ".";
  }

  var programExt = program.match(/.*\.(.*)/);
  programExt = programExt && programExt[1];

  if (!extensions) {
    // If no extensions passed try to guess from the program
    extensions = "node|js|styl|eco|coffee|jade";
    if (programExt && extensions.indexOf(programExt) == -1)
      extensions += "|" + programExt;
  }
  fileExtensionPattern = new RegExp(".*\.(" + extensions + ")$");

  if (!executor) {
    if (programExt === "coffee") {
      executor = "coffee";
    } else if (programExt === "py") {
      executor = "python";
    } else if (programExt === "js") {
      executor = "node";
    } else {
      throw "Extension `" + programExt + "` not supported.";
    }
  }

  sys.puts("")
  sys.debug("Running node-supervisor with");
  sys.debug("  program '" + program + "'");
  sys.debug("  --watch '" + watch + "'");
  sys.debug("  --extensions '" + extensions + "'");
  sys.debug("  --exec '" + executor + "'");
  sys.puts("")

  // if we have a program, then run it, and restart when it crashes.
  // if we have a watch folder, then watch the folder for changes and restart the prog

  if (program !== NO_PROGRAM) startProgram(program, executor);
  var watchItems = watch.split(',');
  watchItems.forEach(function (watchItem) {
    if (!watchItem.match(/^\/.*/)) { // watch is not an absolute path
      // convert watch item to absolute path
      watchItem = process.cwd() + '/' + watchItem;
    }
    sys.debug("Watching directory '" + watchItem + "' for changes.");
    findAllWatchFiles(watchItem, watchGivenFile);
  });
};

function print (m, n) { sys.print(m+(!n?"\n":"")); return print }

function help () {
  print
    ("")
    ("Node Supervisor is used to restart programs when they crash.")
    ("It can also be used to restart programs when a *.js file changes.")
    ("")
    ("Usage:")
    ("  supervisor [options] <program>")
    ("")
    ("Required:")
    ("  <program>")
    ("    The program to run.")
    ("")
    ("Options:")
    ("  -w|--watch <watchItems>")
    ("    A comma-delimited list of folders or js files to watch for changes.")
    ("    When a change to a js file occurs, reload the program")
    ("    Default is '.'")
    ("")
    ("  -e|--extensions <extensions>")
    ("    Specific file extensions to watch in addition to defaults.")
    ("    Used when --watch option includes folders")
    ("    Default is 'node|js'")
    ("")
    ("  -x|--exec <executable>")
    ("    The executable that runs the specified program.")
    ("    Default is 'node'")
    ("")
    ("  -h|--help|-?")
    ("    Display these usage instructions.")
    ("")
    ("Examples:")
    ("  supervisor myapp.js")
    ("  supervisor myapp.coffee")
    ("  supervisor -w scripts -e myext -x myrunner myapp")
    ("  supervisor -w lib -w server.js -w config.js server.js")
    ("")
}

function startProgram (prog, exec) {
  var cl_args;
  if (prog == 'manage.py') {
    program = NO_PROGRAM
    // special case for Django program.
    cl_args = [prog, 'runserver', '0.0.0.0:' + (port || 8000)];
  } else {
    cl_args = [prog];
  }
  sys.debug("Starting child process with '" + exec + " " + cl_args.join(' ') + "'");
  var child = exports.child = spawn(exec, cl_args);
  child.stdout.addListener("data", function (chunk) { chunk && sys.print(chunk) });
  child.stderr.addListener("data", function (chunk) { chunk && sys.debug(chunk) });
  child.addListener("exit", function () { startProgram(prog, exec) });
}

var timer = null, counter = -1, mtime = null;

function getExtension(filename) {
  var programExt = filename.match(/.*\.([^\.]*)$/);
  return programExt && programExt[1];
}

function stopCrashing () {
  if (counter > 3) throw new Error("Crashing too much, shutting down");
  else counter = -1;
}

function watchGivenFile (watch) {
  fs.watchFile(watch, function crash (oldStat, newStat) {
    // we only care about modification time, not access time.
    if (
      newStat.mtime.getTime() === oldStat.mtime.getTime()
    ) return;

    if (counter === -1) {
      timer = setTimeout(stopCrashing, 400);
    }
    counter ++;

    var child = exports.child;
    sys.debug("detected change at "+watch);
    var extension = getExtension(watch);
    if ("coffee" === extension) {
      sys.debug("compiling with coffeescript.");
      exec("coffee -c -m "+watch,function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });
    } else if (extension === "styl") {
      sys.debug('compiling with stylus.');
      exec("stylus "+watch,function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });
    } else if (extension === "eco") {
      sys.debug('compiling with eco.');
      exec("eco -o "+p.dirname(watch)+" "+watch,function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });
    } else if (extension === "jade" && watch.indexOf("client") > -1) {
      sys.debug('compiling with clientjade wrapper.');
      exec("clientjade.py " + p.dirname(watch),function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });

    } else {
      if (program !== NO_PROGRAM) process.kill(child.pid);
    }
  });
}

var findAllWatchFiles = function(path, callback) {
  fs.stat(path, function(err, stats){
    if (err) {
      sys.error('Error retrieving stats for file: ' + path);
    } else {
      if (stats.isDirectory()) {
        fs.readdir(path, function(err, fileNames) {
          if(err) {
            sys.puts('Error reading path: ' + path);
          }
          else {
            fileNames.forEach(function (fileName) {
              findAllWatchFiles(path + '/' + fileName, callback);
            });
          }
        });
      } else {

        if (path.match(fileExtensionPattern)) {
          callback(p.normalize(path));
        }
      }
    }
  });
}
<commit_msg>(sharing)<commit_after>
var sys = require("sys");
var p = require("path");
var fs = require("fs");
var spawn = require("child_process").spawn;
var exec = require("child_process").exec;
var fileExtensionPattern;
var program, port;
// A program name which is "impossible" for anyone to choose, which represents no program.
var NO_PROGRAM = "__none__.coffee";
var programExt;
exports.run = run;

function run (args) {
  var arg, next, watch, extensions, executor;
  while (arg = args.shift()) {
    if (arg === "--help" || arg === "-h" || arg === "-?") {
      return help();
    } else if (arg === "--watch" || arg === "-w") {
      watch = args.shift();
    } else if (arg === "--port" || arg === "-p") {
      port = args.shift();
    } else if (arg === "--extensions" || arg === "-e") {
      extensions = args.shift();
    } else if (arg === "--exec" || arg === "-x") {
      executor = args.shift();
    } else if (arg.indexOf("-") && !args.length) {
      // Assume last arg is the program
      program = arg;
    }
  }
  if (!program) {
    //return help();
    var pwdFiles = fs.readdirSync('.');
    var autoRunFiles = ["app.js", "app.coffee", "manage.py"]
    for (var i = 0; i < autoRunFiles.length; i++) {
      if (pwdFiles.indexOf(autoRunFiles[i]) > -1) program=autoRunFiles[i];
    }
    if (!program) {
      program = NO_PROGRAM;
    }

  }
  if (!watch) {
    watch = ".";
  }

  programExt = program.match(/.*\.(.*)/);
  programExt = programExt && programExt[1];

  if (!extensions) {
    // If no extensions passed try to guess from the program
    extensions = "node|js|styl|eco|coffee|jade";
    if (programExt && extensions.indexOf(programExt) == -1)
      extensions += "|" + programExt;
  }
  fileExtensionPattern = new RegExp(".*\.(" + extensions + ")$");

  if (!executor) {
    if (programExt === "coffee") {
      executor = "coffee";
    } else if (programExt === "py") {
      executor = "python";
    } else if (programExt === "js") {
      executor = "node";
    } else {
      throw "Extension `" + programExt + "` not supported.";
    }
  }

  sys.puts("")
  sys.debug("Running node-supervisor with");
  sys.debug("  program '" + program + "'");
  sys.debug("  --watch '" + watch + "'");
  sys.debug("  --extensions '" + extensions + "'");
  sys.debug("  --exec '" + executor + "'");
  sys.puts("")

  // if we have a program, then run it, and restart when it crashes.
  // if we have a watch folder, then watch the folder for changes and restart the prog

  if (program !== NO_PROGRAM) startProgram(program, executor);
  var watchItems = watch.split(',');
  watchItems.forEach(function (watchItem) {
    if (!watchItem.match(/^\/.*/)) { // watch is not an absolute path
      // convert watch item to absolute path
      watchItem = process.cwd() + '/' + watchItem;
    }
    sys.debug("Watching directory '" + watchItem + "' for changes.");
    findAllWatchFiles(watchItem, watchGivenFile);
  });
};

function print (m, n) { sys.print(m+(!n?"\n":"")); return print }

function help () {
  print
    ("")
    ("Node Supervisor is used to restart programs when they crash.")
    ("It can also be used to restart programs when a *.js file changes.")
    ("")
    ("Usage:")
    ("  supervisor [options] <program>")
    ("")
    ("Required:")
    ("  <program>")
    ("    The program to run.")
    ("")
    ("Options:")
    ("  -w|--watch <watchItems>")
    ("    A comma-delimited list of folders or js files to watch for changes.")
    ("    When a change to a js file occurs, reload the program")
    ("    Default is '.'")
    ("")
    ("  -e|--extensions <extensions>")
    ("    Specific file extensions to watch in addition to defaults.")
    ("    Used when --watch option includes folders")
    ("    Default is 'node|js'")
    ("")
    ("  -x|--exec <executable>")
    ("    The executable that runs the specified program.")
    ("    Default is 'node'")
    ("")
    ("  -h|--help|-?")
    ("    Display these usage instructions.")
    ("")
    ("Examples:")
    ("  supervisor myapp.js")
    ("  supervisor myapp.coffee")
    ("  supervisor -w scripts -e myext -x myrunner myapp")
    ("  supervisor -w lib -w server.js -w config.js server.js")
    ("")
}

function startProgram (prog, exec) {
  var cl_args;
  if (prog == 'manage.py') {
    program = NO_PROGRAM
    // special case for Django program.
    cl_args = [prog, 'runserver', '0.0.0.0:' + (port || 8000)];
  } else {
    cl_args = [prog];
  }
  sys.debug("Starting child process with '" + exec + " " + cl_args.join(' ') + "'");
  var child = exports.child = spawn(exec, cl_args);
  child.stdout.addListener("data", function (chunk) { chunk && sys.print(chunk) });
  child.stderr.addListener("data", function (chunk) { chunk && sys.debug(chunk) });
  child.addListener("exit", function () { startProgram(prog, exec) });
}

var timer = null, counter = -1, mtime = null;

function getExtension(filename) {
  var programExt = filename.match(/.*\.([^\.]*)$/);
  return programExt && programExt[1];
}

function stopCrashing () {
  if (counter > 3) throw new Error("Crashing too much, shutting down");
  else counter = -1;
}

function watchGivenFile (watch) {
  fs.watchFile(watch, function crash (oldStat, newStat) {
    // we only care about modification time, not access time.
    if (
      newStat.mtime.getTime() === oldStat.mtime.getTime()
    ) return;

    if (counter === -1) {
      timer = setTimeout(stopCrashing, 400);
    }
    counter ++;

    var child = exports.child;
    sys.debug("detected change at "+watch);
    var extension = getExtension(watch);
    if ("coffee" === extension) {
      sys.debug("compiling with coffeescript.");
      exec("coffee -c -m "+watch,function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });
      if (programExt === "coffee") {
        process.kill(child.pid);
      }
    } else if (extension === "styl") {
      sys.debug('compiling with stylus.');
      exec("stylus "+watch,function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });
    } else if (extension === "eco") {
      sys.debug('compiling with eco.');
      exec("eco -o "+p.dirname(watch)+" "+watch,function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });
    } else if (extension === "jade" && watch.indexOf("client") > -1) {
      sys.debug('compiling with clientjade wrapper.');
      exec("clientjade.py " + p.dirname(watch),function(err, stderr, stdout) {
            if (err) sys.debug(err);
            if (stderr) sys.debug(stderr);
            if (stdout) sys.debug(stdout);
      });
    } else if (extension === "js" && programExt === "coffee") {
      // Do nothing.
    } else {
      if (program !== NO_PROGRAM) process.kill(child.pid);
    }
  });
}

var findAllWatchFiles = function(path, callback) {
  fs.stat(path, function(err, stats){
    if (err) {
      sys.error('Error retrieving stats for file: ' + path);
    } else {
      if (stats.isDirectory()) {
        fs.readdir(path, function(err, fileNames) {
          if(err) {
            sys.puts('Error reading path: ' + path);
          }
          else {
            fileNames.forEach(function (fileName) {
              findAllWatchFiles(path + '/' + fileName, callback);
            });
          }
        });
      } else {

        if (path.match(fileExtensionPattern)) {
          callback(p.normalize(path));
        }
      }
    }
  });
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

/**
 * @param {Element} playerContainer Main container.
 * @param {Element} videoContainer Container for the video element.
 * @param {Element} controlsContainer Container for video controls.
 * @constructor
 */
function FullWindowVideoControls(
    playerContainer, videoContainer, controlsContainer) {
  VideoControls.call(this,
      controlsContainer,
      this.onPlaybackError_.wrap(this),
      loadTimeData.getString.wrap(loadTimeData),
      this.toggleFullScreen_.wrap(this),
      videoContainer);

  this.playerContainer_ = playerContainer;
  this.decodeErrorOccured = false;

  this.updateStyle();
  window.addEventListener('resize', this.updateStyle.wrap(this));
  document.addEventListener('keydown', function(e) {
    if (e.keyIdentifier == 'U+0020') {  // Space
      this.togglePlayStateWithFeedback();
      e.preventDefault();
    }
    if (e.keyIdentifier == 'U+001B') {  // Escape
      util.toggleFullScreen(
          chrome.app.window.current(),
          false);  // Leave the full screen mode.
      e.preventDefault();
    }
  }.wrap(this));

  // TODO(mtomasz): Simplify. crbug.com/254318.
  videoContainer.addEventListener('click', function(e) {
    if (e.ctrlKey) {
      this.toggleLoopedModeWithFeedback(true);
      if (!this.isPlaying())
        this.togglePlayStateWithFeedback();
    } else {
      this.togglePlayStateWithFeedback();
    }
  }.wrap(this));

  this.inactivityWatcher_ = new MouseInactivityWatcher(playerContainer);
  this.__defineGetter__('inactivityWatcher', function() {
    return this.inactivityWatcher_;
  }.wrap(this));

  this.inactivityWatcher_.check();
}

FullWindowVideoControls.prototype = { __proto__: VideoControls.prototype };

/**
 * Displays error message.
 *
 * @param {string} message Message id.
 * @private
 */
FullWindowVideoControls.prototype.showErrorMessage_ = function(message) {
  var errorBanner = document.querySelector('#error');
  errorBanner.textContent =
      loadTimeData.getString(message);
  errorBanner.setAttribute('visible', 'true');

  // The window is hidden if the video has not loaded yet.
  chrome.app.window.current().show();
};

/**
 * Handles playback (decoder) errors.
 * @private
 */
FullWindowVideoControls.prototype.onPlaybackError_ = function() {
  this.showErrorMessage_('GALLERY_VIDEO_DECODING_ERROR');
  this.decodeErrorOccured = true;

  // Disable inactivity watcher, and disable the ui, by hiding tools manually.
  this.inactivityWatcher.disabled = true;
  document.querySelector('#video-player').setAttribute('disabled', 'true');

  // Detach the video element, since it may be unreliable and reset stored
  // current playback time.
  this.cleanup();
  this.clearState();

  // Avoid reusing a video element.
  player.unloadVideo();
};

/**
 * Toggles the full screen mode.
 * @private
 */
FullWindowVideoControls.prototype.toggleFullScreen_ = function() {
  var appWindow = chrome.app.window.current();
  util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow));
};

/**
 * @constructor
 */
function VideoPlayer() {
  this.controls_ = null;
  this.videoElement_ = null;
  this.videos_ = null;
  this.currentPos_ = 0;

  Object.seal(this);
}

VideoPlayer.prototype = {
  get controls() {
    return this.controls_;
  }
};

/**
 * Initializes the video player window. This method must be called after DOM
 * initialization.
 * @param {Array.<Object.<string, Object>>} videos List of videos.
 */
VideoPlayer.prototype.prepare = function(videos) {
  this.videos_ = videos;

  var preventDefault = function(event) { event.preventDefault(); }.wrap(null);

  document.ondragstart = preventDefault;

  var maximizeButton = document.querySelector('.maximize-button');
  maximizeButton.addEventListener(
    'click',
    function(event) {
      var appWindow = chrome.app.window.current();
      if (appWindow.isMaximized())
        appWindow.restore();
      else
        appWindow.maximize();
      event.stopPropagation();
    }.wrap(null));
  maximizeButton.addEventListener('mousedown', preventDefault);

  var minimizeButton = document.querySelector('.minimize-button');
  minimizeButton.addEventListener(
    'click',
    function(event) {
      chrome.app.window.current().minimize()
      event.stopPropagation();
    }.wrap(null));
  minimizeButton.addEventListener('mousedown', preventDefault);

  var closeButton = document.querySelector('.close-button');
  closeButton.addEventListener(
    'click',
    function(event) {
      close();
      event.stopPropagation();
    }.wrap(null));
  closeButton.addEventListener('mousedown', preventDefault);

  var castButton = document.querySelector('.cast-button');
  cr.ui.decorate(castButton, cr.ui.MenuButton);
  castButton.addEventListener(
    'click',
    function(event) {
      event.stopPropagation();
    }.wrap(null));
  castButton.addEventListener('mousedown', preventDefault);

  var menu = document.querySelector('#cast-menu');
  cr.ui.decorate(menu, cr.ui.Menu);

  this.controls_ = new FullWindowVideoControls(
      document.querySelector('#video-player'),
      document.querySelector('#video-container'),
      document.querySelector('#controls'));

  var reloadVideo = function(e) {
    if (this.controls_.decodeErrorOccured &&
        // Ignore shortcut keys
        !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
      this.reloadCurrentVideo_(function() {
        this.videoElement_.play();
      }.wrap(this));
      e.preventDefault();
    }
  }.wrap(this);

  var arrowRight = document.querySelector('.arrow-box .arrow.right');
  arrowRight.addEventListener('click', this.advance_.wrap(this, 1));
  var arrowLeft = document.querySelector('.arrow-box .arrow.left');
  arrowLeft.addEventListener('click', this.advance_.wrap(this, 0));

  var videoPlayerElement = document.querySelector('#video-player');
  if (videos.length > 1)
    videoPlayerElement.setAttribute('multiple', true);
  else
    videoPlayerElement.removeAttribute('multiple');

  document.addEventListener('keydown', reloadVideo);
  document.addEventListener('click', reloadVideo);
};

/**
 * Unloads the player.
 */
function unload() {
  if (!player.controls || !player.controls.getMedia())
    return;

  player.controls.savePosition(true /* exiting */);
  player.controls.cleanup();
}

/**
 * Loads the video file.
 * @param {string} url URL of the video file.
 * @param {string} title Title of the video file.
 * @param {function()=} opt_callback Completion callback.
 * @private
 */
VideoPlayer.prototype.loadVideo_ = function(url, title, opt_callback) {
  this.unloadVideo();

  document.title = title;

  document.querySelector('#title').innerText = title;

  var videoPlayerElement = document.querySelector('#video-player');
  if (this.currentPos_ === (this.videos_.length - 1))
    videoPlayerElement.setAttribute('last-video', true);
  else
    videoPlayerElement.removeAttribute('last-video');

  if (this.currentPos_ === 0)
    videoPlayerElement.setAttribute('first-video', true);
  else
    videoPlayerElement.removeAttribute('first-video');

  // Re-enables ui and hides error message if already displayed.
  document.querySelector('#video-player').removeAttribute('disabled');
  document.querySelector('#error').removeAttribute('visible');
  this.controls.inactivityWatcher.disabled = false;
  this.controls.decodeErrorOccured = false;

  this.videoElement_ = document.createElement('video');
  document.querySelector('#video-container').appendChild(this.videoElement_);
  this.controls.attachMedia(this.videoElement_);

  this.videoElement_.src = url;
  this.videoElement_.load();

  if (opt_callback) {
    var handler = function(currentPos, event) {
      console.log('loaded: ', currentPos, this.currentPos_);
      if (currentPos === this.currentPos_)
        opt_callback();
      this.videoElement_.removeEventListener('loadedmetadata', handler);
    }.wrap(this, this.currentPos_);

    this.videoElement_.addEventListener('loadedmetadata', handler);
  }
};

/**
 * Plays the first video.
 */
VideoPlayer.prototype.playFirstVideo = function() {
  this.currentPos_ = 0;
  this.reloadCurrentVideo_(this.onFirstVideoReady_.wrap(this));
};

/**
 * Unloads the current video.
 */
VideoPlayer.prototype.unloadVideo = function() {
  // Detach the previous video element, if exists.
  if (this.videoElement_)
    this.videoElement_.parentNode.removeChild(this.videoElement_);
  this.videoElement_ = null;
};

/**
 * Called when the first video is ready after starting to load.
 * @private
 */
VideoPlayer.prototype.onFirstVideoReady_ = function() {
  var videoWidth = this.videoElement_.videoWidth;
  var videoHeight = this.videoElement_.videoHeight;

  var aspect = videoWidth / videoHeight;
  var newWidth = videoWidth;
  var newHeight = videoHeight;

  var shrinkX = newWidth / window.screen.availWidth;
  var shrinkY = newHeight / window.screen.availHeight;
  if (shrinkX > 1 || shrinkY > 1) {
    if (shrinkY > shrinkX) {
      newHeight = newHeight / shrinkY;
      newWidth = newHeight * aspect;
    } else {
      newWidth = newWidth / shrinkX;
      newHeight = newWidth / aspect;
    }
  }

  var oldLeft = window.screenX;
  var oldTop = window.screenY;
  var oldWidth = window.outerWidth;
  var oldHeight = window.outerHeight;

  if (!oldWidth && !oldHeight) {
    oldLeft = window.screen.availWidth / 2;
    oldTop = window.screen.availHeight / 2;
  }

  var appWindow = chrome.app.window.current();
  appWindow.resizeTo(newWidth, newHeight);
  appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2,
                   oldTop - (newHeight - oldHeight) / 2);
  appWindow.show();

  this.videoElement_.play();
};

/**
 * Advances to the next (or previous) track.
 *
 * @param {boolean} direction True to the next, false to the previous.
 * @private
 */
VideoPlayer.prototype.advance_ = function(direction) {
  var newPos = this.currentPos_ + (direction ? 1 : -1);
  if (0 <= newPos && newPos < this.videos_.length) {
    this.currentPos_ = newPos;
    this.reloadCurrentVideo_(function() {
      this.videoElement_.play();
    }.wrap(this));
  }
};

/**
 * Reloads the current video.
 *
 * @param {function()=} opt_callback Completion callback.
 * @private
 */
VideoPlayer.prototype.reloadCurrentVideo_ = function(opt_callback) {
  var currentVideo = this.videos_[this.currentPos_];
  this.loadVideo_(currentVideo.fileUrl, currentVideo.entry.name, opt_callback);
};

/**
 * Set the list of casts.
 * @param {Array.<Object>} casts List of casts.
 */
VideoPlayer.prototype.setCastList = function(casts) {
  var button = document.querySelector('.cast-button');
  var menu = document.querySelector('#cast-menu');
  menu.innerHTML = '';

  if (casts.length === 0) {
    button.classList.add('hidden');
    return;
  }

  for (var i = 0; i < casts.length; i++) {
    var item = new cr.ui.MenuItem();
    item.textContent = casts[i].name;
    menu.appendChild(item);
  }
  button.classList.remove('hidden');
};

/**
 * Initialize the list of videos.
 * @param {function(Array.<Object>)} callback Called with the video list when
 *     it is ready.
 */
function initVideos(callback) {
  if (window.videos) {
    var videos = window.videos;
    window.videos = null;
    callback(videos);
    return;
  }

  chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        var videos = window.videos;
        window.videos = null;
        callback(videos);
      }.wrap(null));
}

var player = new VideoPlayer();

/**
 * Initializes the strings.
 * @param {function()} callback Called when the sting data is ready.
 */
function initStrings(callback) {
  chrome.fileBrowserPrivate.getStrings(function(strings) {
    loadTimeData.data = strings;
    callback();
  }.wrap(null));
}

var initPromise = Promise.all(
    [new Promise(initVideos.wrap(null)),
     new Promise(initStrings.wrap(null)),
     new Promise(util.addPageLoadHandler.wrap(null))]);

initPromise.then(function(results) {
  var videos = results[0];
  player.prepare(videos);
  return new Promise(player.playFirstVideo.wrap(player));
}.wrap(null));
<commit_msg>Video Player: Automatically load next video<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

/**
 * @param {Element} playerContainer Main container.
 * @param {Element} videoContainer Container for the video element.
 * @param {Element} controlsContainer Container for video controls.
 * @constructor
 */
function FullWindowVideoControls(
    playerContainer, videoContainer, controlsContainer) {
  VideoControls.call(this,
      controlsContainer,
      this.onPlaybackError_.wrap(this),
      loadTimeData.getString.wrap(loadTimeData),
      this.toggleFullScreen_.wrap(this),
      videoContainer);

  this.playerContainer_ = playerContainer;
  this.decodeErrorOccured = false;

  this.updateStyle();
  window.addEventListener('resize', this.updateStyle.wrap(this));
  document.addEventListener('keydown', function(e) {
    if (e.keyIdentifier == 'U+0020') {  // Space
      this.togglePlayStateWithFeedback();
      e.preventDefault();
    }
    if (e.keyIdentifier == 'U+001B') {  // Escape
      util.toggleFullScreen(
          chrome.app.window.current(),
          false);  // Leave the full screen mode.
      e.preventDefault();
    }
  }.wrap(this));

  // TODO(mtomasz): Simplify. crbug.com/254318.
  videoContainer.addEventListener('click', function(e) {
    if (e.ctrlKey) {
      this.toggleLoopedModeWithFeedback(true);
      if (!this.isPlaying())
        this.togglePlayStateWithFeedback();
    } else {
      this.togglePlayStateWithFeedback();
    }
  }.wrap(this));

  this.inactivityWatcher_ = new MouseInactivityWatcher(playerContainer);
  this.__defineGetter__('inactivityWatcher', function() {
    return this.inactivityWatcher_;
  }.wrap(this));

  this.inactivityWatcher_.check();
}

FullWindowVideoControls.prototype = { __proto__: VideoControls.prototype };

/**
 * Displays error message.
 *
 * @param {string} message Message id.
 * @private
 */
FullWindowVideoControls.prototype.showErrorMessage_ = function(message) {
  var errorBanner = document.querySelector('#error');
  errorBanner.textContent =
      loadTimeData.getString(message);
  errorBanner.setAttribute('visible', 'true');

  // The window is hidden if the video has not loaded yet.
  chrome.app.window.current().show();
};

/**
 * Handles playback (decoder) errors.
 * @private
 */
FullWindowVideoControls.prototype.onPlaybackError_ = function() {
  this.showErrorMessage_('GALLERY_VIDEO_DECODING_ERROR');
  this.decodeErrorOccured = true;

  // Disable inactivity watcher, and disable the ui, by hiding tools manually.
  this.inactivityWatcher.disabled = true;
  document.querySelector('#video-player').setAttribute('disabled', 'true');

  // Detach the video element, since it may be unreliable and reset stored
  // current playback time.
  this.cleanup();
  this.clearState();

  // Avoid reusing a video element.
  player.unloadVideo();
};

/**
 * Toggles the full screen mode.
 * @private
 */
FullWindowVideoControls.prototype.toggleFullScreen_ = function() {
  var appWindow = chrome.app.window.current();
  util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow));
};

/**
 * Media completion handler.
 */
FullWindowVideoControls.prototype.onMediaComplete = function() {
  VideoControls.prototype.onMediaComplete.apply(this, arguments);
  if (!this.getMedia().loop)
    player.advance_(1);
};

/**
 * @constructor
 */
function VideoPlayer() {
  this.controls_ = null;
  this.videoElement_ = null;
  this.videos_ = null;
  this.currentPos_ = 0;

  Object.seal(this);
}

VideoPlayer.prototype = {
  get controls() {
    return this.controls_;
  }
};

/**
 * Initializes the video player window. This method must be called after DOM
 * initialization.
 * @param {Array.<Object.<string, Object>>} videos List of videos.
 */
VideoPlayer.prototype.prepare = function(videos) {
  this.videos_ = videos;

  var preventDefault = function(event) { event.preventDefault(); }.wrap(null);

  document.ondragstart = preventDefault;

  var maximizeButton = document.querySelector('.maximize-button');
  maximizeButton.addEventListener(
    'click',
    function(event) {
      var appWindow = chrome.app.window.current();
      if (appWindow.isMaximized())
        appWindow.restore();
      else
        appWindow.maximize();
      event.stopPropagation();
    }.wrap(null));
  maximizeButton.addEventListener('mousedown', preventDefault);

  var minimizeButton = document.querySelector('.minimize-button');
  minimizeButton.addEventListener(
    'click',
    function(event) {
      chrome.app.window.current().minimize()
      event.stopPropagation();
    }.wrap(null));
  minimizeButton.addEventListener('mousedown', preventDefault);

  var closeButton = document.querySelector('.close-button');
  closeButton.addEventListener(
    'click',
    function(event) {
      close();
      event.stopPropagation();
    }.wrap(null));
  closeButton.addEventListener('mousedown', preventDefault);

  var castButton = document.querySelector('.cast-button');
  cr.ui.decorate(castButton, cr.ui.MenuButton);
  castButton.addEventListener(
    'click',
    function(event) {
      event.stopPropagation();
    }.wrap(null));
  castButton.addEventListener('mousedown', preventDefault);

  var menu = document.querySelector('#cast-menu');
  cr.ui.decorate(menu, cr.ui.Menu);

  this.controls_ = new FullWindowVideoControls(
      document.querySelector('#video-player'),
      document.querySelector('#video-container'),
      document.querySelector('#controls'));

  var reloadVideo = function(e) {
    if (this.controls_.decodeErrorOccured &&
        // Ignore shortcut keys
        !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
      this.reloadCurrentVideo_(function() {
        this.videoElement_.play();
      }.wrap(this));
      e.preventDefault();
    }
  }.wrap(this);

  var arrowRight = document.querySelector('.arrow-box .arrow.right');
  arrowRight.addEventListener('click', this.advance_.wrap(this, 1));
  var arrowLeft = document.querySelector('.arrow-box .arrow.left');
  arrowLeft.addEventListener('click', this.advance_.wrap(this, 0));

  var videoPlayerElement = document.querySelector('#video-player');
  if (videos.length > 1)
    videoPlayerElement.setAttribute('multiple', true);
  else
    videoPlayerElement.removeAttribute('multiple');

  document.addEventListener('keydown', reloadVideo);
  document.addEventListener('click', reloadVideo);
};

/**
 * Unloads the player.
 */
function unload() {
  if (!player.controls || !player.controls.getMedia())
    return;

  player.controls.savePosition(true /* exiting */);
  player.controls.cleanup();
}

/**
 * Loads the video file.
 * @param {string} url URL of the video file.
 * @param {string} title Title of the video file.
 * @param {function()=} opt_callback Completion callback.
 * @private
 */
VideoPlayer.prototype.loadVideo_ = function(url, title, opt_callback) {
  this.unloadVideo();

  document.title = title;

  document.querySelector('#title').innerText = title;

  var videoPlayerElement = document.querySelector('#video-player');
  if (this.currentPos_ === (this.videos_.length - 1))
    videoPlayerElement.setAttribute('last-video', true);
  else
    videoPlayerElement.removeAttribute('last-video');

  if (this.currentPos_ === 0)
    videoPlayerElement.setAttribute('first-video', true);
  else
    videoPlayerElement.removeAttribute('first-video');

  // Re-enables ui and hides error message if already displayed.
  document.querySelector('#video-player').removeAttribute('disabled');
  document.querySelector('#error').removeAttribute('visible');
  this.controls.inactivityWatcher.disabled = false;
  this.controls.decodeErrorOccured = false;

  this.videoElement_ = document.createElement('video');
  document.querySelector('#video-container').appendChild(this.videoElement_);
  this.controls.attachMedia(this.videoElement_);

  this.videoElement_.src = url;
  this.videoElement_.load();

  if (opt_callback) {
    var handler = function(currentPos, event) {
      console.log('loaded: ', currentPos, this.currentPos_);
      if (currentPos === this.currentPos_)
        opt_callback();
      this.videoElement_.removeEventListener('loadedmetadata', handler);
    }.wrap(this, this.currentPos_);

    this.videoElement_.addEventListener('loadedmetadata', handler);
  }
};

/**
 * Plays the first video.
 */
VideoPlayer.prototype.playFirstVideo = function() {
  this.currentPos_ = 0;
  this.reloadCurrentVideo_(this.onFirstVideoReady_.wrap(this));
};

/**
 * Unloads the current video.
 */
VideoPlayer.prototype.unloadVideo = function() {
  // Detach the previous video element, if exists.
  if (this.videoElement_)
    this.videoElement_.parentNode.removeChild(this.videoElement_);
  this.videoElement_ = null;
};

/**
 * Called when the first video is ready after starting to load.
 * @private
 */
VideoPlayer.prototype.onFirstVideoReady_ = function() {
  var videoWidth = this.videoElement_.videoWidth;
  var videoHeight = this.videoElement_.videoHeight;

  var aspect = videoWidth / videoHeight;
  var newWidth = videoWidth;
  var newHeight = videoHeight;

  var shrinkX = newWidth / window.screen.availWidth;
  var shrinkY = newHeight / window.screen.availHeight;
  if (shrinkX > 1 || shrinkY > 1) {
    if (shrinkY > shrinkX) {
      newHeight = newHeight / shrinkY;
      newWidth = newHeight * aspect;
    } else {
      newWidth = newWidth / shrinkX;
      newHeight = newWidth / aspect;
    }
  }

  var oldLeft = window.screenX;
  var oldTop = window.screenY;
  var oldWidth = window.outerWidth;
  var oldHeight = window.outerHeight;

  if (!oldWidth && !oldHeight) {
    oldLeft = window.screen.availWidth / 2;
    oldTop = window.screen.availHeight / 2;
  }

  var appWindow = chrome.app.window.current();
  appWindow.resizeTo(newWidth, newHeight);
  appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2,
                   oldTop - (newHeight - oldHeight) / 2);
  appWindow.show();

  this.videoElement_.play();
};

/**
 * Advances to the next (or previous) track.
 *
 * @param {boolean} direction True to the next, false to the previous.
 * @private
 */
VideoPlayer.prototype.advance_ = function(direction) {
  var newPos = this.currentPos_ + (direction ? 1 : -1);
  if (0 <= newPos && newPos < this.videos_.length) {
    this.currentPos_ = newPos;
    this.reloadCurrentVideo_(function() {
      this.videoElement_.play();
    }.wrap(this));
  }
};

/**
 * Reloads the current video.
 *
 * @param {function()=} opt_callback Completion callback.
 * @private
 */
VideoPlayer.prototype.reloadCurrentVideo_ = function(opt_callback) {
  var currentVideo = this.videos_[this.currentPos_];
  this.loadVideo_(currentVideo.fileUrl, currentVideo.entry.name, opt_callback);
};

/**
 * Set the list of casts.
 * @param {Array.<Object>} casts List of casts.
 */
VideoPlayer.prototype.setCastList = function(casts) {
  var button = document.querySelector('.cast-button');
  var menu = document.querySelector('#cast-menu');
  menu.innerHTML = '';

  if (casts.length === 0) {
    button.classList.add('hidden');
    return;
  }

  for (var i = 0; i < casts.length; i++) {
    var item = new cr.ui.MenuItem();
    item.textContent = casts[i].name;
    menu.appendChild(item);
  }
  button.classList.remove('hidden');
};

/**
 * Initialize the list of videos.
 * @param {function(Array.<Object>)} callback Called with the video list when
 *     it is ready.
 */
function initVideos(callback) {
  if (window.videos) {
    var videos = window.videos;
    window.videos = null;
    callback(videos);
    return;
  }

  chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        var videos = window.videos;
        window.videos = null;
        callback(videos);
      }.wrap(null));
}

var player = new VideoPlayer();

/**
 * Initializes the strings.
 * @param {function()} callback Called when the sting data is ready.
 */
function initStrings(callback) {
  chrome.fileBrowserPrivate.getStrings(function(strings) {
    loadTimeData.data = strings;
    callback();
  }.wrap(null));
}

var initPromise = Promise.all(
    [new Promise(initVideos.wrap(null)),
     new Promise(initStrings.wrap(null)),
     new Promise(util.addPageLoadHandler.wrap(null))]);

initPromise.then(function(results) {
  var videos = results[0];
  player.prepare(videos);
  return new Promise(player.playFirstVideo.wrap(player));
}.wrap(null));
<|endoftext|>