<commit_before>/*
Expollapser version 0.11.0
*/

(function ($) {

	// Defaults
	var expollapser_defaults = {
		'toggler': 'header',
		'bodyElement': 'next',
		'expandHeaderCss': null,
		'expandBodyCss': null,
		'collapseHeaderCss': null,
		'collapseBodyCss': null,
		'headerReplaceHtml': '',
		'open': false,
		'contentHtml': '',
		'expandAnimator': function (header, body, toggler, callback) { $(body).slideDown(200, callback); },
		'collapseAnimator': function (header, body, toggler, callback) { $(body).slideUp(200, callback); },
		'togglerSeparation': false
	};

	function expollapser_setDefaults(options) {
		if (options) {
			$.extend(expollapser_defaults, options);
		}
	}

	// Define methods of the expollapser plugin
	var methods = {

		// init : Sets up the plugin on the matched element(s)
		init: function (options) {
			return this.each(function () {
				var $this = $(this);
				var data = $this.data('expollapser');

				// If the plugin hasn't been initialized yet
				if (!data) {
					var settings = $.extend({}, expollapser_defaults); // Clone, shallow copy

					// Merge user options
					if (options) {
						$.extend(settings, options);
					}

					// Process the settings, basically by converting all convenience string settings
					// to underlying functions.
					var getBodyFn = processBodyElement(settings.bodyElement);
					var getTogglersFn = resolveTogglers(settings.toggler, $(this));
					var replaceHeaderHtmlFn = processHeaderReplaceHtml(settings.headerReplaceHtml);
					settings.contentHtml = processContentHtml(settings.contentHtml, settings);

					$(this).bind('preExpand', function (e, context) {
						ensureClass(context.header, settings.expandHeaderCss);
						ensureClassRemoved(context.header, settings.collapseHeaderCss);
						ensureClass(context.body, settings.expandBodyCss);
						ensureClassRemoved(context.body, settings.collapseBodyCss);
					});

					$(this).bind('postExpand', function (e, context) {
						replaceHeaderHtmlFn(context.header);
					});

					$(this).bind('postCollapse', function (e, context) {
						ensureClassRemoved(context.header, settings.expandHeaderCss);
						ensureClass(context.header, settings.collapseHeaderCss);
						ensureClassRemoved(context.body, settings.expandBodyCss);
						ensureClass(context.body, settings.collapseBodyCss);
						replaceHeaderHtmlFn(context.header);
					});

					// Setup data
					$(this).data('expollapser', {
						isopen: settings.open,
						getTogglers: getTogglersFn,
						getBody: getBodyFn,
						contentLoaded: false,
						disabled: false,
						settings: settings
					});

					if (settings.open == true) {
						ensureClass($(this), settings.expandHeaderCss);
						ensureClass(getBodyFn($(this)), settings.expandBodyCss);
						replaceHeaderHtmlFn($(this));
						getBodyFn($(this)).show();
					}
					else {
						ensureClass($(this), settings.collapseHeaderCss);
						ensureClass(getBodyFn($(this)), settings.collapseBodyCss);
						replaceHeaderHtmlFn($(this));
						getBodyFn($(this)).hide();
					}

					// Setup togglers
					ensureToggleHookup($(this).data('expollapser').getTogglers, $(this));
				}
			});
		},

		// disable: Disables expand/collapse functionality
		disable: function () {
			return this.each(function () {
				$(this).data('expollapser').disabled = true;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'auto');
			})
		},

		// enable: Enables expand/collapse functionality
		enable: function () {
			return this.each(function () {
				$(this).data('expollapser').disabled = false;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'hand');
			})
		},

		// toggle: Toggles between expanded and collapsed state
		toggle: function (toggler) {
			return this.each(function () {
				var data = $(this).data('expollapser');

				// Handle special case with multiple togglers producing multiple contents
				if (data.isopen == true && data.settings.togglerSeparation && data.expandedBy.get(0) != toggler.get(0)) {
					var $this = $(this);
					$(this).expollapser('collapse', data.expandedBy, function () { $this.expollapser('expand', toggler) });
				}
				else { // Default toggle
					if (data.isopen == false)
						$(this).expollapser('expand', toggler);
					else {
						$(this).expollapser('collapse', toggler);
					}
				}
			});
		},

		// expand: Expands the matched element(s)
		expand: function (toggler) {
			return this.each(function () {
				var $this = $(this);
				var data = $(this).data('expollapser');
				var settings = data.settings;
				if (data.isopen == false && data.disabled == false) {
					if (toggler == null)
						toggler = $(data.getTogglers($this).get(0));
					var bodyElement = data.getBody($(this));
					$(this).trigger('preExpand', { header: $this, body: bodyElement, toggler: toggler });

					// Set content and do expand animation
					data.expandedBy = toggler;
					data.isopen = true;
					settings.contentHtml($(this), bodyElement, toggler, function () { });
					settings.expandAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postExpand', { header: $this, body: bodyElement, toggler: toggler });
					});
				}
			});
		},

		collapse: function (toggler, callback) {
			return this.each(function () {
				var $this = $(this);
				var data = $(this).data('expollapser');
				var settings = $(this).data('expollapser').settings;
				if (data.isopen == true && data.disabled == false) {
					if (toggler == null)
						toggler = data.expandedBy;
					if (toggler == null)
						toggler = $this;
					var bodyElement = data.getBody($(this));
					$(this).trigger('preCollapse', { header: $this, body: bodyElement, toggler: toggler });

					data.isopen = false;
					settings.collapseAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postCollapse', { header: $this, body: bodyElement, toggler: toggler });
						if (callback)
							callback();
					});
				}
			});
		}
	};

	// Ensures that the supplied togglers function on the supplied header element is setup with click events
	function ensureToggleHookup(togglersFn, headerElement) {
		togglersFn(headerElement).each(function () {
			// Set up click events of togglersFn if they have no click event already
			if (!$.data(this, 'events') || !$.data(this, 'events')['click'] || $.data(this, 'events')['click'].length == 0) {
				$(this).css('cursor', 'hand');
				$(this).bind('click.expollapser', function () {
					headerElement.expollapser('toggle', $(this));
					return false;
				});
			}
		});
	}

	function assertStringOrFunction(subject, name, allowNull) {
		if ((!subject && allowNull) || typeof subject === 'string' || $.isFunction(subject))
			return;

		alert('Expollapser options error: ' + name + ' should be either a string or a function.');
	}

	function ensureClass(jq, cssClass) {
		if (cssClass && !jq.hasClass(cssClass))
			jq.addClass(cssClass);
	};

	function ensureClassRemoved(jq, cssClass) {
		if (cssClass)
			jq.removeClass(cssClass);
	};

	// Parses bodyElement setting and returns a function to get the content element
	function processBodyElement(contentSetting) {
		assertStringOrFunction(contentSetting, 'bodyElement');
		if (typeof contentSetting === 'string') {
			if (contentSetting == 'next')
				return function (headerElement) { return headerElement.next(); };
			else if (contentSetting == 'prev')
				return function (headerElement) { return headerElement.prev(); };
			else
				return function () { return $(contentSetting); };
		}

		return contentSetting;
	}

	// Parse for convenience settings in togglers
	function resolveTogglers(togglersSetting, $header) {
		assertStringOrFunction(togglersSetting, 'togglers');
		var togglersFunction;
		if (typeof togglersSetting === 'string') {
			if (togglersSetting == 'header') {
				return function () { return $header; };
			}
			else if (togglersSetting == 'headerLinks') {
				return function () { return $('a', $header); };
			}
			else {
				var stringSetting = togglersSetting;
				return function () { return $(stringSetting, $header); };
			}
		}

		return togglersSetting;
	}

	function processHeaderReplaceHtml(setting) {
		assertStringOrFunction(setting, 'headerReplaceHtml');
		if (typeof setting === 'string') {
			var html = setting;
			if (html.indexOf('<-->') > -1) {
				var replaceExpressions = html.split(',');
				return function (header) {
					for (var item in replaceExpressions) {
						var pair = replaceExpressions[item].split('<-->');
						if (header.data('expollapser') && header.data('expollapser').isopen == true) {
							header.html(header.html().replace(pair[0], pair[1]));
						}
						else {
							header.html(header.html().replace(pair[1], pair[0]));
						}
					}
				};
			}

			return function () { };
		}

		return setting;
	}

	// TODO: getUniqueId check om loaded content.
	function processContentHtml(setting, settings) {
		assertStringOrFunction(setting, 'contentHtml', false);
		var processedSetting;
		if (typeof setting === 'string') {
			var stringSetting = setting;
			if (setting == 'togglerHref')
				stringSetting = 'togglerAttr:href';
			if (stringSetting.beginsWith('togglerAttr:')) {
				processedSetting = function (header, content, toggler, callback) {
					$.get(toggler.attr(stringSetting.substring(12)), function (response) {
						content.html(response);
						callback();
					});
				};
				settings.togglerSeparation = true;
			}
			else if (setting.beginsWith('url:'))
				processedSetting = function (header, content, toggler, callback) {
					$.get(stringSetting.substring(4), function (response) {
						content.html(response);
						callback();
					});
				};
			else if (setting.length > 0)
				processedSetting = function (header, content, toggler, callback) {
					content.html(stringSetting);
					callback();
				};
			else
				processedSetting = function (header, content, toggler, callback) { callback(); };
		}
		else {
			processedSetting = setting;
		}

		var finalSetting = function (header, content, toggler, callback) {
			var id = getUniqueId(header, content, toggler);
			if (header.data('expollapser').contentLoaded != id) {
				processedSetting(header, content, toggler, function () {
					ensureToggleHookup(header.data('expollapser').getTogglers, header);
					callback();
				});
			}
			else
				callback();
		};

		return finalSetting;
	}

	function getUniqueId(elem1, elem2, elem3) {
		return $(elem1).attr($.expando) + $(elem2).attr($.expando) + $(elem3).attr($.expando);
	}

	// Core plugin registration point
	$.fn.expollapser = function (method) {

		// Method calling logic
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' + method + ' does not exist on jQuery.expollapser');
		}
	};

	// Prototype extensions for common used string functions
	String.prototype.beginsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(0, t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(0, t.length).toLowerCase());
		}
	}

	String.prototype.endsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(this.length - t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(this.length - t.length).toLowerCase());
		}
	}
})(jQuery);

