<commit_before>(function (window, Q, $, undefined) {

/**
 * @module Q
 */

/**
 * YUIDoc description goes here
 * @class Q video
 * @constructor
 * @param {Object} [options] Override various options for this tool
 *  @param {String} [options.url] URL of video source
 *  @param {string} [options.clipStart] Clip start position in milliseconds
 *  @param {string} [options.clipEnd] Clip end position in milliseconds
 *  @param {boolean} [options.autoplay=false] If true - start play on load
 */
Q.Tool.define("Q/video", function (options) {
	var tool = this;
	var state = tool.state;

	if (state.url) {
		state.url = state.url.interpolate({ "baseUrl": Q.info.baseUrl });
	}

	tool.adapters = {};

	tool.adapters.mp4 = {
		init: function () {
			var options = {
				sources: [{
					src: state.url,
					type: 'video/mp4'
				}]
			};

			tool.initVideojsPlayer(options);
		}
	};
	tool.adapters.webm = {
		init: function () {
			var options = {
				sources: [{
					src: state.url,
					type: 'video/webm'
				}]
			};

			tool.initVideojsPlayer(options);
		}
	};
	tool.adapters.ogg = {
		init: function () {
			var options = {
				sources: [{
					src: state.url,
					type: 'video/ogg'
				}]
			};

			tool.initVideojsPlayer(options);
		}
	};
	tool.adapters.youtube = {
		init: function () {
			Q.addScript("{{Q}}/js/videojs/plugins/YouTube.js", function () {
				var options = {
					techOrder: ["youtube"],
					sources: [{
						src: state.url,
						type: 'video/youtube'
					}],
					youtube: {
						ytControls: 2
					}
				};

				tool.initVideojsPlayer(options);
			});
		}
	};
	tool.adapters.vimeo = {
		init: function () {
			Q.addScript("{{Q}}/js/videojs/plugins/Vimeo.js", function () {
				var options = {
					techOrder: ["vimeo"],
					sources: [{
						src: state.url,
						type: 'video/vimeo'
					}],
					vimeo: {
						ytControls: 2
					}
				};

				tool.initVideojsPlayer(options);
			});
		}
	};
	tool.adapters.twitch = {
		init: function () {
			var element = tool.element;
			var throttle = state.throttle;

			var newA = document.createElement('A');
			newA.href = state.url;
			var host = newA.hostname;

			element.classList.add("Q_video_twitch");

			var options = {
				autoplay: false
				//channel: "<channel ID>",
				//video: "782042263",
				//collection: "<collection ID>"
			};

			// convert start time to pass as option
			if (state.clipStart) {
				options.time = state.clipStart.convertTimeToString(false).replace(/:/, 'h').replace(/:/, 'm') + 's';
			}

			var videoId = state.url.match(/\/videos\/([0-9]+).*$/);
			var channel = state.url.match(new RegExp(host + "/(\\w+)"));
			if (videoId) {
				options.video = videoId[1];
			} else if (channel) {
				options.channel = channel[1];
			} else {
				throw new Q.Error("Q/video/twitch: none of videoId or channel filled");
			}

			Q.addScript("{{Q}}/js/twitch/lib.js", function () {
				state.player = new Twitch.Player(element, options);
				state.player.currentTime = function (time) {
					state.player.seek(time);
				};

				var _getCurrentPostion = function () {
					return Math.trunc(state.player.getCurrentTime() * 1000);
				};

				var onPlay = Q.throttle(function () {
					state.currentPosition = _getCurrentPostion();
					console.log("Started at position " + state.currentPosition + " milliseconds");
					Q.handle(state.onPlay, tool);

					// clear timer if exist
					tool.clearPlayInterval();

					// start new timer to change needed layout params during play
					state.playIntervalID = setInterval(function(){
						state.currentPosition = _getCurrentPostion();
						Q.handle(state.onPlaying, tool);
					}, 100);
				}, throttle);
				var onPause = Q.throttle(function () {
					var position = _getCurrentPostion();
					console.log("Paused at position " + position + " milliseconds");
					Q.handle(state.onPause, tool);
				}, throttle);
				var onEnded = Q.throttle(function () {
					var position = _getCurrentPostion();
					console.log("Seeked at position " + position + " milliseconds");
					Q.handle(state.onEnded, tool);
				}, throttle);

				state.player.addEventListener(Twitch.Player.PLAY, onPlay);
				state.player.addEventListener(Twitch.Player.PAUSE, onPause);
				state.player.addEventListener(Twitch.Player.ENDED, onEnded);
			});
		}
	};

	//tool.adapters.youtube = tool.adapters.vimeo = tool.adapters.mp4 = tool.adapters.webm = tool.adapters.general;

	var p = Q.pipe(['stylesheet', 'text', 'scripts'], function (params, subjects) {
		tool.text = params.text[1].video;
		tool.implement();
	});

	Q.addStylesheet(["{{Q}}/css/videojs.css", "{{Q}}/css/video.css"], p.fill('stylesheet'), { slotName: 'Q' });
	Q.addScript("{{Q}}/js/videojs/lib.js", p.fill('scripts'));
	Q.Text.get('Q/content', p.fill('text'));
},

{
	url: null,
	autoplay: false,
	throttle: 10,
	currentPosition: 0,
	clipStart: null,
	clipEnd: null,
	onSuccess: new Q.Event(),
	onError: new Q.Event(function (message) {
		alert('Flie upload error' + (message ? ': ' + message : '') + '.');
	}, 'Q/video'),
	onFinish: new Q.Event(),
	onLoad: new Q.Event(),
	onPlay: new Q.Event(function () {
		this.checkClip();
	}),
	onPlaying: new Q.Event(function () {
		this.checkClip();
	}),
	onPause: new Q.Event(function () {
		this.clearPlayInterval();
	}),
	onSeek: new Q.Event(),
	onEnded: new Q.Event(function () {
		// stop timer if exist
		this.clearPlayInterval();
	})
},

{
	/**
	 * Check clip borders and pause if outside
	 * @method checkClip
	 */
	checkClip: function () {
		var tool = this;
		var state = this.state;

		// clipStart handler
		if (state.clipStart && state.currentPosition < state.clipStart) {
			tool.setCurrentPosition(state.clipStart);
		}
		// clipStart handler
		if (state.clipEnd && state.currentPosition > state.clipEnd) {
			tool.pause();
			tool.setCurrentPosition(state.clipEnd);
		}
	},
	/**
	 * Refreshes the appearance of the tool completely
	 * @method implement
	 */
	implement: function () {
		var tool = this;

		var adapterName = tool.adapterNameFromUrl();
		tool.adapters[adapterName].init();
	},
	/**
	 *
	 * @method initVideojsPlayer
	 */
	initVideojsPlayer: function (options) {
		var tool = this;
		var state = this.state;
		var throttle = state.throttle;

		Q.Template.render('Q/video/videojs', {
			autoplay: state.autoplay ? 'autoplay' : '',
		}, function (err, html) {
			tool.element.innerHTML = html;

			var _getCurrentPostion = function () {
				return Math.trunc(state.player.currentTime() * 1000);
			};

			var onPlay = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Started at position " + position + " milliseconds");
				Q.handle(state.onPlay, tool, [position]);
			}, throttle);
			var onPause = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Paused at position " + position + " milliseconds");
				Q.handle(state.onPause, tool, [position]);
			}, throttle);
			var onSeek = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Seeked at position " + position + " milliseconds");
				Q.handle(state.onSeek, tool, [position]);
			}, throttle);
			var onEnded = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Seeked at position " + position + " milliseconds");
				Q.handle(state.onEnded, tool, [position]);
			}, throttle);

			state.player = videojs($("video", tool.element)[0], options, function onPlayerReady() {
				videojs.log('Your player is ready!');

				state.currentPosition = 0;

				this.on('play', function () {
					onPlay();
				});

				this.on('pause', function () {
					onPause();
				});

				this.on('seeking', function() {
					onPause();
				});

				this.on('waiting', function() {
					onPause();
				});

				this.on('seeked', function() {
					onPlay();
					onSeek();
				});

				this.on('ended', function() {
					onPause();
					onEnded();
				});

				// update currentPosition array on play
				this.on('timeupdate', function() {
					setTimeout(function(){
						state.currentPosition = _getCurrentPostion();
						Q.handle(state.onPlaying, tool, [state.currentPosition]);
					}, 500);
				});
			});
		});
	},
	/**
	 * @method play
	 */
	play: function () {
		this.state.player && this.state.player.play();
	},
	/**
	 * @method pause
	 */
	pause: function () {
		this.state.player && this.state.player.pause();
	},
	/**
	 * @method setCurrentPosition
	 * @param {integer} position in milliseonds
	 */
	setCurrentPosition: function (position) {
		this.state.player && this.state.player.currentTime(position/1000);
	},
	/**
	 * Detect adapter from url
	 * @method adapterNameFromUrl
	 */
	adapterNameFromUrl: function () {
		var url = this.state.url;
		if (!url) {
			throw new Q.Exception(this.id + ": url is required");
		}
		var newA = document.createElement('A');
		newA.href = url;
		var host = newA.hostname;

		if (host.includes("youtube.com") || host.includes("youtu.be")) {
			return 'youtube';
		} else if (host.includes("vimeo.com")) {
			return 'vimeo';
		} else if (host.includes("twitch")) {
			return 'twitch';
		}

		var ext = url.split('.').pop();
		switch(ext) {
			case 'webm': return 'webm';
			case 'ogg': return 'ogg';
			default: return 'mp4';
		}
		//throw new Q.Exception(this.id + ': No adapter for this URL');
	},
	/**
	 *
	 * @method clearPlayInterval
	 */
	clearPlayInterval: function () {
		var playIntervalID = this.state.playIntervalID;
		if (playIntervalID) {
			clearInterval(playIntervalID);
			playIntervalID = false;
		}
	},
	Q: {
		beforeRemove: function () {
			this.clearPlayInterval();
		}
	}
});