<commit_msg>Initiating work on lazyLoad feature.<commit_after>/*
Expollapser version 0.11.0
*/

(function ($) {

	// Defaults
	var expollapser_defaults = {
		'toggler': 'header',
		'bodyElement': 'next',
		'expandHeaderCss': null,
		'expandBodyCss': null,
		'collapseHeaderCss': null,
		'collapseBodyCss': null,
		'headerReplaceHtml': '',
		'open': false,
		'lazyLoad': 'togglerAttr:href',
		'contentHtml' : '',
		'expandAnimator': function (header, body, toggler, callback) { $(body).slideDown(200, callback); },
		'collapseAnimator': function (header, body, toggler, callback) { $(body).slideUp(200, callback); },
		'togglerSeparation': false
	};

	function expollapser_setDefaults(options) {
		if (options) {
			$.extend(expollapser_defaults, options);
		}
	}

	// Define methods of the expollapser plugin
	var methods = {

		// init : Sets up the plugin on the matched element(s)
		init: function (options) {
			return this.each(function () {
				var $this = $(this);
				var data = $this.data('expollapser');

				// If the plugin hasn't been initialized yet
				if (!data) {
					var settings = $.extend({}, expollapser_defaults); // Clone, shallow copy

					// Merge user options
					if (options) {
						$.extend(settings, options);
					}

					// Process the settings, basically by converting all convenience string settings
					// to underlying functions.
					var getBodyFn = processBodyElement(settings.bodyElement);
					var getTogglersFn = resolveTogglers(settings.toggler, $(this));
					var replaceHeaderHtmlFn = processHeaderReplaceHtml(settings.headerReplaceHtml);
					settings.contentHtml = processContentHtml(settings.contentHtml, settings);

					$(this).bind('preExpand', function (e, context) {
						ensureClass(context.header, settings.expandHeaderCss);
						ensureClassRemoved(context.header, settings.collapseHeaderCss);
						ensureClass(context.body, settings.expandBodyCss);
						ensureClassRemoved(context.body, settings.collapseBodyCss);
					});

					$(this).bind('postExpand', function (e, context) {
						replaceHeaderHtmlFn(context.header);
					});

					$(this).bind('postCollapse', function (e, context) {
						ensureClassRemoved(context.header, settings.expandHeaderCss);
						ensureClass(context.header, settings.collapseHeaderCss);
						ensureClassRemoved(context.body, settings.expandBodyCss);
						ensureClass(context.body, settings.collapseBodyCss);
						replaceHeaderHtmlFn(context.header);
					});

					// Setup data
					$(this).data('expollapser', {
						isopen: settings.open,
						getTogglers: getTogglersFn,
						getBody: getBodyFn,
						contentLoaded: false,
						disabled: false,
						settings: settings
					});

					if (settings.open == true) {
						ensureClass($(this), settings.expandHeaderCss);
						ensureClass(getBodyFn($(this)), settings.expandBodyCss);
						replaceHeaderHtmlFn($(this));
						getBodyFn($(this)).show();
					}
					else {
						ensureClass($(this), settings.collapseHeaderCss);
						ensureClass(getBodyFn($(this)), settings.collapseBodyCss);
						replaceHeaderHtmlFn($(this));
						getBodyFn($(this)).hide();
					}

					// Setup togglers
					ensureToggleHookup($(this).data('expollapser').getTogglers, $(this));
				}
			});
		},

		// disable: Disables expand/collapse functionality
		disable: function () {
			return this.each(function () {
				$(this).data('expollapser').disabled = true;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'auto');
			})
		},

		// enable: Enables expand/collapse functionality
		enable: function () {
			return this.each(function () {
				$(this).data('expollapser').disabled = false;
				$(this).data('expollapser').getTogglers($(this)).css('cursor', 'hand');
			})
		},

		// toggle: Toggles between expanded and collapsed state
		toggle: function (toggler) {
			return this.each(function () {
				var data = $(this).data('expollapser');

				// Handle special case with multiple togglers producing multiple contents
				if (data.isopen == true && data.settings.togglerSeparation && data.expandedBy.get(0) != toggler.get(0)) {
					var $this = $(this);
					$(this).expollapser('collapse', data.expandedBy, function () { $this.expollapser('expand', toggler) });
				}
				else { // Default toggle
					if (data.isopen == false)
						$(this).expollapser('expand', toggler);
					else {
						$(this).expollapser('collapse', toggler);
					}
				}
			});
		},

		// expand: Expands the matched element(s)
		expand: function (toggler) {
			return this.each(function () {
				var $this = $(this);
				var data = $(this).data('expollapser');
				var settings = data.settings;
				if (data.isopen == false && data.disabled == false) {
					if (toggler == null)
						toggler = $(data.getTogglers($this).get(0));
					var bodyElement = data.getBody($(this));
					$(this).trigger('preExpand', { header: $this, body: bodyElement, toggler: toggler });

					// Set content and do expand animation
					data.expandedBy = toggler;
					data.isopen = true;
					settings.contentHtml($(this), bodyElement, toggler, function () { });
					settings.expandAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postExpand', { header: $this, body: bodyElement, toggler: toggler });
					});
				}
			});
		},

		collapse: function (toggler, callback) {
			return this.each(function () {
				var $this = $(this);
				var data = $(this).data('expollapser');
				var settings = $(this).data('expollapser').settings;
				if (data.isopen == true && data.disabled == false) {
					if (toggler == null)
						toggler = data.expandedBy;
					if (toggler == null)
						toggler = $this;
					var bodyElement = data.getBody($(this));
					$(this).trigger('preCollapse', { header: $this, body: bodyElement, toggler: toggler });

					data.isopen = false;
					settings.collapseAnimator($this, bodyElement, toggler, function () {
						$this.trigger('postCollapse', { header: $this, body: bodyElement, toggler: toggler });
						if (callback)
							callback();
					});
				}
			});
		}
	};

	// Ensures that the supplied togglers function on the supplied header element is setup with click events
	function ensureToggleHookup(togglersFn, headerElement) {
		togglersFn(headerElement).each(function () {
			// Set up click events of togglersFn if they have no click event already
			if (!$.data(this, 'events') || !$.data(this, 'events')['click'] || $.data(this, 'events')['click'].length == 0) {
				$(this).css('cursor', 'hand');
				$(this).bind('click.expollapser', function () {
					headerElement.expollapser('toggle', $(this));
					return false;
				});
			}
		});
	}

	function assertStringOrFunction(subject, name, allowNull) {
		if ((!subject && allowNull) || typeof subject === 'string' || $.isFunction(subject))
			return;

		alert('Expollapser options error: ' + name + ' should be either a string or a function.');
	}

	function ensureClass(jq, cssClass) {
		if (cssClass && !jq.hasClass(cssClass))
			jq.addClass(cssClass);
	};

	function ensureClassRemoved(jq, cssClass) {
		if (cssClass)
			jq.removeClass(cssClass);
	};

	// Parses bodyElement setting and returns a function to get the content element
	function processBodyElement(contentSetting) {
		assertStringOrFunction(contentSetting, 'bodyElement');
		if (typeof contentSetting === 'string') {
			if (contentSetting == 'next')
				return function (headerElement) { return headerElement.next(); };
			else if (contentSetting == 'prev')
				return function (headerElement) { return headerElement.prev(); };
			else
				return function () { return $(contentSetting); };
		}

		return contentSetting;
	}

	// Parse for convenience settings in togglers
	function resolveTogglers(togglersSetting, $header) {
		assertStringOrFunction(togglersSetting, 'togglers');
		var togglersFunction;
		if (typeof togglersSetting === 'string') {
			if (togglersSetting == 'header') {
				return function () { return $header; };
			}
			else if (togglersSetting == 'headerLinks') {
				return function () { return $('a', $header); };
			}
			else {
				var stringSetting = togglersSetting;
				return function () { return $(stringSetting, $header); };
			}
		}

		return togglersSetting;
	}

	function processHeaderReplaceHtml(setting) {
		assertStringOrFunction(setting, 'headerReplaceHtml');
		if (typeof setting === 'string') {
			var html = setting;
			if (html.indexOf('<-->') > -1) {
				var replaceExpressions = html.split(',');
				return function (header) {
					for (var item in replaceExpressions) {
						var pair = replaceExpressions[item].split('<-->');
						if (header.data('expollapser') && header.data('expollapser').isopen == true) {
							header.html(header.html().replace(pair[0], pair[1]));
						}
						else {
							header.html(header.html().replace(pair[1], pair[0]));
						}
					}
				};
			}

			return function () { };
		}

		return setting;
	}

	function processLazyLoadSetting(setting, data)
	{
		assertStringOrFunction(setting, 'contentHtml', false);
		if (typeof setting === 'string') {
			if (setting.beginsWith('attr:')) {
				var attr = setting.substring(5);
				return function (header, content, toggler) {
					return header.attr(attr);
				}
			}
		}
	}

	// TODO: getUniqueId check om loaded content.
	// lazyLoad: attr:..., togglerAttr:..., http://..., function
	function processContentHtml(setting, settings) {
		assertStringOrFunction(setting, 'contentHtml', false);
		var processedSetting;
		if (typeof setting === 'string') {
			var stringSetting = setting;
			if (stringSetting.beginsWith('togglerAttr:')) {
				processedSetting = function (header, content, toggler, callback) {
					$.get(toggler.attr(stringSetting.substring(12)), function (response) {
						content.html(response);
						callback();
					});
				};
				settings.togglerSeparation = true;
			}
			else if (setting.beginsWith('url:'))
				processedSetting = function (header, content, toggler, callback) {
					$.get(stringSetting.substring(4), function (response) {
						content.html(response);
						callback();
					});
				};
			else if (setting.length > 0)
				processedSetting = function (header, content, toggler, callback) {
					content.html(stringSetting);
					callback();
				};
			else
				processedSetting = function (header, content, toggler, callback) { callback(); };
		}
		else {
			processedSetting = setting;
		}

		var finalSetting = function (header, content, toggler, callback) {
			var id = getUniqueId(header, content, toggler);
			if (header.data('expollapser').contentLoaded != id) {
				processedSetting(header, content, toggler, function () {
					ensureToggleHookup(header.data('expollapser').getTogglers, header);
					callback();
				});
			}
			else
				callback();
		};

		return finalSetting;
	}

	function getUniqueId(elem1, elem2, elem3) {
		return $(elem1).attr($.expando) + $(elem2).attr($.expando) + $(elem3).attr($.expando);
	}

	// Core plugin registration point
	$.fn.expollapser = function (method) {

		// Method calling logic
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' + method + ' does not exist on jQuery.expollapser');
		}
	};

	// Prototype extensions for common used string functions
	String.prototype.beginsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(0, t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(0, t.length).toLowerCase());
		}
	}

	String.prototype.endsWith = function (t, i) {
		if (i == false) {
			return (t == this.substring(this.length - t.length));
		}
		else {
			return (t.toLowerCase() == this.substring(this.length - t.length).toLowerCase());
		}
	}
})(jQuery);