Q.Template.set('Q/video/videojs',
	'<video preload="auto" controls class="video-js vjs-default-skin vjs-4-3" width="100%" height="auto" {{autoplay}}/>'
);

})(window, Q, jQuery);<commit_msg>Added method getCurrentPosition to Q/video, and addded option "start". If start option defined, start play from this position.<commit_after>(function (window, Q, $, undefined) {

/**
 * @module Q
 */

/**
 * YUIDoc description goes here
 * @class Q video
 * @constructor
 * @param {Object} [options] Override various options for this tool
 *  @param {String} [options.url] URL of video source
 *  @param {string} [options.start] start position in milliseconds
 *  @param {string} [options.clipStart] Clip start position in milliseconds
 *  @param {string} [options.clipEnd] Clip end position in milliseconds
 *  @param {boolean} [options.autoplay=false] If true - start play on load
 */
Q.Tool.define("Q/video", function (options) {
	var tool = this;
	var state = tool.state;

	if (state.url) {
		state.url = state.url.interpolate({ "baseUrl": Q.info.baseUrl });
	}

	tool.adapters = {};

	tool.adapters.mp4 = {
		init: function () {
			var options = {
				sources: [{
					src: state.url,
					type: 'video/mp4'
				}]
			};

			tool.initVideojsPlayer(options);
		}
	};
	tool.adapters.webm = {
		init: function () {
			var options = {
				sources: [{
					src: state.url,
					type: 'video/webm'
				}]
			};

			tool.initVideojsPlayer(options);
		}
	};
	tool.adapters.ogg = {
		init: function () {
			var options = {
				sources: [{
					src: state.url,
					type: 'video/ogg'
				}]
			};

			tool.initVideojsPlayer(options);
		}
	};
	tool.adapters.youtube = {
		init: function () {
			Q.addScript("{{Q}}/js/videojs/plugins/YouTube.js", function () {
				var options = {
					techOrder: ["youtube"],
					sources: [{
						src: state.url,
						type: 'video/youtube'
					}],
					youtube: {
						ytControls: 2
					}
				};

				tool.initVideojsPlayer(options);
			});
		}
	};
	tool.adapters.vimeo = {
		init: function () {
			Q.addScript("{{Q}}/js/videojs/plugins/Vimeo.js", function () {
				var options = {
					techOrder: ["vimeo"],
					sources: [{
						src: state.url,
						type: 'video/vimeo'
					}],
					vimeo: {
						ytControls: 2
					}
				};

				tool.initVideojsPlayer(options);
			});
		}
	};
	tool.adapters.twitch = {
		init: function () {
			var element = tool.element;
			var throttle = state.throttle;

			var newA = document.createElement('A');
			newA.href = state.url;
			var host = newA.hostname;

			element.classList.add("Q_video_twitch");

			var options = {
				autoplay: false
				//channel: "<channel ID>",
				//video: "782042263",
				//collection: "<collection ID>"
			};

			// convert start time to pass as option
			if (state.start) {
				options.time = state.start.convertTimeToString(false).replace(/:/, 'h').replace(/:/, 'm') + 's';
			}
			if (state.clipStart) {
				options.time = state.clipStart.convertTimeToString(false).replace(/:/, 'h').replace(/:/, 'm') + 's';
			}

			var videoId = state.url.match(/\/videos\/([0-9]+).*$/);
			var channel = state.url.match(new RegExp(host + "/(\\w+)"));
			if (videoId) {
				options.video = videoId[1];
			} else if (channel) {
				options.channel = channel[1];
			} else {
				throw new Q.Error("Q/video/twitch: none of videoId or channel filled");
			}

			Q.addScript("{{Q}}/js/twitch/lib.js", function () {
				state.player = new Twitch.Player(element, options);
				state.player.currentTime = function (time) {
					state.player.seek(time);
				};

				var _getCurrentPostion = function () {
					return Math.trunc(state.player.getCurrentTime() * 1000);
				};

				var onPlay = Q.throttle(function () {
					state.currentPosition = _getCurrentPostion();
					console.log("Started at position " + state.currentPosition + " milliseconds");
					Q.handle(state.onPlay, tool);

					// clear timer if exist
					tool.clearPlayInterval();

					// start new timer to change needed layout params during play
					state.playIntervalID = setInterval(function(){
						state.currentPosition = _getCurrentPostion();
						Q.handle(state.onPlaying, tool);
					}, 100);
				}, throttle);
				var onPause = Q.throttle(function () {
					var position = _getCurrentPostion();
					console.log("Paused at position " + position + " milliseconds");
					Q.handle(state.onPause, tool);
				}, throttle);
				var onEnded = Q.throttle(function () {
					var position = _getCurrentPostion();
					console.log("Seeked at position " + position + " milliseconds");
					Q.handle(state.onEnded, tool);
				}, throttle);

				state.player.addEventListener(Twitch.Player.PLAY, onPlay);
				state.player.addEventListener(Twitch.Player.PAUSE, onPause);
				state.player.addEventListener(Twitch.Player.ENDED, onEnded);
			});
		}
	};

	//tool.adapters.youtube = tool.adapters.vimeo = tool.adapters.mp4 = tool.adapters.webm = tool.adapters.general;

	var p = Q.pipe(['stylesheet', 'text', 'scripts'], function (params, subjects) {
		tool.text = params.text[1].video;
		tool.implement();
	});

	Q.addStylesheet(["{{Q}}/css/videojs.css", "{{Q}}/css/video.css"], p.fill('stylesheet'), { slotName: 'Q' });
	Q.addScript("{{Q}}/js/videojs/lib.js", p.fill('scripts'));
	Q.Text.get('Q/content', p.fill('text'));
},

{
	url: null,
	autoplay: false,
	throttle: 10,
	currentPosition: 0,
	start: null,
	clipStart: null,
	clipEnd: null,
	videojsOptions: {
		controls: true
	},
	onSuccess: new Q.Event(),
	onError: new Q.Event(function (message) {
		alert('Flie upload error' + (message ? ': ' + message : '') + '.');
	}, 'Q/video'),
	onFinish: new Q.Event(),
	onLoad: new Q.Event(),
	onPlay: new Q.Event(function () {
		this.checkClip();
	}),
	onPlaying: new Q.Event(function () {
		this.checkClip();
	}),
	onPause: new Q.Event(function () {
		this.clearPlayInterval();
	}),
	onSeek: new Q.Event(),
	onEnded: new Q.Event(function () {
		// stop timer if exist
		this.clearPlayInterval();
	})
},

{
	/**
	 * Check clip borders and pause if outside
	 * @method checkClip
	 */
	checkClip: function () {
		var tool = this;
		var state = this.state;

		// clipStart handler
		if (state.clipStart && state.currentPosition < state.clipStart) {
			tool.setCurrentPosition(state.clipStart);
		}
		// clipStart handler
		if (state.clipEnd && state.currentPosition > state.clipEnd) {
			tool.pause();
			tool.setCurrentPosition(state.clipEnd);
		}
	},
	/**
	 * Refreshes the appearance of the tool completely
	 * @method implement
	 */
	implement: function () {
		var tool = this;

		var adapterName = tool.adapterNameFromUrl();
		tool.adapters[adapterName].init();
	},
	/**
	 *
	 * @method initVideojsPlayer
	 */
	initVideojsPlayer: function (options) {
		var tool = this;
		var state = this.state;
		var throttle = state.throttle;

		options = Q.extend(state.videojsOptions, options);

		Q.Template.render('Q/video/videojs', {
			autoplay: state.autoplay ? 'autoplay' : '',
		}, function (err, html) {
			tool.element.innerHTML = html;

			var _getCurrentPostion = function () {
				return Math.trunc(state.player.currentTime() * 1000);
			};

			var onPlay = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Started at position " + position + " milliseconds");
				Q.handle(state.onPlay, tool, [position]);
			}, throttle);
			var onPause = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Paused at position " + position + " milliseconds");
				Q.handle(state.onPause, tool, [position]);
			}, throttle);
			var onSeek = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Seeked at position " + position + " milliseconds");
				Q.handle(state.onSeek, tool, [position]);
			}, throttle);
			var onEnded = Q.throttle(function () {
				var position = state.currentPosition || _getCurrentPostion();
				console.log("Seeked at position " + position + " milliseconds");
				Q.handle(state.onEnded, tool, [position]);
			}, throttle);

			state.player = videojs($("video", tool.element)[0], options, function onPlayerReady() {
				videojs.log('Your player is ready!');

				if (state.clipStart || state.start) {
					var start = (state.clipStart || state.start)/1000;
					this.currentTime(start);
					state.currentPosition = start;
				} else {
					state.currentPosition = 0;
				}

				this.on('play', function () {
					onPlay();
				});

				this.on('pause', function () {
					onPause();
				});

				this.on('seeking', function() {
					onPause();
				});

				this.on('waiting', function() {
					onPause();
				});

				this.on('seeked', function() {
					onPlay();
					onSeek();
				});

				this.on('ended', function() {
					onPause();
					onEnded();
				});

				// update currentPosition array on play
				this.on('timeupdate', function() {
					setTimeout(function(){
						state.currentPosition = _getCurrentPostion();
						Q.handle(state.onPlaying, tool, [state.currentPosition]);
					}, 500);
				});
			});
		});
	},
	/**
	 * @method play
	 */
	play: function () {
		this.state.player && this.state.player.play();
	},
	/**
	 * @method pause
	 */
	pause: function () {
		this.state.player && this.state.player.pause();
	},
	/**
	 * @method setCurrentPosition
	 * @param {integer} position in milliseonds
	 */
	setCurrentPosition: function (position) {
		this.state.player && this.state.player.currentTime(position/1000);
	},
	/**
	 * @method getCurrentPosition
	 */
	getCurrentPosition: function () {
		return this.state.currentPosition;
	},
	/**
	 * Detect adapter from url
	 * @method adapterNameFromUrl
	 */
	adapterNameFromUrl: function () {
		var url = this.state.url;
		if (!url) {
			throw new Q.Exception(this.id + ": url is required");
		}
		var newA = document.createElement('A');
		newA.href = url;
		var host = newA.hostname;

		if (host.includes("youtube.com") || host.includes("youtu.be")) {
			return 'youtube';
		} else if (host.includes("vimeo.com")) {
			return 'vimeo';
		} else if (host.includes("twitch")) {
			return 'twitch';
		}

		var ext = url.split('.').pop();
		switch(ext) {
			case 'webm': return 'webm';
			case 'ogg': return 'ogg';
			default: return 'mp4';
		}
		//throw new Q.Exception(this.id + ': No adapter for this URL');
	},
	/**
	 *
	 * @method clearPlayInterval
	 */
	clearPlayInterval: function () {
		var playIntervalID = this.state.playIntervalID;
		if (playIntervalID) {
			clearInterval(playIntervalID);
			playIntervalID = false;
		}
	},
	Q: {
		beforeRemove: function () {
			this.clearPlayInterval();

			// if videojs, call dispose to kill this player with events, triggers, dom etc
			if (Q.getObject("player.dispose", this.state)) {
				this.state.player.dispose();
			}
		}
	}
});