<|endoftext|>


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

(function(shared) {
  // If the polyfill is being loaded in a context where Element.animate is
  // supported but object-form syntax is not, then creating an animation
  // using the new syntax will either have no effect or will throw an exception.
  // In either case, we want to proceed to load this part of the polyfill.
  //
  // The test animation starts from an opacity other than the one the element
  // already has. The finish opacity is arbitrary. After the test, the element's
  // opacity will be left how we found it:
  // - If the animation is not created, the test will leave the element's
  //   opacity untouched at originalOpacity.
  // - If the animation is created, it will be cancelled, and leave the
  //   element's opacity at originalOpacity.
  // - If the animation is somehow created and runs without being cancelled,
  //   when it finishes after 1ms, it will cease to have any effect (because
  //   fill is not specified), and opacity will again be left at originalOpacity.
  var element = document.documentElement;
  var animation = null;
  var animated = true;
  try {
    var originalOpacity = getComputedStyle(element).getPropertyValue('opacity');
    var startOpacity = originalOpacity == '0' ? '1' : '0';
    var finishOpacity = '1';
    animation = element.animate({'opacity': [startOpacity, finishOpacity]},
        {duration: 1});
    animation.currentTime = 0;
    animated = getComputedStyle(element).getPropertyValue('opacity') == startOpacity;
  } catch (err) {
    animated = false;
  } finally {
    if (animation)
      animation.cancel();
  }
  if (animated) {
    return;
  }

  var originalElementAnimate = window.Element.prototype.animate;
  window.Element.prototype.animate = function(effectInput, options) {
    if (window.Symbol && Symbol.iterator && Array.prototype.from && effectInput[Symbol.iterator]) {
      // Handle custom iterables in most browsers by converting to an array
      effectInput = Array.from(effectInput);
    }

    if (!Array.isArray(effectInput) && effectInput !== null) {
      effectInput = shared.convertToArrayForm(effectInput);
    }

    return originalElementAnimate.call(this, effectInput, options);
  };
})(webAnimationsShared);
<commit_msg>Response to review<commit_after>// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//     You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//     See the License for the specific language governing permissions and
// limitations under the License.

(function(shared) {
  // If the polyfill is being loaded in a context where Element.animate is
  // supported but object-form syntax is not, then creating an animation
  // using the new syntax will either have no effect or will throw an exception.
  // In either case, we want to proceed to load this part of the polyfill.
  //
  // The test animation uses an opacity other than the one the element already
  // has, and doesn't need to change during the animation for the test to work.
  // After the test, the element's opacity will be left how we found it:
  // - If the animation is not created, the test will leave the element's
  //   opacity untouched at originalOpacity.
  // - If the animation is created, it will be cancelled, and leave the
  //   element's opacity at originalOpacity.
  // - If the animation is somehow created and runs without being cancelled,
  //   when it finishes after 1ms, it will cease to have any effect (because
  //   fill is not specified), and opacity will again be left at originalOpacity.
  var element = document.documentElement;
  var animation = null;
  var animated = false;
  try {
    var originalOpacity = getComputedStyle(element).getPropertyValue('opacity');
    var testOpacity = originalOpacity == '0' ? '1' : '0';
    animation = element.animate({'opacity': [testOpacity, testOpacity]},
        {duration: 1});
    animation.currentTime = 0;
    animated = getComputedStyle(element).getPropertyValue('opacity') == testOpacity;
  } finally {
    if (animation)
      animation.cancel();
  }
  if (animated) {
    return;
  }

  var originalElementAnimate = window.Element.prototype.animate;
  window.Element.prototype.animate = function(effectInput, options) {
    if (window.Symbol && Symbol.iterator && Array.prototype.from && effectInput[Symbol.iterator]) {
      // Handle custom iterables in most browsers by converting to an array
      effectInput = Array.from(effectInput);
    }

    if (!Array.isArray(effectInput) && effectInput !== null) {
      effectInput = shared.convertToArrayForm(effectInput);
    }

    return originalElementAnimate.call(this, effectInput, options);
  };
})(webAnimationsShared);
<|endoftext|>


<commit_before>;(function () {
	'use strict';
	angular.module('ngImageViewer', [])
		.directive('draggablePhoto', function ($window, $document, $timeout) {
			return {
				restrict: 'A',
				scope: {
					viewedImgId: '=',
					imgId: '='
				},
				link: function(scope, element) {
					var eventNames, eventHandlers, _mrx, _dragOffset, _mx, _tx, move, tools;

					_dragOffset = {};
					eventNames = {
						start: 'touchstart mousedown',
						move: 'touchmove mousemove',
						end: 'touchend mouseup'
					};

					move = {
						to: function (x) {
							element.css({
								transform: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', 0, 0, 1)',
								'z-index': 99999,
								'-webkit-transform': 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', 0, 0, 1)',
								'-ms-transform': 'matrix(1, 0, 0, 1, ' + x + ', 0)',
								'transition': ''
							});
						},
						defaults: function() {
							element.css({
								'transform':'translate3d(0,0,0)',
								'-webkit-transform': 'translate3d(0,0,0)',
								'transition': '0.5s ease all'
							});
						},
						right: function() {
							element.css({
								'transform':'translate3d(130%,0,0)',
								'-webkit-transform': 'translate3d(130%,0,0)',
								'transition': '0.5s ease all'
							});
						},
						left: function() {
							element.css({
								'transform':'translate3d(-130%,0,0)',
								'-webkit-transform': 'translate3d(-130%,0,0)',
								'transition': '0.5s ease all'
							});
						}
					};

					eventHandlers = {
						start: function(evt) {
							if (!tools.isCurrentImgViewed()) {
								return false;
							}
							if (!tools.isCurrentObj(evt.target)) {
								return false;
							}
							evt.preventDefault();

							_dragOffset = angular.element(element)[0].getBoundingClientRect();
							_mx = tools.getEvent(evt).pageX;
							_mrx = _mx - _dragOffset.left;
							_tx = _mx - _mrx - $window.pageXOffset;

							$document.on(eventNames.move, eventHandlers.move);
							$document.on(eventNames.end, eventHandlers.end);
						},
						move: function(evt) {
							if (!tools.isCurrentImgViewed()) {
								return false;
							}
							if (!tools.isCurrentObj(evt.target)) {
								return false;
							}
							evt.preventDefault();

							_mx = tools.getEvent(evt).pageX;
							_tx = _mx - _mrx - _dragOffset.left;

							move.to(_tx);
						},
						end: function(evt) {
							if (!tools.isCurrentImgViewed()) {
								return false;
							}
							if (!tools.isCurrentObj(evt.target)) {
								return false;
							}
							evt.preventDefault();

							if (_mrx + (_mrx / 3) > _mx) {
								move.right();
								scope.$emit('photoViewer:next');
							}
							else if (_mx - (_mx / 3) > _mrx) {
								move.left();
								scope.$emit('photoViewer:back');
							}
							else {
								move.defaults();
							}
							$document.off(eventNames.move, eventHandlers.move);
							$document.off(eventNames.end, eventHandlers.end);
						}
					};

					tools = {
						getEvent: function(event) {
							if (angular.isDefined(event.touches)) {
								return event.touches[0];
							}
							else if (angular.isDefined(event.originalEvent) && angular.isDefined(event.originalEvent.touches)) {
								return event.originalEvent.touches[0];
							}
							return event;
						},
						isCurrentObj: function (target) {
							return angular.equals(angular.element(target)[0], element[0]);
						},
						isCurrentImgViewed: function () {
							return scope.viewedImgId == scope.imgId;
						},
						calculateImgPosition: function () {
							if (tools.isCurrentImgViewed()) {
								move.defaults();
							}
							else if (scope.viewedImgId < scope.imgId) {
								move.right();
							}
							else if (scope.viewedImgId > scope.imgId) {
								move.left();
							}
						}
					};

					$document.on(eventNames.start, eventHandlers.start);
					$document.on(eventNames.move, eventHandlers.move);
					$document.on(eventNames.end, eventHandlers.end);

					scope.$watch('viewedImgId', tools.calculateImgPosition);
					scope.$on('changePhoto', tools.calculateImgPosition);

					tools.calculateImgPosition();
				}
			};
		})
		.directive('ngImageViewer', function () {
			return {
				restrict: 'A',
				scope: {
					imgs: '=',
					current: '=?'
				},
				template:
					'
= current || $index - 1 <= current">' +
						'' +
					'
',
				link: function(scope) {
					scope.current = !!scope.current ? scope.current : 0;
					scope.currentImgId = scope.current;
				},
				controller: function($scope, Debounce) {
					var backDebounceFunc, forwardDebounceFunc;
					$scope.$on('photoViewer:back', function () {
						if (!backDebounceFunc) {
							backDebounceFunc = Debounce(10, function () {
								$scope.$broadcast('changePhoto');
								if ($scope.currentImgId < 1) {
									return false;
								}
								$scope.currentImgId -= 1;
								backDebounceFunc = undefined;
							});
						}
						backDebounceFunc();
					});
					$scope.$on('photoViewer:next', function () {
						if (!forwardDebounceFunc) {
							forwardDebounceFunc = Debounce(10, function () {
								$scope.$broadcast('changePhoto');
								if ($scope.currentImgId == $scope.imgs.length - 1) {
									return false;
								}
								$scope.currentImgId += 1;
								forwardDebounceFunc = undefined;
							});
						}
						forwardDebounceFunc();
					});
					$scope.$watch('current', function (newVal) {
						$scope.currentImgId = $scope.current;
					});
				}
			};
		})
		.factory('Debounce', function ($timeout) {
			return function (wait, fn) {
				var args, context, result, timeout;
				function ping() {
					result = fn.apply(context || this, args || []);
					context = args = null;
				}
				function cancel() {
					if (timeout) {
						$timeout.cancel(timeout);
						timeout = null;
					}
				}
				function wrapper() {
					context = this;
					args = arguments;
					cancel();
					timeout = $timeout(ping, wait);
				}
				function flushPending() {
					var pending = !!context;
					if (pending) {
						// Call pending, do it now.
						cancel();
						ping();
					}
					return pending;
				}
				wrapper.flush = function () {
					if (!flushPending() && !timeout) {
						ping();
					}
					return result;
				};
				wrapper.flushPending = function () {
					flushPending();
					return result;
				};
				wrapper.cancel = cancel;
				return wrapper;
			};
		});
})();<commit_msg>MSIE support<commit_after>;(function () {
	'use strict';
	angular.module('ngImageViewer', [])
		.directive('draggablePhoto', function ($window, $document, $timeout) {
			return {
				restrict: 'A',
				scope: {
					viewedImgId: '=',
					imgId: '='
				},
				link: function(scope, element) {
					var eventNames, eventHandlers, _mrx, _dragOffset, _mx, _tx, move, tools;

					_dragOffset = {};
					eventNames = {
						start: 'touchstart mousedown',
						move: 'touchmove mousemove',
						end: 'touchend mouseup'
					};

					move = {
						to: function (x) {
							element.css({
								transform: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', 0, 0, 1)',
								'-webkit-transform': 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', 0, 0, 1)',
								'-ms-transform': 'matrix(1, 0, 0, 1, ' + x + ', 0)',
								'transition': ''
							});
						},
						defaults: function() {
							element.css({
								'transform':'translate3d(0,0,0)',
								'-webkit-transform': 'translate3d(0,0,0)',
								'-ms-transform': 'translate3d(0,0,0)',
								'transition': '0.5s ease all'
							});
						},
						right: function() {
							element.css({
								'transform':'translate3d(130%,0,0)',
								'-webkit-transform': 'translate3d(130%,0,0)',
								'-ms-transform': 'translate3d(130%,0,0)',
								'transition': '0.5s ease all'
							});
						},
						left: function() {
							element.css({
								'transform':'translate3d(-130%,0,0)',
								'-webkit-transform': 'translate3d(-130%,0,0)',
								'-ms-transform': 'translate3d(-130%,0,0)',
								'transition': '0.5s ease all'
							});
						}
					};

					eventHandlers = {
						start: function(evt) {
							if (!tools.isCurrentImgViewed()) {
								return false;
							}
							if (!tools.isCurrentObj(evt.target)) {
								return false;
							}
							evt.preventDefault();

							_dragOffset = angular.element(element)[0].getBoundingClientRect();
							_mx = tools.getEvent(evt).pageX;
							_mrx = _mx - _dragOffset.left;
							_tx = _mx - _mrx - $window.pageXOffset;

							$document.on(eventNames.move, eventHandlers.move);
							$document.on(eventNames.end, eventHandlers.end);
						},
						move: function(evt) {
							if (!tools.isCurrentImgViewed()) {
								return false;
							}
							if (!tools.isCurrentObj(evt.target)) {
								return false;
							}
							evt.preventDefault();

							_mx = tools.getEvent(evt).pageX;
							_tx = _mx - _mrx - _dragOffset.left;

							move.to(_tx);
						},
						end: function(evt) {
							if (!tools.isCurrentImgViewed()) {
								return false;
							}
							if (!tools.isCurrentObj(evt.target)) {
								return false;
							}
							evt.preventDefault();

							if (_mrx + (_mrx / 3) > _mx) {
								move.right();
								scope.$emit('photoViewer:next');
							}
							else if (_mx - (_mx / 3) > _mrx) {
								move.left();
								scope.$emit('photoViewer:back');
							}
							else {
								move.defaults();
							}
							$document.off(eventNames.move, eventHandlers.move);
							$document.off(eventNames.end, eventHandlers.end);
						}
					};

					tools = {
						getEvent: function(event) {
							if (angular.isDefined(event.touches)) {
								return event.touches[0];
							}
							else if (angular.isDefined(event.originalEvent) && angular.isDefined(event.originalEvent.touches)) {
								return event.originalEvent.touches[0];
							}
							return event;
						},
						isCurrentObj: function (target) {
							return angular.equals(angular.element(target)[0], element[0]);
						},
						isCurrentImgViewed: function () {
							return scope.viewedImgId == scope.imgId;
						},
						calculateImgPosition: function () {
							if (tools.isCurrentImgViewed()) {
								move.defaults();
							}
							else if (scope.viewedImgId < scope.imgId) {
								move.right();
							}
							else if (scope.viewedImgId > scope.imgId) {
								move.left();
							}
						}
					};

					$document.on(eventNames.start, eventHandlers.start);
					$document.on(eventNames.move, eventHandlers.move);
					$document.on(eventNames.end, eventHandlers.end);

					scope.$watch('viewedImgId', tools.calculateImgPosition);
					scope.$on('changePhoto', tools.calculateImgPosition);

					tools.calculateImgPosition();
				}
			};
		})
		.directive('ngImageViewer', function () {
			return {
				restrict: 'A',
				scope: {
					imgs: '=',
					current: '=?'
				},
				template:
					'
= current || $index - 1 <= current">' +
						'' +
					'
',
				link: function(scope) {
					scope.current = !!scope.current ? scope.current : 0;
					scope.currentImgId = scope.current;
				},
				controller: function($scope, Debounce) {
					var backDebounceFunc, forwardDebounceFunc;
					$scope.$on('photoViewer:back', function () {
						if (!backDebounceFunc) {
							backDebounceFunc = Debounce(10, function () {
								$scope.$broadcast('changePhoto');
								if ($scope.currentImgId < 1) {
									return false;
								}
								$scope.currentImgId -= 1;
								backDebounceFunc = undefined;
							});
						}
						backDebounceFunc();
					});
					$scope.$on('photoViewer:next', function () {
						if (!forwardDebounceFunc) {
							forwardDebounceFunc = Debounce(10, function () {
								$scope.$broadcast('changePhoto');
								if ($scope.currentImgId == $scope.imgs.length - 1) {
									return false;
								}
								$scope.currentImgId += 1;
								forwardDebounceFunc = undefined;
							});
						}
						forwardDebounceFunc();
					});
					$scope.$watch('current', function (newVal) {
						$scope.currentImgId = $scope.current;
					});
				}
			};
		})
		.factory('Debounce', function ($timeout) {
			return function (wait, fn) {
				var args, context, result, timeout;
				function ping() {
					result = fn.apply(context || this, args || []);
					context = args = null;
				}
				function cancel() {
					if (timeout) {
						$timeout.cancel(timeout);
						timeout = null;
					}
				}
				function wrapper() {
					context = this;
					args = arguments;
					cancel();
					timeout = $timeout(ping, wait);
				}
				function flushPending() {
					var pending = !!context;
					if (pending) {
						// Call pending, do it now.
						cancel();
						ping();
					}
					return pending;
				}
				wrapper.flush = function () {
					if (!flushPending() && !timeout) {
						ping();
					}
					return result;
				};
				wrapper.flushPending = function () {
					flushPending();
					return result;
				};
				wrapper.cancel = cancel;
				return wrapper;
			};
		});
})();<|endoftext|>