Q.Template.set('Q/video/videojs',
	'<video preload="auto" controls class="video-js vjs-default-skin vjs-4-3" width="100%" height="auto" {{autoplay}}/>'
);

})(window, Q, jQuery);<|endoftext|>


<commit_before><commit_msg>add desc<commit_after><|endoftext|>


<commit_before>var WebSocket = require('ws')
  , ws = new WebSocket('ws://localhost:8080');

ws.on('open', function()
      {
          //ws.send('something');
          console.log('connected');
      });

var ctrl_msg = null;
var encoder_timer = null;
var encoder1 = 0;

function encoder_calculator()
{
    // Send control signal and read actual encoder values

    if(ctrl_msg.encoder1 > 0)
    {
        ctrl_msg.encoder1 -= 1;
    }
    else
    {
        if(encoder_timer != null)
            clearInterval(encoder_timer);
        ws.send('OK');
    }
};

ws.on('message', function(message)
      {
          console.log('received: %s', message);

          try
          {
              ctrl_msg = JSON.parse(message);
              encoder_timer = setInterval(encoder_calculator, 100);
          }
          catch(err) // Handle json.parse synchronous errors
          {
              ws.send('NOK');
              console.error('message parsing error: ' + err);
          }
      });
<commit_msg>Find out correct ws url<commit_after>var WebSocket = require('ws')
var ws = new WebSocket('wss://actionserver.herokuapp.com');
//var ws = new WebSocket('ws://localhost:5000');

ws.on('open', function()
      {
          //ws.send('something');
          console.log('connected');
      });

var ctrl_msg = null;
var encoder_timer = null;
var encoder1 = 0;

function encoder_calculator()
{
    // Send control signal and read actual encoder values

    if(ctrl_msg.encoder1 > 0)
    {
        ctrl_msg.encoder1 -= 1;
    }
    else
    {
        if(encoder_timer != null)
            clearInterval(encoder_timer);
        ws.send('OK');
    }
};

ws.on('message', function(message)
      {
          console.log('received: %s', message);

          try
          {
              ctrl_msg = JSON.parse(message);
              encoder_timer = setInterval(encoder_calculator, 100);
          }
          catch(err) // Handle json.parse synchronous errors
          {
              ws.send('NOK');
              console.error('message parsing error: ' + err);
          }
      });
<|endoftext|>


<commit_before>// jscs:disable requireParenthesesAroundArrowParam

import { pluralize, camelize } from './utils/inflector';
import Pretender from 'pretender';
import Db from './db';
import Schema from './orm/schema';
import assert from './assert';
import SerializerRegistry from './serializer-registry';
import RouteHandler from './route-handler';

import _isArray from 'lodash/lang/isArray';
import _keys from 'lodash/object/keys';
import _pick from 'lodash/object/pick';
import _assign from 'lodash/object/assign';

function createPretender(server) {
  return new Pretender(function() {
    this.passthroughRequest = function(verb, path, request) {
      if (server.shouldLog()) {
        console.log(`Passthrough request: ${verb.toUpperCase()} ${request.url}`);
      }
    };

    this.handledRequest = function(verb, path, request) {
      if (server.shouldLog()) {
        console.log(`Successful request: ${verb.toUpperCase()} $[request.url}`);
        let { responseText } = request;
        let loggedResponse;

        try {
          loggedResponse = JSON.parse(responseText);
        } catch(e) {
          loggedResponse = responseText;
        }

        console.log(loggedResponse);
      }
    };

    this.unhandledRequest = function(verb, path) {
      path = decodeURI(path);
      assert(
        `Your Ember app tried to ${verb} '${path}',
         but there was no route defined to handle this request.
         Define a route that matches this path in your
         mirage/config.js file. Did you forget to add your namespace?`
      );
    };
  });
}

const defaultRouteOptions = {
  coalesce: false,
  timing: undefined
};

const defaultPassthroughs = [
  'http://localhost:0/chromecheckurl'
];
export { defaultPassthroughs };

function isOption(option) {
  if (!option || typeof option !== 'object') {
    return false;
  }

  let allOptions = Object.keys(defaultRouteOptions);
  let optionKeys = Object.keys(option);
  for (let i = 0; i < optionKeys.length; i++) {
    let key = optionKeys[i];
    if (allOptions.indexOf(key) > -1) {
      return true;
    }
  }
  return false;
}

/*
  Args can be of the form
    [options]
    [object, code]
    [function, code]
    [shorthand, options]
    [shorthand, code, options]
    with all optional. This method returns an array of
    [handler (i.e. the function, object or shorthand), code, options].
*/

function extractRouteArguments(args) {
  let [ lastArg ] = args.splice(-1);
  if (isOption(lastArg)) {
    lastArg = _assign({}, defaultRouteOptions, lastArg);
  } else {
    args.push(lastArg);
    lastArg = defaultRouteOptions;
  }
  let t = 2 - args.length;
  while (t-- > 0) {
    args.push(undefined);
  }
  args.push(lastArg);
  return args;
}

export default class Server {

  constructor(options = {}) {
    this.environment = options.environment || 'development';
    this.options = options;
    this.timing = 400;
    this.namespace = '';
    this.urlPrefix = '';

    this._defineRouteHandlerHelpers();

    this.db = new Db();
    this.schema = new Schema(this.db, options.models);
    this.serializerOrRegistry = new SerializerRegistry(this.schema, options.serializers);

    let hasFactories = this._hasModulesOfType(options, 'factories');
    let hasDefaultScenario = options.scenarios && options.scenarios.hasOwnProperty('default');

    this.pretender = createPretender(this);

    if (options.baseConfig) {
      this.loadConfig(options.baseConfig);
    }

    if (this.isTest()) {
      if (options.testConfig) {
        this.loadConfig(options.testConfig);
      }

      window.server = this; // TODO: Better way to inject server into test env
    }

    if (this.isTest() && hasFactories) {
      this.loadFactories(options.factories);
    } else if (!this.isTest() && hasDefaultScenario && hasFactories) {
      this.loadFactories(options.factories);
      options.scenarios.default(this);
    } else {
      this.loadFixtures();
    }

    if (options.useDefaultPassthroughs) {
      this._configureDefaultPassthroughs();
    }
  }

  isTest() {
    return this.environment === 'test';
  }

  shouldLog() {
    return typeof this.logging !== 'undefined' ? this.logging : !this.isTest();
  }

  loadConfig(config) {
    config.call(this);
    this.timing = this.isTest() ? 0 : (this.timing || 0);
  }

  passthrough(...paths) {
    let verbs = ['get', 'post', 'put', 'delete', 'patch'];
    let lastArg = paths[paths.length - 1];

    if (paths.length === 0) {
      paths = ['/*catchall'];
    } else if (_isArray(lastArg)) {
      verbs = paths.pop();
    }

    verbs.forEach(verb => {
      paths.forEach(path => {
        let fullPath = this._getFullPath(path);
        this.pretender[verb](fullPath, this.pretender.passthrough);
      });
    });
  }

  loadFixtures(...args) {
    let { fixtures } = this.options;
    if (args.length) {
      let camelizedArgs = args.map(camelize);
      fixtures = _pick(fixtures, ...camelizedArgs);
    }

    this.db.loadData(fixtures);
  }

  /*
    Factory methods
  */
  loadFactories(factoryMap) {
    // Store a reference to the factories
    this._factoryMap = factoryMap;

    // Create a collection for each factory
    _keys(factoryMap).forEach(type => {
      let collectionName = this.schema ? pluralize(camelize(type)) : pluralize(type);
      this.db.createCollection(collectionName);
    });
  }

  build(type, overrides) {
    let camelizedType = camelize(type);

    // Store sequence for factory type as instance variable
    this.factorySequences = this.factorySequences || {};
    this.factorySequences[camelizedType] = this.factorySequences[camelizedType] + 1 || 0;

    assert(
      this._factoryMap && this._factoryMap[camelizedType],
      `You're trying to create a ${camelizedType}, but no factory for this type was found`
    );

    let OriginalFactory = this._factoryMap[camelizedType];
    let Factory = OriginalFactory.extend(overrides);
    let factory = new Factory();

    let sequence = this.factorySequences[camelizedType];
    return factory.build(sequence);
  }

  buildList(type, amount, overrides) {
    let list = [];

    for (let i = 0; i < amount; i++) {
      list.push(this.build(type, overrides));
    }

    return list;
  }

  create(type, overrides, collectionFromCreateList) {
    let attrs = this.build(type, overrides);
    let collection, collectionName;
    if (collectionFromCreateList) {
      collection = collectionFromCreateList;
    } else {
      collectionName = this.schema ? pluralize(camelize(type)) : pluralize(type);
      collection = this.db[collectionName];
    }

    let inserted = collection.insert(attrs);
    if (this.schema && this.schema[camelize(type)]) {
      // When there is a Model defined, we should return an instance
      // of it instead of returning the bare attributes.
      // https://github.com/samselikoff/ember-cli-mirage/issues/427
      return this.schema[camelize(type)].find(inserted.id);
    } else {
      return inserted;
    }
  }

  createList(type, amount, overrides) {
    let list = [];
    let collectionName = this.schema ? pluralize(camelize(type)) : pluralize(type);
    let collection = this.db[collectionName];

    for (let i = 0; i < amount; i++) {
      list.push(this.create(type, overrides, collection));
    }

    return list;
  }

  shutdown() {
    this.pretender.shutdown();
    if (this.environment === 'test') {
      window.server = undefined;
    }
  }

  _defineRouteHandlerHelpers() {
    [['get'], ['post'], ['put'], ['delete', 'del'], ['patch']].forEach(([verb, alias]) => {
      this[verb] = (path, ...args) => {
        let [ rawHandler, customizedCode, options ] = extractRouteArguments(args);
        this._registerRouteHandler(verb, path, rawHandler, customizedCode, options);
      };

      if (alias) {
        this[alias] = this[verb];
      }
    });
  }

  _serialize(body) {
    if (body) {
      return typeof body !== 'string' ? JSON.stringify(body) : body;
    } else {
      return '{"error": "not found"}';
    }
  }

  _registerRouteHandler(verb, path, rawHandler, customizedCode, options) {

    let routeHandler = new RouteHandler({
      schema: this.schema,
      verb, rawHandler, customizedCode, options, path,
      serializerOrRegistry: this.serializerOrRegistry
    });

    let fullPath = this._getFullPath(path);
    let timing = options.timing !== undefined ? options.timing : (() => this.timing);

    this.pretender[verb](
      fullPath,
      (request) => {
        let [ code, headers, response ] = routeHandler.handle(request);
        return [ code, headers, this._serialize(response) ];
      },
      timing
    );
  }

  _hasModulesOfType(modules, type) {
    let modulesOfType = modules[type];
    return modulesOfType ? _keys(modulesOfType).length > 0 : false;
  }

  /*
    Builds a full path for Pretender to monitor based on the `path` and
    configured options (`urlPrefix` and `namespace`).
  */
  _getFullPath(path) {
    path = path[0] === '/' ? path.slice(1) : path;
    let fullPath = '';
    let urlPrefix = this.urlPrefix ? this.urlPrefix.trim() : '';
    let namespace = this.namespace ? this.namespace.trim() : '';

    // check to see if path is a FQDN. if so, ignore any urlPrefix/namespace that was set
    if (/^https?:\/\//.test(path)) {
      fullPath += path;
    } else {

      // otherwise, if there is a urlPrefix, use that as the beginning of the path
      if (!!urlPrefix.length) {
        fullPath += urlPrefix[urlPrefix.length - 1] === '/' ? urlPrefix : `${urlPrefix}/`;
      }

      // if a namespace has been configured, add it before the path
      if (!!namespace.length) {
        fullPath += namespace ? `${namespace}/` : namespace;
      }

      // finally add the configured path
      fullPath += path;
    }

    return fullPath;
  }

  _configureDefaultPassthroughs() {
    defaultPassthroughs.forEach(passthroughUrl => {
      this.passthrough(passthroughUrl);
    });
  }
}
<commit_msg>Fix typo in handledRequest string interp.<commit_after>// jscs:disable requireParenthesesAroundArrowParam

import { pluralize, camelize } from './utils/inflector';
import Pretender from 'pretender';
import Db from './db';
import Schema from './orm/schema';
import assert from './assert';
import SerializerRegistry from './serializer-registry';
import RouteHandler from './route-handler';

import _isArray from 'lodash/lang/isArray';
import _keys from 'lodash/object/keys';
import _pick from 'lodash/object/pick';
import _assign from 'lodash/object/assign';

function createPretender(server) {
  return new Pretender(function() {
    this.passthroughRequest = function(verb, path, request) {
      if (server.shouldLog()) {
        console.log(`Passthrough request: ${verb.toUpperCase()} ${request.url}`);
      }
    };

    this.handledRequest = function(verb, path, request) {
      if (server.shouldLog()) {
        console.log(`Successful request: ${verb.toUpperCase()} ${request.url}`);
        let { responseText } = request;
        let loggedResponse;

        try {
          loggedResponse = JSON.parse(responseText);
        } catch(e) {
          loggedResponse = responseText;
        }

        console.log(loggedResponse);
      }
    };

    this.unhandledRequest = function(verb, path) {
      path = decodeURI(path);
      assert(
        `Your Ember app tried to ${verb} '${path}',
         but there was no route defined to handle this request.
         Define a route that matches this path in your
         mirage/config.js file. Did you forget to add your namespace?`
      );
    };
  });
}

const defaultRouteOptions = {
  coalesce: false,
  timing: undefined
};

const defaultPassthroughs = [
  'http://localhost:0/chromecheckurl'
];
export { defaultPassthroughs };

function isOption(option) {
  if (!option || typeof option !== 'object') {
    return false;
  }

  let allOptions = Object.keys(defaultRouteOptions);
  let optionKeys = Object.keys(option);
  for (let i = 0; i < optionKeys.length; i++) {
    let key = optionKeys[i];
    if (allOptions.indexOf(key) > -1) {
      return true;
    }
  }
  return false;
}

/*
  Args can be of the form
    [options]
    [object, code]
    [function, code]
    [shorthand, options]
    [shorthand, code, options]
    with all optional. This method returns an array of
    [handler (i.e. the function, object or shorthand), code, options].
*/

function extractRouteArguments(args) {
  let [ lastArg ] = args.splice(-1);
  if (isOption(lastArg)) {
    lastArg = _assign({}, defaultRouteOptions, lastArg);
  } else {
    args.push(lastArg);
    lastArg = defaultRouteOptions;
  }
  let t = 2 - args.length;
  while (t-- > 0) {
    args.push(undefined);
  }
  args.push(lastArg);
  return args;
}

export default class Server {

  constructor(options = {}) {
    this.environment = options.environment || 'development';
    this.options = options;
    this.timing = 400;
    this.namespace = '';
    this.urlPrefix = '';

    this._defineRouteHandlerHelpers();

    this.db = new Db();
    this.schema = new Schema(this.db, options.models);
    this.serializerOrRegistry = new SerializerRegistry(this.schema, options.serializers);

    let hasFactories = this._hasModulesOfType(options, 'factories');
    let hasDefaultScenario = options.scenarios && options.scenarios.hasOwnProperty('default');

    this.pretender = createPretender(this);

    if (options.baseConfig) {
      this.loadConfig(options.baseConfig);
    }

    if (this.isTest()) {
      if (options.testConfig) {
        this.loadConfig(options.testConfig);
      }

      window.server = this; // TODO: Better way to inject server into test env
    }

    if (this.isTest() && hasFactories) {
      this.loadFactories(options.factories);
    } else if (!this.isTest() && hasDefaultScenario && hasFactories) {
      this.loadFactories(options.factories);
      options.scenarios.default(this);
    } else {
      this.loadFixtures();
    }

    if (options.useDefaultPassthroughs) {
      this._configureDefaultPassthroughs();
    }
  }

  isTest() {
    return this.environment === 'test';
  }

  shouldLog() {
    return typeof this.logging !== 'undefined' ? this.logging : !this.isTest();
  }

  loadConfig(config) {
    config.call(this);
    this.timing = this.isTest() ? 0 : (this.timing || 0);
  }

  passthrough(...paths) {
    let verbs = ['get', 'post', 'put', 'delete', 'patch'];
    let lastArg = paths[paths.length - 1];

    if (paths.length === 0) {
      paths = ['/*catchall'];
    } else if (_isArray(lastArg)) {
      verbs = paths.pop();
    }

    verbs.forEach(verb => {
      paths.forEach(path => {
        let fullPath = this._getFullPath(path);
        this.pretender[verb](fullPath, this.pretender.passthrough);
      });
    });
  }

  loadFixtures(...args) {
    let { fixtures } = this.options;
    if (args.length) {
      let camelizedArgs = args.map(camelize);
      fixtures = _pick(fixtures, ...camelizedArgs);
    }

    this.db.loadData(fixtures);
  }

  /*
    Factory methods
  */
  loadFactories(factoryMap) {
    // Store a reference to the factories
    this._factoryMap = factoryMap;

    // Create a collection for each factory
    _keys(factoryMap).forEach(type => {
      let collectionName = this.schema ? pluralize(camelize(type)) : pluralize(type);
      this.db.createCollection(collectionName);
    });
  }

  build(type, overrides) {
    let camelizedType = camelize(type);

    // Store sequence for factory type as instance variable
    this.factorySequences = this.factorySequences || {};
    this.factorySequences[camelizedType] = this.factorySequences[camelizedType] + 1 || 0;

    assert(
      this._factoryMap && this._factoryMap[camelizedType],
      `You're trying to create a ${camelizedType}, but no factory for this type was found`
    );

    let OriginalFactory = this._factoryMap[camelizedType];
    let Factory = OriginalFactory.extend(overrides);
    let factory = new Factory();

    let sequence = this.factorySequences[camelizedType];
    return factory.build(sequence);
  }

  buildList(type, amount, overrides) {
    let list = [];

    for (let i = 0; i < amount; i++) {
      list.push(this.build(type, overrides));
    }

    return list;
  }

  create(type, overrides, collectionFromCreateList) {
    let attrs = this.build(type, overrides);
    let collection, collectionName;
    if (collectionFromCreateList) {
      collection = collectionFromCreateList;
    } else {
      collectionName = this.schema ? pluralize(camelize(type)) : pluralize(type);
      collection = this.db[collectionName];
    }

    let inserted = collection.insert(attrs);
    if (this.schema && this.schema[camelize(type)]) {
      // When there is a Model defined, we should return an instance
      // of it instead of returning the bare attributes.
      // https://github.com/samselikoff/ember-cli-mirage/issues/427
      return this.schema[camelize(type)].find(inserted.id);
    } else {
      return inserted;
    }
  }

  createList(type, amount, overrides) {
    let list = [];
    let collectionName = this.schema ? pluralize(camelize(type)) : pluralize(type);
    let collection = this.db[collectionName];

    for (let i = 0; i < amount; i++) {
      list.push(this.create(type, overrides, collection));
    }

    return list;
  }

  shutdown() {
    this.pretender.shutdown();
    if (this.environment === 'test') {
      window.server = undefined;
    }
  }

  _defineRouteHandlerHelpers() {
    [['get'], ['post'], ['put'], ['delete', 'del'], ['patch']].forEach(([verb, alias]) => {
      this[verb] = (path, ...args) => {
        let [ rawHandler, customizedCode, options ] = extractRouteArguments(args);
        this._registerRouteHandler(verb, path, rawHandler, customizedCode, options);
      };

      if (alias) {
        this[alias] = this[verb];
      }
    });
  }

  _serialize(body) {
    if (body) {
      return typeof body !== 'string' ? JSON.stringify(body) : body;
    } else {
      return '{"error": "not found"}';
    }
  }

  _registerRouteHandler(verb, path, rawHandler, customizedCode, options) {

    let routeHandler = new RouteHandler({
      schema: this.schema,
      verb, rawHandler, customizedCode, options, path,
      serializerOrRegistry: this.serializerOrRegistry
    });

    let fullPath = this._getFullPath(path);
    let timing = options.timing !== undefined ? options.timing : (() => this.timing);

    this.pretender[verb](
      fullPath,
      (request) => {
        let [ code, headers, response ] = routeHandler.handle(request);
        return [ code, headers, this._serialize(response) ];
      },
      timing
    );
  }

  _hasModulesOfType(modules, type) {
    let modulesOfType = modules[type];
    return modulesOfType ? _keys(modulesOfType).length > 0 : false;
  }