<commit_before>var moment = require('moment');

module.exports = {
	install: function (Vue, options) {
		Object.defineProperties(Vue.prototype, {
			$moment: {
				get: function() {
					return Vue.moment.bind(this);
				},
			},
		});

		if (options && options.moment) {
			moment = options.moment
		}

		Vue.moment = function(data) {
			return moment(data);
		}

		Vue.filter('moment', function() {
			var args = Array.prototype.slice.call(arguments),
				input = args.shift(),
				date;

			if (Array.isArray(input) && typeof input[0] === 'string') {
				// If input is array, assume we're being passed a format pattern to parse against.
				// Format pattern will accept an array of potential formats to parse against.
				// Date string should be at [0], format pattern(s) should be at [1]
				date = moment(string = input[0], formats = input[1], true);
			} else {
				// Otherwise, throw the input at moment and see what happens...
				date = moment(input);
			}

			if (!date.isValid()) {
				// Log a warning if moment couldn't reconcile the input. Better than throwing an error?
				console.warn('Could not build a valid `moment` object from input.');
				return input;
			}

			function parse() {
				var args = Array.prototype.slice.call(arguments),
					method = args.shift();

				switch (method) {
					case 'add':

						// Mutates the original moment by adding time.
						// http://momentjs.com/docs/#/manipulating/add/

						var addends = args.shift()
										  .split(',')
										  .map(Function.prototype.call, String.prototype.trim);
						obj = {};
						for (var n = 0; n < addends.length; n++) {
							var addend = addends[n].split(' ');
							obj[addend[1]] = addend[0];
						}
						date = date.add(obj);
						break;

					case 'subtract':

						// Mutates the original moment by subtracting time.
						// http://momentjs.com/docs/#/manipulating/subtract/

						var subtrahends = args.shift()
										  .split(',')
										  .map(Function.prototype.call, String.prototype.trim);
						obj = {};
						for (var n = 0; n < subtrahends.length; n++) {
							var subtrahend = subtrahends[n].split(' ');
							obj[subtrahend[1]] = subtrahend[0];
						}
						date = date.subtract(obj);
						break;

					case 'from':

						// Display a moment in relative time, either from now or from a specified date.
						// http://momentjs.com/docs/#/displaying/fromnow/

						var from = 'now';
						if (args[0] == 'now') args.shift();

						if (moment(args[0]).isValid()) {
							// If valid, assume it is a date we want the output computed against.
							from = moment(args.shift());
						}

						var removeSuffix = false;
						if (args[0] === true) {
							args.shift();
							var removeSuffix = true;
						}

						if (from != 'now') {
							date = date.from(from, removeSuffix);
							break;
						}

						date = date.fromNow(removeSuffix);
						break;

					case 'diff':

						// Mutates the original moment by doing a difference with another date.
						// http://momentjs.com/docs/#/displaying/difference/

						var dateDiff = 'now';
						if (args[0] == 'now') args.shift();

						if (moment(args[0]).isValid()) {
							dateDiff = moment(args.shift());
						}

						var units = '';
						if (args[0]) {
							var units = args.shift();
						}

						var floatingValue = false;
						if (args[0] === true) {
							args.shift();
							var floatingValue = true;
						}

						date = date.diff(dateDiff, units, floatingValue)
						break;

					case 'calendar':

						// Formats a date with different strings depending on how close to a certain date (today by default) the date is.
						// http://momentjs.com/docs/#/displaying/calendar-time/

						var referenceTime = moment();

						if (moment(args[0]).isValid()) {
							// If valid, assume it is a date we want the output computed against.
							referenceTime = moment(args.shift());
						}

						date = date.calendar(referenceTime);
						break;

					default:
						// Format
						// Formats a date by taking a string of tokens and replacing them with their corresponding values.
						// http://momentjs.com/docs/#/displaying/format/

						var format = method;
						date = date.format(format);
				}

				if (args.length) parse.apply(parse, args);
			}

			parse.apply(parse, args);

			return date;
		});
	},
};
<commit_msg>full proxy to momentjs<commit_after>var moment = require('moment');

module.exports = {
	install: function (Vue, options) {
		Object.defineProperties(Vue.prototype, {
			$moment: {
				get: function() {
					return Vue.moment.bind(this);
				},
			},
		});

		if (options && options.moment) {
			moment = options.moment
		}

		Vue.moment = moment;

		Vue.filter('moment', function() {
			var args = Array.prototype.slice.call(arguments),
				input = args.shift(),
				date;

			if (Array.isArray(input) && typeof input[0] === 'string') {
				// If input is array, assume we're being passed a format pattern to parse against.
				// Format pattern will accept an array of potential formats to parse against.
				// Date string should be at [0], format pattern(s) should be at [1]
				date = moment(string = input[0], formats = input[1], true);
			} else {
				// Otherwise, throw the input at moment and see what happens...
				date = moment(input);
			}

			if (!date.isValid()) {
				// Log a warning if moment couldn't reconcile the input. Better than throwing an error?
				console.warn('Could not build a valid `moment` object from input.');
				return input;
			}

			function parse() {
				var args = Array.prototype.slice.call(arguments),
					method = args.shift();

				switch (method) {
					case 'add':

						// Mutates the original moment by adding time.
						// http://momentjs.com/docs/#/manipulating/add/

						var addends = args.shift()
										  .split(',')
										  .map(Function.prototype.call, String.prototype.trim);
						obj = {};
						for (var n = 0; n < addends.length; n++) {
							var addend = addends[n].split(' ');
							obj[addend[1]] = addend[0];
						}
						date = date.add(obj);
						break;

					case 'subtract':

						// Mutates the original moment by subtracting time.
						// http://momentjs.com/docs/#/manipulating/subtract/

						var subtrahends = args.shift()
										  .split(',')
										  .map(Function.prototype.call, String.prototype.trim);
						obj = {};
						for (var n = 0; n < subtrahends.length; n++) {
							var subtrahend = subtrahends[n].split(' ');
							obj[subtrahend[1]] = subtrahend[0];
						}
						date = date.subtract(obj);
						break;

					case 'from':

						// Display a moment in relative time, either from now or from a specified date.
						// http://momentjs.com/docs/#/displaying/fromnow/

						var from = 'now';
						if (args[0] == 'now') args.shift();

						if (moment(args[0]).isValid()) {
							// If valid, assume it is a date we want the output computed against.
							from = moment(args.shift());
						}

						var removeSuffix = false;
						if (args[0] === true) {
							args.shift();
							var removeSuffix = true;
						}

						if (from != 'now') {
							date = date.from(from, removeSuffix);
							break;
						}

						date = date.fromNow(removeSuffix);
						break;

					case 'diff':

						// Mutates the original moment by doing a difference with another date.
						// http://momentjs.com/docs/#/displaying/difference/

						var dateDiff = 'now';
						if (args[0] == 'now') args.shift();

						if (moment(args[0]).isValid()) {
							dateDiff = moment(args.shift());
						}

						var units = '';
						if (args[0]) {
							var units = args.shift();
						}

						var floatingValue = false;
						if (args[0] === true) {
							args.shift();
							var floatingValue = true;
						}

						date = date.diff(dateDiff, units, floatingValue)
						break;

					case 'calendar':

						// Formats a date with different strings depending on how close to a certain date (today by default) the date is.
						// http://momentjs.com/docs/#/displaying/calendar-time/

						var referenceTime = moment();

						if (moment(args[0]).isValid()) {
							// If valid, assume it is a date we want the output computed against.
							referenceTime = moment(args.shift());
						}

						date = date.calendar(referenceTime);
						break;

					default:
						// Format
						// Formats a date by taking a string of tokens and replacing them with their corresponding values.
						// http://momentjs.com/docs/#/displaying/format/

						var format = method;
						date = date.format(format);
				}

				if (args.length) parse.apply(parse, args);
			}

			parse.apply(parse, args);

			return date;
		});
	},
};
<|endoftext|>