  /*
    Builds a full path for Pretender to monitor based on the `path` and
    configured options (`urlPrefix` and `namespace`).
  */
  _getFullPath(path) {
    path = path[0] === '/' ? path.slice(1) : path;
    let fullPath = '';
    let urlPrefix = this.urlPrefix ? this.urlPrefix.trim() : '';
    let namespace = this.namespace ? this.namespace.trim() : '';

    // check to see if path is a FQDN. if so, ignore any urlPrefix/namespace that was set
    if (/^https?:\/\//.test(path)) {
      fullPath += path;
    } else {

      // otherwise, if there is a urlPrefix, use that as the beginning of the path
      if (!!urlPrefix.length) {
        fullPath += urlPrefix[urlPrefix.length - 1] === '/' ? urlPrefix : `${urlPrefix}/`;
      }

      // if a namespace has been configured, add it before the path
      if (!!namespace.length) {
        fullPath += namespace ? `${namespace}/` : namespace;
      }

      // finally add the configured path
      fullPath += path;
    }

    return fullPath;
  }

  _configureDefaultPassthroughs() {
    defaultPassthroughs.forEach(passthroughUrl => {
      this.passthrough(passthroughUrl);
    });
  }
}
<|endoftext|>


<commit_before>function SolarAltitude(win, doc, $) {
    var priv = {}, pub = {};

    // ----------------------------------------------------------------------------------------------- Private

    priv.shapes = {
        world: $('.application'),
        north: $('#north'),
        east:  $('#east'),
        south: $('#south'),
        west:  $('#west')
    };

    priv.time = 12; // 00:00 - 24:00

    priv.worldColor = {
        r: 255,
        g: 255,
        b: 255
    };

    priv.cubeColor = {
        north: { r: 127, g: 127, b: 127 },
        east:  { r: 127, g: 127, b: 127 },
        south: { r: 127, g: 127, b: 127 },
        west:  { r: 127, g: 127, b: 127 }
    };

    priv.solarColor = {
        sunrise:  { r: 100, g: 0,   b: 0   },
        midday:   { r: 100, g: 100, b: 0   },
        sunset:   { r: 100, g: 0,   b: 0   },
        moonrise: { r: 0,   g: 0,   b: 50  },
        midnight: { r: 0,   g: 0,   b: 100 },
        moonset:  { r: 0,   g: 0,   b: 50  }
    };

    priv.getBrightness = function getBrightness(time) {
        var brightness = 0;

        if (time >= 0 && time < 12) {
            brightness = ((100 / 12) * time);
        }
        else {
            brightness = 100 - ((100 / 12) * (time-12));
        }

        return brightness;
    };

    // ------------------------------------------------------------------------------------------------ Public

    pub.init = function () {
        pub.updateColors();

        // Simulate a day
        /** /
        setInterval(function() {
            priv.time += 0.1;
            if (priv.time >= 24) {
                priv.time = 0;
            }
            pub.updateColors();
        }, 100);
        /**/
    };

    // Returns percentage brightness
    priv.getBrightness = function getBrightness(time) {
        var min        = 25,
            max        = 100,
            brightness = min;

        if (time >= 0 && time < 12) {
            brightness = min + ((time * (max - min)) / 12);
        }
        else if (time >= 12 && time <= 24 ) {
            brightness = max - (((time - 12) * (max - min)) / 12);
        }

        return brightness;
    };

    pub.updateColors = function updateColors() {
        var brightness = priv.getBrightness(priv.time),
            r, g, b;

        // Render world color
        r = Math.round((priv.worldColor.r / 100) * brightness);
        g = Math.round((priv.worldColor.g / 100) * brightness);
        b = Math.round((priv.worldColor.b / 100) * brightness);
        priv.shapes.world.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.north.r / 100) * brightness);
        g = Math.round((priv.cubeColor.north.g / 100) * brightness);
        b = Math.round((priv.cubeColor.north.b / 100) * brightness);
        priv.shapes.north.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.east.r / 100) * brightness);
        g = Math.round((priv.cubeColor.east.g / 100) * brightness);
        b = Math.round((priv.cubeColor.east.b / 100) * brightness);
        priv.shapes.east.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.south.r / 100) * brightness);
        g = Math.round((priv.cubeColor.south.g / 100) * brightness);
        b = Math.round((priv.cubeColor.south.b / 100) * brightness);
        priv.shapes.south.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.west.r / 100) * brightness);
        g = Math.round((priv.cubeColor.west.g / 100) * brightness);
        b = Math.round((priv.cubeColor.west.b / 100) * brightness);
        priv.shapes.west.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Logging
        /** /
        console.log(brightness);
        console.log(r);
        console.log(g);
        console.log(b);
        /**/
    };

    // ------------------------------------------------------------------------------------------------ Return

    return pub;

}

// ----------------------------------------------------------------------------------------------------- Run application

jQuery(document).ready(function() {
    'use strict';

    var solarAltitude = new SolarAltitude(window, document, jQuery);

    solarAltitude.init();
});
<commit_msg>World and cube color rendered with colored light.<commit_after>function SolarAltitude(win, doc, $) {
    var priv = {}, pub = {};

    // ----------------------------------------------------------------------------------------------- Private

    priv.shapes = {
        world: $('.application'),
        north: $('#north'),
        east:  $('#east'),
        south: $('#south'),
        west:  $('#west')
    };

    priv.time = 12; // 00:00 - 24:00

    priv.worldColor = {
        r: 255,
        g: 255,
        b: 255
    };

    priv.cubeColor = {
        north: { r: 127, g: 127, b: 127 },
        east:  { r: 127, g: 127, b: 127 },
        south: { r: 127, g: 127, b: 127 },
        west:  { r: 127, g: 127, b: 127 }
    };

    priv.solarColor = {
        sunrise:  { r: 255, g: 0,   b: 0   },
        midday:   { r: 255, g: 255, b: 0   },
        sunset:   { r: 255, g: 0,   b: 0   },
        moonrise: { r: 0,   g: 0,   b: 50  },
        midnight: { r: 0,   g: 0,   b: 100 },
        moonset:  { r: 0,   g: 0,   b: 50  }
    };

    // Returns percentage brightness
    priv.getBrightness = function getBrightness(time) {
        var min        = 25,
            max        = 100,
            brightness = min;

        if (time >= 0 && time < 12) {
            brightness = min + ((time * (max - min)) / 12);
        }
        else if (time >= 12 && time <= 24 ) {
            brightness = max - (((time - 12) * (max - min)) / 12);
        }

        return brightness;
    };

    priv.getSolarColor = function getSolarColor(time) {
        var solarColor = { r: 255, g: 255, b: 255 };

        return solarColor;
    };

    // ------------------------------------------------------------------------------------------------ Public

    pub.init = function () {
        pub.updateColors();

        // Simulate a day
        /** /
        setInterval(function() {
            priv.time += 1;
            if (priv.time >= 24) {
                priv.time = 0;
            }
            pub.updateColors();
        }, 100);
        /**/
    };

    pub.updateColors = function updateColors() {
        var brightness = priv.getBrightness(priv.time),
            solarColor = priv.getSolarColor(priv.time),
            r, g, b;

        // Render world color
        r = Math.round((priv.worldColor.r + solarColor.r) / 200 * brightness);
        g = Math.round((priv.worldColor.g + solarColor.g) / 200 * brightness);
        b = Math.round((priv.worldColor.b + solarColor.b) / 200 * brightness);
        priv.shapes.world.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.north.r + solarColor.r) / 200 * brightness);
        g = Math.round((priv.cubeColor.north.g + solarColor.g) / 200 * brightness);
        b = Math.round((priv.cubeColor.north.b + solarColor.b) / 200 * brightness);
        priv.shapes.north.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.east.r + solarColor.r) / 200 * brightness);
        g = Math.round((priv.cubeColor.east.g + solarColor.g) / 200 * brightness);
        b = Math.round((priv.cubeColor.east.b + solarColor.b) / 200 * brightness);
        priv.shapes.east.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.south.r + solarColor.r) / 200 * brightness);
        g = Math.round((priv.cubeColor.south.g + solarColor.g) / 200 * brightness);
        b = Math.round((priv.cubeColor.south.b + solarColor.b) / 200 * brightness);
        priv.shapes.south.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round((priv.cubeColor.west.r + solarColor.r) / 200 * brightness);
        g = Math.round((priv.cubeColor.west.g + solarColor.g) / 200 * brightness);
        b = Math.round((priv.cubeColor.west.b + solarColor.b) / 200 * brightness);
        priv.shapes.west.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Logging
        /** /
        console.log(brightness);
        console.log(solarColor);
        console.log(r);
        console.log(g);
        console.log(b);
        /**/
    };

    // ------------------------------------------------------------------------------------------------ Return

    return pub;

}

// ----------------------------------------------------------------------------------------------------- Run application

jQuery(document).ready(function() {
    'use strict';

    var solarAltitude = new SolarAltitude(window, document, jQuery);

    solarAltitude.init();
});
<|endoftext|>


<commit_before>"use strict"

var abs = Math.abs
  , min = Math.min

function almostEqual(a, b, absoluteError, relativeError) {
  var d = abs(a - b)
  if(d <= absoluteError) {
    return true
  }
  if(d <= relativeError * min(abs(a), abs(b))) {
    return true
  }
  return a === b
}

almostEqual.FLT_EPSILON = 1.19209290e-7
almostEqual.DBL_EPSILON = 2.2204460492503131e-16

module.exports = almostEqual
<commit_msg>Do not force error values<commit_after>"use strict"

var abs = Math.abs
  , min = Math.min

function almostEqual(a, b, absoluteError, relativeError) {
  var d = abs(a - b)

  if (absoluteError == null) absoluteError = almostEqual.FLT_EPSILON;
  if (relativeError == null) relativeError = almostEqual.FLT_EPSILON;

  if(d <= absoluteError) {
    return true
  }
  if(d <= relativeError * min(abs(a), abs(b))) {
    return true
  }
  return a === b
}

almostEqual.FLT_EPSILON = 1.19209290e-7
almostEqual.DBL_EPSILON = 2.2204460492503131e-16

module.exports = almostEqual
<|endoftext|>


<commit_before>angular.module('cgBusy',[]);

//loosely modeled after angular-promise-tracker
angular.module('cgBusy').factory('_cgBusyTrackerFactory',['$timeout','$q',function($timeout,$q){

    return function(){

        var tracker = {};
        tracker.promises = [];
        tracker.delayPromise = null;
        tracker.durationPromise = null;
        tracker.delayJustFinished = false;

        tracker.reset = function(options){
            tracker.minDuration = options.minDuration;

            tracker.promises = [];
            angular.forEach(options.promises,function(p){
                if (!p || p.$cgBusyFulfilled) {
                    return;
                }
                addPromiseLikeThing(p);
            });

            if (tracker.promises.length === 0) {
                //if we have no promises then dont do the delay or duration stuff
                return;
            }

            tracker.delayJustFinished = false;
            if (options.delay) {
                tracker.delayPromise = $timeout(function(){
                    tracker.delayPromise = null;
                    tracker.delayJustFinished = true;
                },parseInt(options.delay,10));
            }
            if (options.minDuration) {
                tracker.durationPromise = $timeout(function(){
                    tracker.durationPromise = null;
                },parseInt(options.minDuration,10) + (options.delay ? parseInt(options.delay,10) : 0));
            }
        };

        tracker.isPromise = function(promiseThing){
            var then = promiseThing && (promiseThing.then || promiseThing.$then ||
                (promiseThing.$promiseThing && promiseThing.$promiseThing.then));

            return typeof then !== 'undefined';
        };

        tracker.callThen = function(promiseThing,success,error){
            var promise;
            if (promiseThing.then || promiseThing.$then){
                promise = promiseThing;
            } else if (promiseThing.$promise){
                promise = promiseThing.$promise;
            } else if (promiseThing.denodeify){
                promise = $q.when(promiseThing);
            }

            var then = (promise.then || promise.$them);

            then.call(promise,success,error);
        };

        var addPromiseLikeThing = function(promise){

            if (!tracker.isPromise(promise)) {
                throw new Error('cgBusy expects a promise (or something that has a .promise or .$promise');
            }

            if (tracker.promises.indexOf(promise) !== -1){
                return;
            }
            tracker.promises.push(promise);

            tracker.callThen(promise, function(){
                promise.$cgBusyFulfilled = true;
                if (tracker.promises.indexOf(promise) === -1) {
                    return;
                }
                tracker.promises.splice(tracker.promises.indexOf(promise),1);
            },function(){
                promise.$cgBusyFulfilled = true;
                if (tracker.promises.indexOf(promise) === -1) {
                    return;
                }
                tracker.promises.splice(tracker.promises.indexOf(promise),1);
            });
        };

        tracker.active = function(){
            if (tracker.delayPromise){
                return false;
            }

            if (!tracker.delayJustFinished){
                if (tracker.durationPromise){
                    return true;
                }
                return tracker.promises.length > 0;
            } else {
                //if both delay and min duration are set,
                //we don't want to initiate the min duration if the
                //promise finished before the delay was complete
                tracker.delayJustFinished = false;
                return tracker.promises.length > 0;
            }
        };

        return tracker;

    };
}]);

angular.module('cgBusy').value('cgBusyDefaults',{});

angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusyDefaults','$http','_cgBusyTrackerFactory',
    function($compile,$templateCache,cgBusyDefaults,$http,_cgBusyTrackerFactory){
        return {
            restrict: 'A',
            link: function(scope, element, attrs, fn) {

                //Apply position:relative to parent element if necessary
                var position = element.css('position');
                if (position === 'static' || position === '' || typeof position === 'undefined'){
                    element.css('position','relative');
                }

                var templateElement;
                var backdropElement;
                var currentTemplate;
                var templateScope;
                var backdrop;
                var tracker = _cgBusyTrackerFactory();

                var defaults = {
                    templateUrl: 'angular-busy.html',
                    delay:0,
                    minDuration:0,
                    backdrop: true,
                    message:'Please Wait...'
                };

                angular.extend(defaults,cgBusyDefaults);

                scope.$watchCollection(attrs.cgBusy,function(options){

                    if (!options) {
                        options = {promise:null};
                    }

                    if (angular.isString(options)) {
                        throw new Error('Invalid value for cg-busy. cgBusy no longer accepts string ids to represent promises/trackers.');
                    }

                    //is it an array (of promises) or one promise
                    if (angular.isArray(options) || tracker.isPromise(options)) {
                        options = {promise:options};
                    }

                    options = angular.extend(angular.copy(defaults),options);

                    if (!options.templateUrl){
                        options.templateUrl = defaults.templateUrl;
                    }

                    if (!angular.isArray(options.promise)){
                        options.promise = [options.promise];
                    }

                    // options.promise = angular.isArray(options.promise) ? options.promise : [options.promise];
                    // options.message = options.message ? options.message : 'Please Wait...';
                    // options.template = options.template ? options.template : cgBusyTemplateName;
                    // options.minDuration = options.minDuration ? options.minDuration : 0;
                    // options.delay = options.delay ? options.delay : 0;

                    if (!templateScope) {
                        templateScope = scope.$new();
                    }

                    templateScope.$message = options.message;

                    if (!angular.equals(tracker.promises,options.promise)) {
                        tracker.reset({
                            promises:options.promise,
                            delay:options.delay,
                            minDuration: options.minDuration
                        });
                    }

                    templateScope.$cgBusyIsActive = function() {
                        return tracker.active();
                    };

                    if (!templateElement || currentTemplate !== options.templateUrl || backdrop !== options.backdrop) {

                        if (templateElement) {
                            templateElement.remove();
                        }
                        if (backdropElement){
                            backdropElement.remove();
                        }

                        currentTemplate = options.templateUrl;
                        backdrop = options.backdrop;

                        $http.get(currentTemplate,{cache: $templateCache}).success(function(indicatorTemplate){

                            options.backdrop = typeof options.backdrop === 'undefined' ? true : options.backdrop;

                            if (options.backdrop){
                                var backdrop = '

';
                                backdropElement = $compile(backdrop)(templateScope);
                                element.append(backdropElement);
                            }

                            var template = '
' + indicatorTemplate + '
';
                            templateElement = $compile(template)(templateScope);

                            angular.element(templateElement.children()[0])
                                .css('position','absolute')
                                .css('top',0)
                                .css('left',0)
                                .css('right',0)
                                .css('bottom',0);
                            element.append(templateElement);

                        }).error(function(data){
                            throw new Error('Template specified for cgBusy ('+options.templateUrl+') could not be loaded. ' + data);
                        });
                    }

                },true);
            }
        };
    }
]);

<commit_msg>Fix typo $them -> $then<commit_after>angular.module('cgBusy',[]);

//loosely modeled after angular-promise-tracker
angular.module('cgBusy').factory('_cgBusyTrackerFactory',['$timeout','$q',function($timeout,$q){

    return function(){

        var tracker = {};
        tracker.promises = [];
        tracker.delayPromise = null;
        tracker.durationPromise = null;
        tracker.delayJustFinished = false;

        tracker.reset = function(options){
            tracker.minDuration = options.minDuration;

            tracker.promises = [];
            angular.forEach(options.promises,function(p){
                if (!p || p.$cgBusyFulfilled) {
                    return;
                }
                addPromiseLikeThing(p);
            });

            if (tracker.promises.length === 0) {
                //if we have no promises then dont do the delay or duration stuff
                return;
            }

            tracker.delayJustFinished = false;
            if (options.delay) {
                tracker.delayPromise = $timeout(function(){
                    tracker.delayPromise = null;
                    tracker.delayJustFinished = true;
                },parseInt(options.delay,10));
            }
            if (options.minDuration) {
                tracker.durationPromise = $timeout(function(){
                    tracker.durationPromise = null;
                },parseInt(options.minDuration,10) + (options.delay ? parseInt(options.delay,10) : 0));
            }
        };

        tracker.isPromise = function(promiseThing){
            var then = promiseThing && (promiseThing.then || promiseThing.$then ||
                (promiseThing.$promiseThing && promiseThing.$promiseThing.then));

            return typeof then !== 'undefined';
        };

        tracker.callThen = function(promiseThing,success,error){
            var promise;
            if (promiseThing.then || promiseThing.$then){
                promise = promiseThing;
            } else if (promiseThing.$promise){
                promise = promiseThing.$promise;
            } else if (promiseThing.denodeify){
                promise = $q.when(promiseThing);
            }

            var then = (promise.then || promise.$then);

            then.call(promise,success,error);
        };

        var addPromiseLikeThing = function(promise){

            if (!tracker.isPromise(promise)) {
                throw new Error('cgBusy expects a promise (or something that has a .promise or .$promise');
            }

            if (tracker.promises.indexOf(promise) !== -1){
                return;
            }
            tracker.promises.push(promise);

            tracker.callThen(promise, function(){
                promise.$cgBusyFulfilled = true;
                if (tracker.promises.indexOf(promise) === -1) {
                    return;
                }
                tracker.promises.splice(tracker.promises.indexOf(promise),1);
            },function(){
                promise.$cgBusyFulfilled = true;
                if (tracker.promises.indexOf(promise) === -1) {
                    return;
                }
                tracker.promises.splice(tracker.promises.indexOf(promise),1);
            });
        };

        tracker.active = function(){
            if (tracker.delayPromise){
                return false;
            }

            if (!tracker.delayJustFinished){
                if (tracker.durationPromise){
                    return true;
                }
                return tracker.promises.length > 0;
            } else {
                //if both delay and min duration are set,
                //we don't want to initiate the min duration if the
                //promise finished before the delay was complete
                tracker.delayJustFinished = false;
                return tracker.promises.length > 0;
            }
        };

        return tracker;

    };
}]);

angular.module('cgBusy').value('cgBusyDefaults',{});

angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusyDefaults','$http','_cgBusyTrackerFactory',
    function($compile,$templateCache,cgBusyDefaults,$http,_cgBusyTrackerFactory){
        return {
            restrict: 'A',
            link: function(scope, element, attrs, fn) {

                //Apply position:relative to parent element if necessary
                var position = element.css('position');
                if (position === 'static' || position === '' || typeof position === 'undefined'){
                    element.css('position','relative');
                }

                var templateElement;
                var backdropElement;
                var currentTemplate;
                var templateScope;
                var backdrop;
                var tracker = _cgBusyTrackerFactory();

                var defaults = {
                    templateUrl: 'angular-busy.html',
                    delay:0,
                    minDuration:0,
                    backdrop: true,
                    message:'Please Wait...'
                };

                angular.extend(defaults,cgBusyDefaults);

                scope.$watchCollection(attrs.cgBusy,function(options){

                    if (!options) {
                        options = {promise:null};
                    }

                    if (angular.isString(options)) {
                        throw new Error('Invalid value for cg-busy. cgBusy no longer accepts string ids to represent promises/trackers.');
                    }

                    //is it an array (of promises) or one promise
                    if (angular.isArray(options) || tracker.isPromise(options)) {
                        options = {promise:options};
                    }

                    options = angular.extend(angular.copy(defaults),options);

                    if (!options.templateUrl){
                        options.templateUrl = defaults.templateUrl;
                    }

                    if (!angular.isArray(options.promise)){
                        options.promise = [options.promise];
                    }

                    // options.promise = angular.isArray(options.promise) ? options.promise : [options.promise];
                    // options.message = options.message ? options.message : 'Please Wait...';
                    // options.template = options.template ? options.template : cgBusyTemplateName;
                    // options.minDuration = options.minDuration ? options.minDuration : 0;
                    // options.delay = options.delay ? options.delay : 0;

                    if (!templateScope) {
                        templateScope = scope.$new();
                    }

                    templateScope.$message = options.message;

                    if (!angular.equals(tracker.promises,options.promise)) {
                        tracker.reset({
                            promises:options.promise,
                            delay:options.delay,
                            minDuration: options.minDuration
                        });
                    }

                    templateScope.$cgBusyIsActive = function() {
                        return tracker.active();
                    };

                    if (!templateElement || currentTemplate !== options.templateUrl || backdrop !== options.backdrop) {

                        if (templateElement) {
                            templateElement.remove();
                        }
                        if (backdropElement){
                            backdropElement.remove();
                        }

                        currentTemplate = options.templateUrl;
                        backdrop = options.backdrop;

                        $http.get(currentTemplate,{cache: $templateCache}).success(function(indicatorTemplate){

                            options.backdrop = typeof options.backdrop === 'undefined' ? true : options.backdrop;

                            if (options.backdrop){
                                var backdrop = '

';
                                backdropElement = $compile(backdrop)(templateScope);
                                element.append(backdropElement);
                            }

                            var template = '
' + indicatorTemplate + '
';
                            templateElement = $compile(template)(templateScope);

                            angular.element(templateElement.children()[0])
                                .css('position','absolute')
                                .css('top',0)
                                .css('left',0)
                                .css('right',0)
                                .css('bottom',0);
                            element.append(templateElement);

                        }).error(function(data){
                            throw new Error('Template specified for cgBusy ('+options.templateUrl+') could not be loaded. ' + data);
                        });
                    }

                },true);
            }
        };
    }
]);

<|endoftext|>


<commit_before>(function () {
'use strict';

angular.module('alAngularHero', ['ngAnimate'])
    .animation('.hero-transition', [function () {

        var _fromScreen, _toScreen, _doneList, _startTimer, _movingList;

        // Capture the screen that is transitioning in
        var enter = function enter(screen, done) {
            _toScreen = screen;
            _doneList.push(done);
            return tryStart();
        };

        // Capture the screen that is transitioning out
        var leave = function leave(screen, done) {
            _fromScreen = screen;
            _doneList.push(done);

            screen.addClass('hero-leave');
            return tryStart();
        };

        // If we have both screens then trigger the transition
        var tryStart = function tryStart() {
            if (!_fromScreen || !_toScreen) {
                // Allow time to get a second screen, or else cancel
                _startTimer = setTimeout(function () { finish(true); });
                return null;
            } else {
                if (_startTimer) clearTimeout(_startTimer);

                // Both screens, so start now
                setTimeout(start);

                // Return a cancel function, which should only call clear once
                var cancelled = false;
                return function () {
                    if (!cancelled) {
                        cancelled = true;
                        clear();
                    }
                };
            }
        };

        // Start the hero transitions
        var start = function start() {
            // Get hero elements from both screens
            var fromHeros = _fromScreen[0].getElementsByClassName("hero");
            var toHeros = _toScreen[0].getElementsByClassName("hero");

            // Find all the matching pairs
            var pairs = [];
            for (var n = 0; n < fromHeros.length; n++) {
                for (var m = 0; m < toHeros.length; m++) {
                    if (fromHeros[n].getAttribute('hero-id') === toHeros[m].getAttribute('hero-id')) {
                        pairs.push({ from: fromHeros[n], to: toHeros[m] });
                    }
                }
            }

            // Trigger the animation for each pair
            pairs.forEach(function (pair) {
                animateHero(angular.element(pair.from), angular.element(pair.to));
            });

            finish();
        };

        // Animate a hero element from one position to another
        var animateHero = function animateHero(fromHero, toHero) {
            // Get the screen positions
            var fromRect = getScreenRect(fromHero, _fromScreen);

            // Clone and hide the source and target elements
            var moving = fromHero.clone();
            fromHero.css('visibility', 'hidden');
            toHero.css('visibility', 'hidden');

            // Move outside the screen element and apply animation css
            _fromScreen.parent().append(moving);
            moving.css({
                top: fromRect.top + 'px',
                left: fromRect.left + 'px',
                width: fromRect.width + 'px',
                height: fromRect.height + 'px',
                margin: '0'
            }).addClass('hero-animating');

            // Setup the event handler for the end of the transition
            var handler = {
                complete: false,
                onComplete: function () {
                    // Allows us to track which animations have finished
                    handler.complete = true;
                    finish();
                },
                remove: function () {
                    // Show the original target element
                    toHero.css('visibility', '');

                    // Unbind the event handler and remove the element
                    moving.unbind('transitionend', handler.onComplete);
                    moving.remove();
                }
            };
            _movingList.push(handler);

            // Delay here allows the DOM to update before starting
            setTimeout(function () {
                var toRect = getScreenRect(toHero, _toScreen);
                // Move to the new position (animated by css transition)
                var transform = 'translate3d(' + (toRect.left - fromRect.left) + 'px, '
                        + (toRect.top - fromRect.top) + 'px, 0)';
                moving.css({
                    '-webkit-transform': transform,
                    transform: transform,
                    width: toRect.width + 'px',
                    height: toRect.height + 'px'
                }).addClass('hero-animating-active');

                // Switch the animating element to the target's classes,
                // which allows us to animate other properties like color,
                // border, corners, etc.
                moving.attr('class', toHero.attr('class') + ' hero-animating');

                // Handle the event at the end of transition
                moving.bind('transitionend', handler.onComplete);
            }, 50);
        };

        // Get the current screen position and size of an element
        var getScreenRect = function getScreenRect(element, screen) {
            var elementRect = element[0].getBoundingClientRect();
            var screenRect = screen[0].getBoundingClientRect();

            return {
                top: elementRect.top - screenRect.top,
                left: elementRect.left - screenRect.left,
                width: elementRect.width,
                height: elementRect.height
            };
        };

        // Finish up if all elements have finished animating
        var finish = function finish(cancelled) {
            // Check that all the moving elements are complete
            var allComplete = true;
            if (!cancelled) {
                _movingList.forEach(function (m) { allComplete = allComplete && m.complete; });
            }

            if (allComplete) {
                // Call "done" on both screens (which may call "clear" so clone the array)
                var doneCallbacks = _doneList.slice(0);
                doneCallbacks.forEach(function (done) { done(); });
                // Make sure we've cleared for the next time
                clear();
            }
        };

        // Clear everything down and initialise for next time
        var clear = function clear() {
            _fromScreen = null;
            _toScreen = null;
            _doneList = [];

            // Call remove for each animating hero element
            if (_movingList) _movingList.forEach(function (m) { m.remove(); });
            _movingList = [];
        };
        clear();

        // Definition of the AngularJS animation
        return {
            enter: function (element, done) {
                return enter(element, done);
            },
            leave: function (element, done) {
                return leave(element, done);
            }
        };
    }]);
})();
<commit_msg>Fix: page transition animation is not working when using version 1.4<commit_after>(function () {
    'use strict';
    function alAngularHero($animateCss) {
        var _fromScreen, _toScreen, _doneList, _startTimer, _movingList;

        // Capture the screen that is transitioning in
        var enter = function enter(screen, done) {
            _toScreen = screen;
            _doneList.push(done);
            return tryStart();
        };

        // Capture the screen that is transitioning out
        var leave = function leave(screen, done) {
            _fromScreen = screen;
            _doneList.push(done);

            screen.addClass('hero-leave');
            return tryStart();
        };

        // If we have both screens then trigger the transition
        var tryStart = function tryStart() {
            if (!_fromScreen || !_toScreen) {
                // Allow time to get a second screen, or else cancel
                _startTimer = setTimeout(function () {
                    finish(true);
                });
                return null;
            } else {
                if (_startTimer) clearTimeout(_startTimer);

                // Both screens, so start now
                setTimeout(start);

                // Return a cancel function, which should only call clear once
                var cancelled = false;
                return function () {
                    if (!cancelled) {
                        cancelled = true;
                        clear();
                    }
                };
            }
        };

        // Start the hero transitions
        var start = function start() {
            // Get hero elements from both screens
            var fromHeros = _fromScreen[0].getElementsByClassName("hero");
            var toHeros = _toScreen[0].getElementsByClassName("hero");

            // Find all the matching pairs
            var pairs = [];
            for (var n = 0; n < fromHeros.length; n++) {
                for (var m = 0; m < toHeros.length; m++) {
                    if (fromHeros[n].getAttribute('hero-id') === toHeros[m].getAttribute('hero-id')) {
                        pairs.push({
                            from: fromHeros[n],
                            to: toHeros[m]
                        });
                    }
                }
            }

            // Trigger the animation for each pair
            pairs.forEach(function (pair) {
                animateHero(angular.element(pair.from), angular.element(pair.to));
            });

            finish();
        };

        // Animate a hero element from one position to another
        var animateHero = function animateHero(fromHero, toHero) {
            // Get the screen positions
            var fromRect = getScreenRect(fromHero, _fromScreen);

            // Clone and hide the source and target elements
            var moving = fromHero.clone();
            fromHero.css('visibility', 'hidden');
            toHero.css('visibility', 'hidden');

            // Move outside the screen element and apply animation css
            _fromScreen.parent().append(moving);
            moving.css({
                top: fromRect.top + 'px',
                left: fromRect.left + 'px',
                width: fromRect.width + 'px',
                height: fromRect.height + 'px',
                margin: '0'
            }).addClass('hero-animating');

            // Setup the event handler for the end of the transition
            var handler = {
                complete: false,
                onComplete: function () {
                    // Allows us to track which animations have finished
                    handler.complete = true;
                    finish();
                },
                remove: function () {
                    // Show the original target element
                    toHero.css('visibility', '');

                    // Unbind the event handler and remove the element
                    moving.unbind('transitionend', handler.onComplete);
                    moving.remove();
                }
            };
            _movingList.push(handler);

            // Delay here allows the DOM to update before starting
            setTimeout(function () {
                var toRect = getScreenRect(toHero, _toScreen);
                // Move to the new position (animated by css transition)
                var transform = 'translate3d(' + (toRect.left - fromRect.left) + 'px, '
                    + (toRect.top - fromRect.top) + 'px, 0)';
                moving.css({
                    '-webkit-transform': transform,
                    transform: transform,
                    width: toRect.width + 'px',
                    height: toRect.height + 'px'
                }).addClass('hero-animating-active');

                // Switch the animating element to the target's classes,
                // which allows us to animate other properties like color,
                // border, corners, etc.
                moving.attr('class', toHero.attr('class') + ' hero-animating');

                // Handle the event at the end of transition
                moving.bind('transitionend', handler.onComplete);
            }, 50);
        };

        // Get the current screen position and size of an element
        var getScreenRect = function getScreenRect(element, screen) {
            var elementRect = element[0].getBoundingClientRect();
            var screenRect = screen[0].getBoundingClientRect();

            return {
                top: elementRect.top - screenRect.top,
                left: elementRect.left - screenRect.left,
                width: elementRect.width,
                height: elementRect.height
            };
        };

        // Finish up if all elements have finished animating
        var finish = function finish(cancelled) {
            // Check that all the moving elements are complete
            var allComplete = true;
            if (!cancelled) {
                _movingList.forEach(function (m) {
                    allComplete = allComplete && m.complete;
                });
            }

            if (allComplete) {
                // Call "done" on both screens (which may call "clear" so clone the array)
                var doneCallbacks = _doneList.slice(0);
                doneCallbacks.forEach(function (done) {
                    done();
                });
                // Make sure we've cleared for the next time
                clear();
            }
        };

        // Clear everything down and initialise for next time
        var clear = function clear() {
            _fromScreen = null;
            _toScreen = null;
            _doneList = [];

            // Call remove for each animating hero element
            if (_movingList) _movingList.forEach(function (m) {
                m.remove();
            });
            _movingList = [];
        };
        clear();

        // Definition of the AngularJS animation
        return {
            enter: function (element, done) {
                if ($animateCss) {
                    var runner = $animateCss(element, {
                        event: 'enter',
                        structural: true
                    }).start();
                    return enter(element, function () {
                        runner.done(done);
                    });
                } else {
                    return enter(element, done);
                }
            },

            leave: function (element, done) {
                if ($animateCss) {
                    var runner = $animateCss(element, {
                        event: 'leave',
                        structural: true
                    }).start();
                    return leave(element, function () {
                        runner.done(done);
                    });
                } else {
                    return leave(element, done);
                }
            }
        };
    }
    alAngularHero.$inject = [];
    var over14 = (angular.version.major >= 1 && angular.version.minor >= 4);
    if (over14) {
        alAngularHero.$inject.push('$animateCss');
    }
    angular.module('alAngularHero', ['ngAnimate'])
        .animation('.hero-transition', alAngularHero);
})();
<|endoftext|>