<commit_before>#! /usr/bin/env node
/*!
* slidedown.js
* Copyright (c) 2012 Aaron Jorbin
* Dual licensed under the MIT license and GPL license.
* https://github.com/aaronjorbin/slidedown.js/blob/master/MIT-license.txt
* https://github.com/aaronjorbin/slidedown.js/blob/master/GPL-license.txt
*/

/**
* Module dependencies.
*/

var fs = require('fs')
    , md =  require("node-markdown").Markdown
    , static = require('node-static');

// A couple of globals
var output = false;
var header = fs.readFileSync('header.html', 'ascii');
console.log('header loaded');
var footer = fs.readFileSync('footer.html', 'ascii');
console.log('footer loaded');
var sourceFilename = process.argv[2] || 'slides.md';
var source = fs.readFileSync(sourceFilename, 'ascii');
console.log('source: ' + sourceFilename +' loaded');
writeFile();

/* Setup our Server */
var file = new static.Server('./public');
require('http').createServer(function (request, response) {
    request.addListener('end', function () {
        file.serve(request, response);
    });
}).listen(9000);

// The first arg is the file to watch
fs.watchFile( sourceFilename, function(curr,prev){
    source = fs.readFileSync(sourceFilename, 'ascii');
    console.log('source reloaded');
    writeFile();
});
fs.watchFile('header.html', function(curr, prev){
    header = fs.readFileSync('header.html', 'ascii');
    console.log('header reloaded');
    writeFile();
})
fs.watchFile('footer.html', function(curr,prev){
    footer = fs.readFileSync('footer.html', 'ascii');
    console.log('footer reloaded');
    writeFile();
});

// The second arg is the output file
function writeFile(){
    var filename =  process.argv[3] ||  process.argv[2].replace(/\.md/, '.html');
    var innerHtml = md(source);
    var html = header + innerHtml + footer;
    fs.writeFileSync('public/'+ filename, html, 'ascii');
    console.log( filename + ' written');
}
<commit_msg>Make all args optional<commit_after>#! /usr/bin/env node
/*!
* slidedown.js
* Copyright (c) 2012 Aaron Jorbin
* Dual licensed under the MIT license and GPL license.
* https://github.com/aaronjorbin/slidedown.js/blob/master/MIT-license.txt
* https://github.com/aaronjorbin/slidedown.js/blob/master/GPL-license.txt
*/

/**
* Module dependencies.
*/

var fs = require('fs')
    , md =  require("node-markdown").Markdown
    , static = require('node-static');

// A couple of globals
var output = false;
var header = fs.readFileSync('header.html', 'ascii');
console.log('header loaded');
var footer = fs.readFileSync('footer.html', 'ascii');
console.log('footer loaded');
var sourceFilename = process.argv[2] || 'slides.md';
var source = fs.readFileSync(sourceFilename, 'ascii');
console.log('source: ' + sourceFilename +' loaded');
writeFile();

/* Setup our Server */
var file = new static.Server('./public');
require('http').createServer(function (request, response) {
    request.addListener('end', function () {
        file.serve(request, response);
    });
}).listen(9000);

// The first arg is the file to watch
fs.watchFile( sourceFilename, function(curr,prev){
    source = fs.readFileSync(sourceFilename, 'ascii');
    console.log('source reloaded');
    writeFile();
});
fs.watchFile('header.html', function(curr, prev){
    header = fs.readFileSync('header.html', 'ascii');
    console.log('header reloaded');
    writeFile();
})
fs.watchFile('footer.html', function(curr,prev){
    footer = fs.readFileSync('footer.html', 'ascii');
    console.log('footer reloaded');
    writeFile();
});

// The second arg is the output file
function writeFile(){
    var filename =  sourceFilename ||  process.argv[2].replace(/\.md/, '.html');
    var innerHtml = md(source);
    var html = header + innerHtml + footer;
    fs.writeFileSync('public/'+ filename, html, 'ascii');
    console.log( filename + ' written');
}
<|endoftext|>


<commit_before>function ScoreBoard(pixiStage, board){
  this.score = 0;
  this.text = new PIXI.Text("" + this.score);
  this.board = board;

  pixiStage.addChild( this.text );
}

ScoreBoard.prototype = {
  incrementScore: function( upMoleNumber, dt ){
    this.score += upMoleNumber * 100 * dt;
    this.text.setText(""+this.score);
  },

  update : function( time, dt ){
    this.incrementScore( this.board.countScoringMoles(), dt);
  }

}

<commit_msg>Time implemented<commit_after>function ScoreBoard(pixiStage, board){
  this.score = 0;
  this.time = 120;

  this.scoreText = new PIXI.Text(this.score.toFixed(0));
  this.scoreText.anchor.x = 1;
  this.scoreText.anchor.y = 1;
  this.scoreText.position.x = 620;
  this.scoreText.position.y = 120;

  this.timeText = new PIXI.Text( timeToString( this.time ) );
  this.timeText.anchor.x = 1;
  this.timeText.anchor.y = 1;
  this.timeText.position.x = 320;
  this.timeText.position.y = 120;

  this.board = board;

  pixiStage.addChild( this.scoreText );
  pixiStage.addChild( this.timeText );
}

ScoreBoard.prototype = {
  incrementScore: function( upMoleNumber, dt ){
    this.score += upMoleNumber * 100 * dt;
    this.scoreText.setText(this.score.toFixed(0));
  },

  updateTime : function( dt ){
    this.time -= dt;
    this.timeText.setText( timeToString( this.time ) );
  },

  update : function( time, dt ){
    this.incrementScore( this.board.countScoringMoles(), dt);
    this.updateTime( dt );
  }
}

function timeToString( t ){
  var s = t % 60;
  return (( t - s )/ 60).toFixed(0) + ":" + (s<10?"0":"")  + s.toFixed(0);
}
<|endoftext|>


<commit_before>// DEMO JAVASCRIPT ONLY
// this is not required to use foresight.js, this is here only to help view info about the images

var initForesightDebugger = function () {
	// oncomplete only being use to print out debugger info, demo purposes only
	var info = [];

	info.push( 'Foresight Images: ' + foresight.images.length );
	info.push( 'Device Pixel Ratio: ' + foresight.devicePixelRatio + ', Device Pixel Ratio Rounded: ' + foresight.devicePixelRatioRounded );
	info.push( 'Connection Test Result: ' + foresight.connTestResult );
	if( foresight.connTestResult !== 'skip' && foresight.connTestResult !== 'forced' ) {
		info.push( 'Connection Type: ' + foresight.connType );
		info.push( 'Estimated Connection Speed: ' + foresight.connKbps + 'Kbps' );
	} else if( foresight.connTestResult === 'skip' && foresight.devicePixelRatio == 1 ) {
		info.push( 'Bandwidth test skipped because this display has a device pixel ratio of 1' );
	}

	//if( foresight.devicePixelRatio > 1 ) {
	//	info.push( 'Force this page to think it has a device pixel ratio of 1: Force DPR 1' );
	//} else {
	//	info.push( 'Force this page to think it has a device pixel ratio of 2: Force DPR 2' );
	//}

	if ( foresight.bandwidth ) {
		info.push( 'Bandwidth: ' + foresight.bandwidth );
	}
	info.push( '
' );

	// add in a
 element or use one already there for debugging info
	var docPres = document.getElementsByTagName('pre');
	if( docPres && docPres.length ) {
		var docPre = docPres[ 0 ];
	} else {
		var docPre = document.createElement( 'pre' );
		if( foresight.images.length ) {
			foresight.images[ 0 ].parentElement.insertBefore( docPre, foresight.images[ 0 ] );
		} else {
			document.body.appendChild( docPre );
		}
	}
	docPre.innerHTML = info.join( '
' );

	// print out img info above each foresight image
	for( var x = 0; x < foresight.images.length; x++ ) {
		var img = foresight.images[ x ];

		if ( !img.requestChange ) {
			continue;
		}

		var imgInfo = [];
		imgInfo.push( 'Dimension Unit Type: ' + img.unitType );
		if ( img.computedWidth ) {
			imgInfo.push( 'Computed Width: ' + img.computedWidth );
		}
		imgInfo.push( 'Browser Width/Height: ' + img.browserWidth + ' x ' + img.browserHeight );
		imgInfo.push( 'Request Width/Height: ' + img.requestWidth + ' x ' + img.requestHeight );
		if ( img.naturalWidth && img.naturalHeight ) {
			imgInfo.push( 'Natural Width/Height: ' + img.naturalWidth + ' x ' + img.naturalHeight );
		}

		imgInfo.push( 'Original: ' + img.orgSrc);
		imgInfo.push( 'Applied Image-set item: Scale: ' + img.appliedImageSetItem.scale + ', Scale Rounded: ' + img.appliedImageSetItem.scaleRounded + ', Bandwidth: ' + img.appliedImageSetItem.bandwidth );
		imgInfo.push( 'Src Modification: ' + img.srcModification );

		if ( img.highResolutionSrc && foresight.hiResEnabled ) {
			imgInfo.push( 'Hi-Res Src Attribute: ' + img.highResolutionSrc );
		} else if( img.srcModification === 'src-uri-template' ) {
			imgInfo.push( 'URI Template: ' + img.appliedImageSetItem.uriTemplate );
		} else if( img.srcModification === 'src-find-replace' ) {
			imgInfo.push( 'URI Find/Replace: Find: ' + img.appliedImageSetItem.uriFind + ', Replace: ' + img.appliedImageSetItem.uriReplace );
		} else if( img.srcModification === 'response-error' ) {
			imgInfo.push( 'Modified updated src had a response error, request the original src instead' );
		}

		imgInfo.push( 'Request: ' + img.src);

		if ( !img.infoElement ) {
			img.infoElement = document.createElement( 'div' );
			img.parentElement.insertBefore(img.infoElement, img);
		}

		var newInfoElement = document.createElement( 'pre' );
		newInfoElement.innerHTML = imgInfo.join( '
' );
		img.infoElement.appendChild(newInfoElement);
	}

};

var foresightDebugger = function () {
	// kick off the debugger when the window has been loaded
	if ( document.readyState === 'complete' ) {
		initForesightDebugger();
	} else {
		if ( document.addEventListener ) {
			window.addEventListener( "load", initForesightDebugger, false );
		} else if ( document.attachEvent ) {
			window.attachEvent( "onload", initForesightDebugger );
		}
	}
}

window.foresight = window.foresight || {};

window.foresight.updateComplete = foresightDebugger;

window.foresight.options = window.foresight.options || {};

// You can set your own variables both bandwidth and device pixel ratio

// Querystring dpr sets the device pixel ratio, possible values: 1.5 and 2
// Querystring bw sets the bandwidth, possible values: low and high

if ( window.location.search.indexOf( 'dpr=2' ) > -1 ) {
	window.foresight.options.forcedPixelRatio = 2
} else if ( window.location.search.indexOf( 'dpr=1.5' ) > -1 ) {
	window.foresight.options.forcedPixelRatio = 1.5
}

if ( window.location.search.indexOf( 'bw=low' ) > -1 ) {
	window.foresight.options.forcedBandwidth = 'low'
} else if ( window.location.search.indexOf( 'bw=high' ) > -1 ) {
	window.foresight.options.forcedBandwidth = 'high'
}

<commit_msg>Debugger
 classnames (.foresight-debug.global, .foresight-debug.local)<commit_after>// DEMO JAVASCRIPT ONLY
// this is not required to use foresight.js, this is here only to help view info about the images

var initForesightDebugger = function () {
	// oncomplete only being use to print out debugger info, demo purposes only
	var info = [];

	info.push( 'Foresight Images: ' + foresight.images.length );
	info.push( 'Device Pixel Ratio: ' + foresight.devicePixelRatio + ', Device Pixel Ratio Rounded: ' + foresight.devicePixelRatioRounded );
	info.push( 'Connection Test Result: ' + foresight.connTestResult );
	if( foresight.connTestResult !== 'skip' && foresight.connTestResult !== 'forced' ) {
		info.push( 'Connection Type: ' + foresight.connType );
		info.push( 'Estimated Connection Speed: ' + foresight.connKbps + 'Kbps' );
	} else if( foresight.connTestResult === 'skip' && foresight.devicePixelRatio == 1 ) {
		info.push( 'Bandwidth test skipped because this display has a device pixel ratio of 1' );
	}

	//if( foresight.devicePixelRatio > 1 ) {
	//	info.push( 'Force this page to think it has a device pixel ratio of 1: Force DPR 1' );
	//} else {
	//	info.push( 'Force this page to think it has a device pixel ratio of 2: Force DPR 2' );
	//}

	if ( foresight.bandwidth ) {
		info.push( 'Bandwidth: ' + foresight.bandwidth );
	}
	info.push( '
' );

	// add in a
 element or use one already there for debugging info
	var docPres = document.getElementsByTagName('pre');
	if( docPres && docPres.length ) {
		var docPre = docPres[ 0 ];
	} else {
		var docPre = document.createElement( 'pre' );
        docPre.className = "foresight-debug global";
		if( foresight.images.length ) {
			foresight.images[ 0 ].parentElement.insertBefore( docPre, foresight.images[ 0 ] );
		} else {
			document.body.appendChild( docPre );
		}
	}
	docPre.innerHTML = info.join( '
' );

	// print out img info above each foresight image
	for( var x = 0; x < foresight.images.length; x++ ) {
		var img = foresight.images[ x ];

		if ( !img.requestChange ) {
			continue;
		}

		var imgInfo = [];
		imgInfo.push( 'Dimension Unit Type: ' + img.unitType );
		if ( img.computedWidth ) {
			imgInfo.push( 'Computed Width: ' + img.computedWidth );
		}
		imgInfo.push( 'Browser Width/Height: ' + img.browserWidth + ' x ' + img.browserHeight );
		imgInfo.push( 'Request Width/Height: ' + img.requestWidth + ' x ' + img.requestHeight );
		if ( img.naturalWidth && img.naturalHeight ) {
			imgInfo.push( 'Natural Width/Height: ' + img.naturalWidth + ' x ' + img.naturalHeight );
		}

		imgInfo.push( 'Original: ' + img.orgSrc);
		imgInfo.push( 'Applied Image-set item: Scale: ' + img.appliedImageSetItem.scale + ', Scale Rounded: ' + img.appliedImageSetItem.scaleRounded + ', Bandwidth: ' + img.appliedImageSetItem.bandwidth );
		imgInfo.push( 'Src Modification: ' + img.srcModification );

		if ( img.highResolutionSrc && foresight.hiResEnabled ) {
			imgInfo.push( 'Hi-Res Src Attribute: ' + img.highResolutionSrc );
		} else if( img.srcModification === 'src-uri-template' ) {
			imgInfo.push( 'URI Template: ' + img.appliedImageSetItem.uriTemplate );
		} else if( img.srcModification === 'src-find-replace' ) {
			imgInfo.push( 'URI Find/Replace: Find: ' + img.appliedImageSetItem.uriFind + ', Replace: ' + img.appliedImageSetItem.uriReplace );
		} else if( img.srcModification === 'response-error' ) {
			imgInfo.push( 'Modified updated src had a response error, request the original src instead' );
		}

		imgInfo.push( 'Request: ' + img.src);

		if ( !img.infoElement ) {
			img.infoElement = document.createElement( 'div' );
			img.parentElement.insertBefore(img.infoElement, img);
		}

		var newInfoElement = document.createElement( 'pre' );
        newInfoElement.className = "foresight-debug local";
		newInfoElement.innerHTML = imgInfo.join( '
' );
		img.infoElement.appendChild(newInfoElement);
	}

};

var foresightDebugger = function () {
	// kick off the debugger when the window has been loaded
	if ( document.readyState === 'complete' ) {
		initForesightDebugger();
	} else {
		if ( document.addEventListener ) {
			window.addEventListener( "load", initForesightDebugger, false );
		} else if ( document.attachEvent ) {
			window.attachEvent( "onload", initForesightDebugger );
		}
	}
}

window.foresight = window.foresight || {};

window.foresight.updateComplete = foresightDebugger;

window.foresight.options = window.foresight.options || {};

// You can set your own variables both bandwidth and device pixel ratio

// Querystring dpr sets the device pixel ratio, possible values: 1.5 and 2
// Querystring bw sets the bandwidth, possible values: low and high

if ( window.location.search.indexOf( 'dpr=2' ) > -1 ) {
	window.foresight.options.forcedPixelRatio = 2
} else if ( window.location.search.indexOf( 'dpr=1.5' ) > -1 ) {
	window.foresight.options.forcedPixelRatio = 1.5
}

if ( window.location.search.indexOf( 'bw=low' ) > -1 ) {
	window.foresight.options.forcedBandwidth = 'low'
} else if ( window.location.search.indexOf( 'bw=high' ) > -1 ) {
	window.foresight.options.forcedBandwidth = 'high'
}

<|endoftext|>


<commit_before>const
Session=require('./Session'),
pTime=require('pico-common').export('pico/time'),
pStr=require('pico-common').export('pico/str'),
dummyCB=()=>{},
SigSlot=function(){
    this.slots= {}
	this.builtRoutes=[]
	this.name=Math.ceil(Math.random()*100000)
},
wildcard=function(path, slots){
    if (!path.length) return
    path.pop()
    return slots[path.join('/')] || wildcard(path, slots)
},
runExpired=function(ctx,idx){
	console.warn(`Signal.run stucked @ ${ctx.api}:${idx-1}`)
},
run=function(route, idx, ctx, cb){
    if (route.length <= idx) return cb()
    const args=[]
	let
    funcs=route[idx++],
    func=funcs[0],
    f

    // callback to request module
    if (!func){
        funcs=ctx.getKeys(ctx.type).reverse()
        f=funcs[0]
        if (!ctx.has(f)) return run(route, idx, ctx, cb)
        func=ctx.get(f)
		if (!(func instanceof Function)) return run(route, idx, ctx, cb)
    }

    for(let i=1; f=funcs[i]; i++){
        if (Array.isArray(f)) args.push(...f)
        else {
            switch(f[0]){
            default: args.push(ctx.get(f)); break
            case '$':args.push(ctx.getReadonly(f)); break
            case ':':args.push(ctx.getArray(f)); break
            case '@':args.push(ctx.getMap(f)); break
            case '#':args.push(ctx.WeakMap(f)); break
            case '%':args.push(ctx.getSet(f)); break
            case '^':args.push(ctx.getWeakSet(f)); break
            }
        }
    }

	const expiry=setTimeout(runExpired,1000,ctx,idx)

    args.push((err, api)=>{
		clearTimeout(expiry)
        if (err || api) return cb(err, api)
        run(route, idx, ctx, cb)
    })

    func.apply(ctx, args)
},
proc=function(routes, idx, ctx){
    if (routes.length <= idx) return
    run(routes[idx++], 0, ctx, (err, api)=>{
        if (err) ctx.sigslot.assert(ctx.api, ctx, err)
        else if (api) ctx.sigslot.signalWithSession.call(ctx.sigslot, api, ctx)
		/* fall through */
        proc(routes, idx, ctx)
    })
},
load=function(self, keys, deps, routes, cb){
    if(!keys.length) return cb()
    const
    k=keys.shift(),
    route=routes[k],
	at=pTime.parse(k)

    for(let i=0,f; f=route[i]; i++){
        switch(f.length){
        case 0: break
        case 1: f.length=0; break
        default:
			f.splice(0, 2, deps[f[0]][f[1]]);
			if (!f[0]) throw `invalid route[${k}] at rule[${i}]`
			break
        }
    }

	if (at) self.signalAt(at,k)

    self.slot(k, route)
    load(self, keys, deps, routes, cb)
}

SigSlot.prototype= {
    load(deps, routes, cb){
        load(this, Object.keys(routes), deps, routes, cb||dummyCB)
    },
    slot(api, funcs){
        const
        slots=this.slots,
        routes=slots[api]=slots[api]||[]

		pStr.compileRest(api,this.builtRoutes)
        routes.push(funcs)
    },
    unslot(api){
        delete this.slots[api]
    },
    signal(api, type){
        let
		routes = this.slots[api],// || wildcard(api.split('/'), this.slots),
		params

        if (!routes){
			params={}
			routes=this.slots[pStr.execRest(api, this.builtRoutes, params)]
			if(!routes)return console.error(`slot[${api}] not found`)
		}
        proc(routes, 0, Session.alloc(
			api,
			this,
			type||Session.TYPE.CUSTOM,
			params,
			Array.prototype.slice.call(arguments, arguments.callee.length)))
    },
    signalWithSession(api, sess){
        let routes = this.slots[api]

        if (!routes){
			routes=this.slots[pStr.execRest(api, this.builtRoutes, sess.params || {})]
			if (!routes) return this.assert(api, sess, `slot[${api}] not found, session[${sess.api}]`)
		}
        proc(routes, 0, sess)
    },
    // at is cron format. at format: min, hour, dom, mon, dow, yr
    signalAt(at){
        const
        now=Date.now(),
        ast=Array.isArray(at) ? at : pTime.parse(at),
        then=pTime.nearest(...ast)
        if (now > then) return

        setTimeout((params)=>{
            this.signalAt(ast, ...params)
            this.signal(...params)
        }, then-now, Array.prototype.slice.call(arguments, arguments.callee.length))
    },
    assert(api, sess, err){
        if (0 === api.indexOf('ERR/')) return console.error(err)
        sess.set('error', err)
        this.signalWithSession('ERR/'+(api||''), sess)
    },
    abort(api){
        return 'END/'+(api||'')
    }
}

module.exports= SigSlot
<commit_msg>incr timeout<commit_after>const
Session=require('./Session'),
pTime=require('pico-common').export('pico/time'),
pStr=require('pico-common').export('pico/str'),
dummyCB=()=>{},
SigSlot=function(){
    this.slots= {}
	this.builtRoutes=[]
	this.name=Math.ceil(Math.random()*100000)
},
wildcard=function(path, slots){
    if (!path.length) return
    path.pop()
    return slots[path.join('/')] || wildcard(path, slots)
},
runExpired=function(ctx,idx){
	console.warn(`Signal.run stucked @ ${ctx.api}:${idx-1}`)
},
run=function(route, idx, ctx, cb){
    if (route.length <= idx) return cb()
    const args=[]
	let
    funcs=route[idx++],
    func=funcs[0],
    f

    // callback to request module
    if (!func){
        funcs=ctx.getKeys(ctx.type).reverse()
        f=funcs[0]
        if (!ctx.has(f)) return run(route, idx, ctx, cb)
        func=ctx.get(f)
		if (!(func instanceof Function)) return run(route, idx, ctx, cb)
    }

    for(let i=1; f=funcs[i]; i++){
        if (Array.isArray(f)) args.push(...f)
        else {
            switch(f[0]){
            default: args.push(ctx.get(f)); break
            case '$':args.push(ctx.getReadonly(f)); break
            case ':':args.push(ctx.getArray(f)); break
            case '@':args.push(ctx.getMap(f)); break
            case '#':args.push(ctx.WeakMap(f)); break
            case '%':args.push(ctx.getSet(f)); break
            case '^':args.push(ctx.getWeakSet(f)); break
            }
        }
    }

	const expiry=setTimeout(runExpired,5000,ctx,idx)

    args.push((err, api)=>{
		clearTimeout(expiry)
        if (err || api) return cb(err, api)
        run(route, idx, ctx, cb)
    })

    func.apply(ctx, args)
},
proc=function(routes, idx, ctx){
    if (routes.length <= idx) return
    run(routes[idx++], 0, ctx, (err, api)=>{
        if (err) ctx.sigslot.assert(ctx.api, ctx, err)
        else if (api) ctx.sigslot.signalWithSession.call(ctx.sigslot, api, ctx)
		/* fall through */
        proc(routes, idx, ctx)
    })
},
load=function(self, keys, deps, routes, cb){
    if(!keys.length) return cb()
    const
    k=keys.shift(),
    route=routes[k],
	at=pTime.parse(k)

    for(let i=0,f; f=route[i]; i++){
        switch(f.length){
        case 0: break
        case 1: f.length=0; break
        default:
			f.splice(0, 2, deps[f[0]][f[1]]);
			if (!f[0]) throw `invalid route[${k}] at rule[${i}]`
			break
        }
    }

	if (at) self.signalAt(at,k)

    self.slot(k, route)
    load(self, keys, deps, routes, cb)
}

SigSlot.prototype= {
    load(deps, routes, cb){
        load(this, Object.keys(routes), deps, routes, cb||dummyCB)
    },
    slot(api, funcs){
        const
        slots=this.slots,
        routes=slots[api]=slots[api]||[]

		pStr.compileRest(api,this.builtRoutes)
        routes.push(funcs)
    },
    unslot(api){
        delete this.slots[api]
    },
    signal(api, type){
        let
		routes = this.slots[api],// || wildcard(api.split('/'), this.slots),
		params

        if (!routes){
			params={}
			routes=this.slots[pStr.execRest(api, this.builtRoutes, params)]
			if(!routes)return console.error(`slot[${api}] not found`)
		}
        proc(routes, 0, Session.alloc(
			api,
			this,
			type||Session.TYPE.CUSTOM,
			params,
			Array.prototype.slice.call(arguments, arguments.callee.length)))
    },
    signalWithSession(api, sess){
        let routes = this.slots[api]

        if (!routes){
			routes=this.slots[pStr.execRest(api, this.builtRoutes, sess.params || {})]
			if (!routes) return this.assert(api, sess, `slot[${api}] not found, session[${sess.api}]`)
		}
        proc(routes, 0, sess)
    },
    // at is cron format. at format: min, hour, dom, mon, dow, yr
    signalAt(at){
        const
        now=Date.now(),
        ast=Array.isArray(at) ? at : pTime.parse(at),
        then=pTime.nearest(...ast)
        if (now > then) return

        setTimeout((params)=>{
            this.signalAt(ast, ...params)
            this.signal(...params)
        }, then-now, Array.prototype.slice.call(arguments, arguments.callee.length))
    },
    assert(api, sess, err){
        if (0 === api.indexOf('ERR/')) return console.error(err)
        sess.set('error', err)
        this.signalWithSession('ERR/'+(api||''), sess)
    },
    abort(api){
        return 'END/'+(api||'')
    }
}

module.exports= SigSlot
<|endoftext|>