<commit_before>/**
 * # Requirements settings
 * Copyright(c) {YEAR} {AUTHOR} <{AUTHOR_EMAIL}>
 * MIT Licensed
 *
 * Requirements settings file.
 *
 * Add custom tests in requirements.js
 *
 * http://nodegame.org
 * ---
 */

module.exports = {

    /**
     * ## enabled
     *
     * If TRUE, it creates a requirements room. Default, TRUE
     */
    enabled: true,

    /**
     * ## maxExecTime
     *
     * If set, limits the maximum execution time for all requirement tests
     */
    maxExecTime: 6000,

    /**
     * ## speedTest
     *
     * If set, client must exchange messages with server "quickly enough"
     */
    speedTest: {
        messages: 1,
        time: 1000
    },

    /**
     * ## viewportSize
     *
     * If set, client must have a resolution between the min and max specified
     */
//     viewportSize: {
//         minX: 1366,
//         minY: 768,
//         // maxX: 13660,
//         // maxY: 7680
//     },

   /**
     * ## browserDetect
     *
     * Checks the browser and device
     *
     * Available options (more will be added):
     *
     *  - parser: (optional) a function that will parse the userAgent.
     *            Default function is `ua-parser-js`
     *  - cb: a callback that takes an object containing the parsed userAgent
     *        and must return an object of the type:
     *        { success: true/false, errors: undefined|array of strings }
     *
     * @see https://github.com/faisalman/ua-parser-js
     */
//     browserDetect: {
//         cb: function(ua, params) {
//             if (ua.device.model || ua.device.type) {
//                 return {
//                     success: false,
//                     errors: [ 'It seems you are using a mobile or tablet ' +
//                               'device. You can participate to this game ' +
//                               'only from a desktop or laptop computer ' +
//                               'with a keyboard and a mouse. If you ' +
//                               'can, try with another browser or device.' ]
//                 };
//             }
//
//             return { success: true };
//         }
//     },

    /**
     * ## cookieSupport
     *
     * If set, client must support setting cookies.
     *
     * Accepted values:
     *
     *   - 'persistent': cookies must persist across session
     *   - 'session': cookies must be set within same session
     */
    cookieSupport: 'persistent'

    /**
     * ## nextRoom
     *
     * If set, clients that pass the requirements are moved to this room.
     *
     * Default: the waiting room
     */
    // nextRoom: 'mynextroom',

    /**
     * ## doChecking
     *
     * If TRUE, start testing the requirements immediately. Default, TRUE
     */
    // doChecking: true,

    /**
     * ## logicPath
     *
     * Alternative path for a custom requirements room.
     */
    // logicPath: './requirements.room.js',

    // # Reserved words for future requirements settings.

    //  mode: 'auto',
    //
    //  page: 'requirements.htm'
};
<commit_msg>E6Support in requirement settings<commit_after>/**
 * # Requirements settings
 * Copyright(c) {YEAR} {AUTHOR} <{AUTHOR_EMAIL}>
 * MIT Licensed
 *
 * Requirements settings file.
 *
 * Add custom tests in requirements.js
 *
 * http://nodegame.org
 * ---
 */

module.exports = {

    /**
     * ## enabled
     *
     * If TRUE, it creates a requirements room. Default, TRUE
     */
    enabled: true,

    /**
     * ## maxExecTime
     *
     * If set, limits the maximum execution time for all requirement tests
     */
    maxExecTime: 6000,

    /**
     * ## speedTest
     *
     * If set, client must exchange messages with server "quickly enough"
     */
    speedTest: {
        messages: 1,
        time: 1000
    },

    /**
     * ## viewportSize
     *
     * If set, client must have a resolution between the min and max specified
     */
//     viewportSize: {
//         minX: 1366,
//         minY: 768,
//         // maxX: 13660,
//         // maxY: 7680
//     },

   /**
     * ## browserDetect
     *
     * Checks the browser and device
     *
     * Available options (more will be added):
     *
     *  - parser: (optional) a function that will parse the userAgent.
     *            Default function is `ua-parser-js`
     *  - cb: a callback that takes an object containing the parsed userAgent
     *        and must return an object of the type:
     *        { success: true/false, errors: undefined|array of strings }
     *
     * @see https://github.com/faisalman/ua-parser-js
     */
//     browserDetect: {
//         cb: function(ua, params) {
//             if (ua.device.model || ua.device.type) {
//                 return {
//                     success: false,
//                     errors: [ 'It seems you are using a mobile or tablet ' +
//                               'device. You can participate to this game ' +
//                               'only from a desktop or laptop computer ' +
//                               'with a keyboard and a mouse. If you ' +
//                               'can, try with another browser or device.' ]
//                 };
//             }
//
//             return { success: true };
//         }
//     },

    /**
     * ## cookieSupport
     *
     * If set, client must support setting cookies.
     *
     * Accepted values:
     *
     *   - 'persistent': cookies must persist across session
     *   - 'session': cookies must be set within same session
     */
    cookieSupport: 'persistent',

    /**
     * ## ES6Support
     *
     * If TRUE, browser must support JS ES6 standard.
     *
     * Default: FALSE
     */
    // ES6Support: true

    /**
     * ## nextRoom
     *
     * If set, clients that pass the requirements are moved to this room.
     *
     * Default: the waiting room
     */
    // nextRoom: 'mynextroom',

    /**
     * ## doChecking
     *
     * If TRUE, start testing the requirements immediately. Default, TRUE
     */
    // doChecking: true,

    /**
     * ## logicPath
     *
     * Alternative path for a custom requirements room.
     */
    // logicPath: './requirements.room.js',

    // # Reserved words for future requirements settings.

    //  mode: 'auto',
    //
    //  page: 'requirements.htm'
};
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { connect } from 'stripes-connect';
import PatronForm from './PatronForm';

// One of multiple stripes-connected components in the patrons module
export default class PatronAdd extends Component {
  static contextTypes = {
    router: PropTypes.object.isRequired
  };

  // The manifest is provided in components by the module developer and consumed by 'stripes connect'
  static manifest = { 'apis/patrons': { type: 'okapi',
                                        pk: '_id',  // The primary key of records from this end-point
                                                    // Set this if not using the default, "id".
                                        clientGeneratePk: false // Set this if the backend service requires
                                                                // that it generates unique IDs for records
                                      }};

  createPatron(data) {
    this.props.mutator['apis/patrons'].create(data);
    this.context.router.push('/patrons/list');
  }

  cancel(data) {
    this.context.router.push('/patrons/list');
  }

  render() {
      return <PatronForm onSubmit={this.createPatron.bind(this)}
                         cancelForm={this.cancel.bind(this)}
                         action={PatronForm.actionTypes['create']}/>
  }
}

// This function call might be implicit in a future version (invoked by the framework)
export default connect(PatronAdd, 'patrons');
<commit_msg>Specifies element holding records<commit_after>import React, { Component, PropTypes } from 'react';
import { connect } from 'stripes-connect';
import PatronForm from './PatronForm';

// One of multiple stripes-connected components in the patrons module
export default class PatronAdd extends Component {
  static contextTypes = {
    router: PropTypes.object.isRequired
  };

  // The manifest is provided in components by the module developer and consumed by 'stripes connect'
  static manifest = { 'apis/patrons': { type: 'okapi',
                                        pk: '_id',  // The primary key of records from this end-point
                                                    // Set this if not using the default, "id".
                                        clientGeneratePk: false, // Set this if the backend service requires
                                                                 // that it generates unique IDs for records
                                        records: 'patrons' // The name of the property in the JSON response
                                                           // that holds the records
                                      }};

  createPatron(data) {
    this.props.mutator['apis/patrons'].create(data);
    this.context.router.push('/patrons/list');
  }

  cancel(data) {
    this.context.router.push('/patrons/list');
  }

  render() {
      return <PatronForm onSubmit={this.createPatron.bind(this)}
                         cancelForm={this.cancel.bind(this)}
                         action={PatronForm.actionTypes['create']}/>
  }
}

// This function call might be implicit in a future version (invoked by the framework)
export default connect(PatronAdd, 'patrons');
<|endoftext|>