<commit_before>
var xhr_reqs = [];

function create_autocomplete_item(item, content_type, multiple_status, field_name){
	var field = { multiple:multiple_status, contenttype: content_type, name: field_name, value: item._id };
	var newel = _.template($('#field-autocomplete-item').html(), { title:item.title, field: field, item:item});
	return newel;
}

function update_content(data) {
	var results_data=_.template($('#'+data.template).html(), data);
	$('#'+data.element).html(results_data);
}

$(function() {
	$(".result_container div a.close").live('click', function(){
		$(this).parent().remove();
	});

	$('
Word count:

').insertAfter(".wordcount");

	$(".wordcount").keyup(function() {
		get_wordcount($(this));
	});

	$(".wordcount").each(function() {
		get_wordcount($(this));
	});

	$(".remover").live("click", function() { //Not sure if this is still used?
		$(this).parent().remove();
		return false;
	});

	$(document).on('keydown', '.datetime_hour', function(e) {
		var key = e.keyCode;
		if ((key > 33) && (key < 47)) {
			return false;
		}
		if ((key > 58) && (key < 126)) {
			return false;
		}
	});

	$(document).on('blur', '.datetime_hour', function() {
		var v = 0;
		if (($(this).val())) {
			v = Number($(this).val());
			$(this).val(leadingZeros(v));
			if ($(this).val().length > 2) {
				var s = $(this).val();
				$(this).val(s.substring(s.length - 2, s.length));
				v = parseInt($(this).val());
			}
			if (v > 23) {
				$(this).val("23");
			}
		} else {
			$(this).val("00");
		}
		if (!isFinite($(this).val())) {
			$(this).val("00");
		}
	});

	$(document).on('blur', '.datetime_minute', function() {
		if ($(this).val()) {
			var v = Number($(this).val());
			$(this).val(leadingZeros(v));
			if ($(this).val().length > 2) {
				var s = $(this).val();
				$(this).val(s.substring(s.length - 2, s.length));
				v = parseInt($(this).val());
			}
			if (v > 59) {
				$(this).val("59");
			}
		} else {
			$(this).val("00");
		}
		if (!isFinite($(this).val())) {
			$(this).val("00");
		}
	});

	$(document).on('keydown', '.datetime_minute', function(e) {
		var key = e.keyCode;
		if ((key > 33) && (key < 47)) {
			return false;
		}
		if ((key > 58) && (key < 126)) {
			return false;
		}
	});

	$(document).on('keyup', '.datetime_change', function() {
		updateDateTime(this);
	});

	$(document).on('change', '.datetime_change', function() {
		updateDateTime(this);
	});

	function updateDateTime(sender) {
		var parent = $(sender).parent();
		var val = "";
		val += parent.children('.datetime_date').val();
		val += " ";
		val += (parent.children('.datetime_hour').val()) ? parent.children('.datetime_hour').val() : "00";
		val += ":";
		val += (parent.children('.datetime_minute').val()) ? parent.children('.datetime_minute').val() : "00";
		$(sender).siblings(':hidden').val(stringToDate(val));
	}

	$(document).on('click', '.deepsearch-search', function() {
		var multiple_status = $(this).prev().attr('multiple');
		var field_name = $(this).prev().attr('fieldname');
		var searchel=$(this).prev();
		var origel = this;
		var search=$(this).prev().val();
		var content_type=$(this).prev().attr("contenttype");
		var optionel=$(this).parent().siblings('.deepsearch-options');
		var resultel=$(this).parent().siblings('.deepsearch-results');
		var indicator = $(this);
		while(xhr_reqs.length>0) {
			jqXHR=xhr_reqs.pop();
			jqXHR.abort();
		}
		indicator.html("Searching...");
		xhr_reqs.push(
			$.getJSON("/api/content", { search: search, content_type: content_type, limit: 20, fields: ["_id", "title"], order_by: "last_modified" }, function(data) {
				var pos = $.extend({}, searchel.offset(), {
		    		height: origel.offsetHeight
				});

				optionel.css({
					top: pos.top + pos.height
					, left: pos.left
				});

				optionel.show();

				optionel.html('');

				_.each(data.content, function(item) {
					var el=$('
'+item.title+'
').click(function(e) {
						e.stopPropagation();
						e.preventDefault();
						optionel.hide();
						resultel.append(create_autocomplete_item(item, content_type, multiple_status, field_name));
						searchel.val("");
					});
					optionel.append(el);
					indicator.html('Search');
				});
			})
		);
	});

	$(document).on('change', 'input[type=file]', function() {
		var files=this.files; //FileList object
		var el=$(this);
		var container=el.parent();
		var multiple = el.attr("data-multiple");
		var contenttype = el.attr("data-contenttype");
		var name = el.attr("data-name");
		container.find('.progress-container').empty();
		_.each(files, function(f, id) {
			var filename = f.name;
			console.log(f);
			var uid = name + "_" + id;

			$.ajax({
				url: "/api/files/upload?api_key=" + $(document.body).data('api_key') + "&filename="+f.name,  //server script to process data
				type: 'POST',
				xhr: function() {  // custom xhr
					var myXhr = $.ajaxSettings.xhr();
					if (myXhr.upload) { // check if upload property exists
						myXhr.upload.addEventListener('progress', function(data) {
							var percentage = Math.round((data.position / data.total) * 100);
							container.find('.progress-container #' + uid + ' .progress .bar').css('width', percentage + '%');
						}, false); // for handling the progress of the upload
					} // else throw an error here maybe?
					return myXhr;
				},

				//Ajax events
				beforeSend: function(data) {
					container.find('.progress-container').append(_.template($("#field-image-progress").html(), { uid: uid, filename: filename }));
					container.find('.progress-container #' + uid + ' .progress').show();
					container.find('.progress-container #' + uid + '').slideDown();
					container.find('.progress-container .progress .bar').removeClass('bar-success').removeClass('bar-danger');
				},
				success: function(data) {

					if (data.error) {
						container.find('.progress-container #' + uid + ' .progress').hide().destroy();
						container.find('.progress-container #' + uid + ' .alert').removeClass('alert-success').addClass('alert-error').html('
File upload failed for '+filename+'
 '+data.message).slideDown(500).delay(2000).slideUp(500);
						container.find('.progress-container #' + uid + ' .progress .bar').removeClass('bar-danger').addClass('bar-success');
						return false;
					}
					var fullname = data.content.full_name;
					var filename = data.content.filename;
					container.find('.progress-container #' + uid + ' .progress').hide();
					container.find('.progress-container #' + uid + ' .alert').addClass('alert-success').removeClass('alert-error').html('File '+ filename +' uploaded').show().delay(1000).slideDown(500).delay(2000).slideUp(500);

					if (multiple == 1) {
						container.find('.preview-image-items').prepend(_.template($("#field-image-item").html(), { value: fullname, field: { value: fullname, name: name, contenttype: contenttype, multiple: multiple } } ));
					} else {
						container.find('.preview-image-items').html(_.template($("#field-image-item").html(), { value: fullname, field: { value: fullname, name: name, contenttype: contenttype, multiple: multiple } } ));
					}
					el.val(""); //Clear the file upload so we don't upload on form submission
				},
				error: function(xhr, s) {
					container.find('.progress-container #' + uid + ' .alert').removeClass('alert-success').addClass('alert-error').html('File upload failed: '+s).slideDown(500).delay(2000).slideUp(500);
					container.find('.progress-container #' + uid + ' .progress .bar').removeClass('bar-success').addClass('bar-danger');
				},
				// Form data
				data: f,
				//Options to tell JQuery not to process data or worry about content-type
				cache: false,
				contentType: false,
				processData: false,
				timeout: 600000 //10 mins
			});
		});
	});

});

function get_wordcount(sender) {
	sender.nextAll(".wordcount_container").first().find(".wordcount_result").load("/workers/ajax_edit/wordcount", {"str": sender.val()});
}

function init_form() {
	$(".chzn-select").chosen();

	$(".my-datepicker").datepicker({ autoclose: true });

	var autocomplete_timer = false;

	$(".autocomplete").each(function(){
		var self = $(this);
		var self_val = '';
		var origel = this;
		self.keyup(function(){
			if ($.trim(self_val) != $.trim(self.val())) {
				self_val = self.val();
				clearTimeout(autocomplete_timer);
				autocomplete_timer = setTimeout(function(){
				var searchel=self.prev();
				var multiple_status = self.attr('multiple');
				var field_name = self.attr('fieldname');
				var search=self.prev().val();
				var optionel=self.parent().siblings('.options');
				var resultel=self.parent().siblings('.result_container');
				var search_content_type = self.attr("contenttypes");
				var url="/api/content/listing/";
				var search = self.val();
				var indicator = self.parent().siblings('.indicator');
				while(xhr_reqs.length>0) {
					jqXHR=xhr_reqs.pop();
					jqXHR.abort();
				}
				indicator.show();
				xhr_reqs.push(
					$.getJSON("/api/content", { search: search, content_type: search_content_type, limit: 20, fields: ["_id", "title"], order_by: "last_modified" }, function(data) {
						var pos = $.extend({}, searchel.offset(), {
							height: origel.offsetHeight
						});

						optionel.css({
							top: pos.top + pos.height
							, left: pos.left
						});

						if(data.content.length > 0){
							optionel.show();
						}else{
							optionel.hide();
							indicator.hide();
						}
						optionel.html('');
						_.each(data.content, function(item) {
							var el=$('
'+item.title+'
').click(function(e) {
								e.stopPropagation();
								e.preventDefault();
								optionel.hide();
								resultel.append(create_autocomplete_item(item, content_type, multiple_status, field_name));
								searchel.val("");
							});
							optionel.append(el);
							indicator.hide();
						});
					})
				)}, 500);
			}
		});
	});

	$(".countchars").each(function() {
		if ($(this).hasClass("countdown")) {
			var max=$(this).attr("max");
			var current=max-$(this).val().length;
			if (current>=0) {
				$(this).after("
"+current+" chars remaining
");
			} else {
				$(this).after("
"+Math.abs(current)+" chars over
");
			}

			$(this).keyup(function() {
				var max=$(this).attr("max");
				var current=max-$(this).val().length;
				if (current>=0) {
					$(this).next().html(current+" chars remaining").removeClass("red");
				} else {
					$(this).next().html(Math.abs(current)+" chars over").addClass("red");
				}
			});
		} else {
			var current=$(this).val().length;
			$(this).after("
"+current+" chars
");
			$(this).keyup(function() {
				current=$(this).val().length;
				$(this).next().html(current+" chars");
			});
		}
		$(this).removeClass("countchars");
	});

	if ($(".wysiwyg").length) {
		//init_tinymce();
		//clearCKEditor();
		initCKEditor();
	}

	var content_type=$(document.body).data('content_type');
	var urlid=$(document.body).data('urlid');
}<commit_msg>Fix problem where images wouldn't return an error<commit_after>
var xhr_reqs = [];

function create_autocomplete_item(item, content_type, multiple_status, field_name){
	var field = { multiple:multiple_status, contenttype: content_type, name: field_name, value: item._id };
	var newel = _.template($('#field-autocomplete-item').html(), { title:item.title, field: field, item:item});
	return newel;
}

function update_content(data) {
	var results_data=_.template($('#'+data.template).html(), data);
	$('#'+data.element).html(results_data);
}

$(function() {
	$(".result_container div a.close").live('click', function(){
		$(this).parent().remove();
	});

	$('
Word count:

').insertAfter(".wordcount");

	$(".wordcount").keyup(function() {
		get_wordcount($(this));
	});

	$(".wordcount").each(function() {
		get_wordcount($(this));
	});

	$(".remover").live("click", function() { //Not sure if this is still used?
		$(this).parent().remove();
		return false;
	});

	$(document).on('keydown', '.datetime_hour', function(e) {
		var key = e.keyCode;
		if ((key > 33) && (key < 47)) {
			return false;
		}
		if ((key > 58) && (key < 126)) {
			return false;
		}
	});

	$(document).on('blur', '.datetime_hour', function() {
		var v = 0;
		if (($(this).val())) {
			v = Number($(this).val());
			$(this).val(leadingZeros(v));
			if ($(this).val().length > 2) {
				var s = $(this).val();
				$(this).val(s.substring(s.length - 2, s.length));
				v = parseInt($(this).val());
			}
			if (v > 23) {
				$(this).val("23");
			}
		} else {
			$(this).val("00");
		}
		if (!isFinite($(this).val())) {
			$(this).val("00");
		}
	});

	$(document).on('blur', '.datetime_minute', function() {
		if ($(this).val()) {
			var v = Number($(this).val());
			$(this).val(leadingZeros(v));
			if ($(this).val().length > 2) {
				var s = $(this).val();
				$(this).val(s.substring(s.length - 2, s.length));
				v = parseInt($(this).val());
			}
			if (v > 59) {
				$(this).val("59");
			}
		} else {
			$(this).val("00");
		}
		if (!isFinite($(this).val())) {
			$(this).val("00");
		}
	});

	$(document).on('keydown', '.datetime_minute', function(e) {
		var key = e.keyCode;
		if ((key > 33) && (key < 47)) {
			return false;
		}
		if ((key > 58) && (key < 126)) {
			return false;
		}
	});

	$(document).on('keyup', '.datetime_change', function() {
		updateDateTime(this);
	});

	$(document).on('change', '.datetime_change', function() {
		updateDateTime(this);
	});

	function updateDateTime(sender) {
		var parent = $(sender).parent();
		var val = "";
		val += parent.children('.datetime_date').val();
		val += " ";
		val += (parent.children('.datetime_hour').val()) ? parent.children('.datetime_hour').val() : "00";
		val += ":";
		val += (parent.children('.datetime_minute').val()) ? parent.children('.datetime_minute').val() : "00";
		$(sender).siblings(':hidden').val(stringToDate(val));
	}

	$(document).on('click', '.deepsearch-search', function() {
		var multiple_status = $(this).prev().attr('multiple');
		var field_name = $(this).prev().attr('fieldname');
		var searchel=$(this).prev();
		var origel = this;
		var search=$(this).prev().val();
		var content_type=$(this).prev().attr("contenttype");
		var optionel=$(this).parent().siblings('.deepsearch-options');
		var resultel=$(this).parent().siblings('.deepsearch-results');
		var indicator = $(this);
		while(xhr_reqs.length>0) {
			jqXHR=xhr_reqs.pop();
			jqXHR.abort();
		}
		indicator.html("Searching...");
		xhr_reqs.push(
			$.getJSON("/api/content", { search: search, content_type: content_type, limit: 20, fields: ["_id", "title"], order_by: "last_modified" }, function(data) {
				var pos = $.extend({}, searchel.offset(), {
		    		height: origel.offsetHeight
				});

				optionel.css({
					top: pos.top + pos.height
					, left: pos.left
				});

				optionel.show();

				optionel.html('');

				_.each(data.content, function(item) {
					var el=$('
'+item.title+'
').click(function(e) {
						e.stopPropagation();
						e.preventDefault();
						optionel.hide();
						resultel.append(create_autocomplete_item(item, content_type, multiple_status, field_name));
						searchel.val("");
					});
					optionel.append(el);
					indicator.html('Search');
				});
			})
		);
	});

	$(document).on('change', 'input[type=file]', function() {
		var files=this.files; //FileList object
		var el=$(this);
		var container=el.parent();
		var multiple = el.attr("data-multiple");
		var contenttype = el.attr("data-contenttype");
		var name = el.attr("data-name");
		container.find('.progress-container').empty();
		_.each(files, function(f, id) {
			var filename = f.name;
			// console.log(f);
			var uid = name + "_" + id;

			$.ajax({
				url: "/api/files/upload?api_key=" + $(document.body).data('api_key') + "&filename="+f.name,  //server script to process data
				type: 'POST',
				xhr: function() {  // custom xhr
					var myXhr = $.ajaxSettings.xhr();
					if (myXhr.upload) { // check if upload property exists
						myXhr.upload.addEventListener('progress', function(data) {
							var percentage = Math.round((data.position / data.total) * 100);
							container.find('.progress-container #' + uid + ' .progress .bar').css('width', percentage + '%');
						}, false); // for handling the progress of the upload
					} // else throw an error here maybe?
					return myXhr;
				},

				//Ajax events
				beforeSend: function(data) {
					container.find('.progress-container').append(_.template($("#field-image-progress").html(), { uid: uid, filename: filename }));
					container.find('.progress-container #' + uid + ' .progress').show();
					container.find('.progress-container #' + uid + '').slideDown();
					container.find('.progress-container .progress .bar').removeClass('bar-success').removeClass('bar-danger');
				},
				success: function(data) {

					if (data.error) {
						container.find('.progress-container #' + uid + ' .progress').hide();
						container.find('.progress-container #' + uid + ' .alert').removeClass('alert-success').addClass('alert-error').html('
File upload failed for '+filename+'
 '+data.message).slideDown(500).delay(2000).slideUp(500);
						container.find('.progress-container #' + uid + ' .progress .bar').removeClass('bar-danger').addClass('bar-success');
						return false;
					}
					var fullname = data.content.full_name;
					var filename = data.content.filename;
					container.find('.progress-container #' + uid + ' .progress').hide();
					container.find('.progress-container #' + uid + ' .alert').addClass('alert-success').removeClass('alert-error').html('File '+ filename +' uploaded').show().delay(1000).slideDown(500).delay(2000).slideUp(500);

					if (multiple == 1) {
						container.find('.preview-image-items').prepend(_.template($("#field-image-item").html(), { value: fullname, field: { value: fullname, name: name, contenttype: contenttype, multiple: multiple } } ));
					} else {
						container.find('.preview-image-items').html(_.template($("#field-image-item").html(), { value: fullname, field: { value: fullname, name: name, contenttype: contenttype, multiple: multiple } } ));
					}
					el.val(""); //Clear the file upload so we don't upload on form submission
				},
				error: function(xhr, s) {
					container.find('.progress-container #' + uid + ' .alert').removeClass('alert-success').addClass('alert-error').html('File upload failed: '+s).slideDown(500).delay(2000).slideUp(500);
					container.find('.progress-container #' + uid + ' .progress .bar').removeClass('bar-success').addClass('bar-danger');
				},
				// Form data
				data: f,
				//Options to tell JQuery not to process data or worry about content-type
				cache: false,
				contentType: false,
				processData: false,
				timeout: 600000 //10 mins
			});
		});
	});

});

function get_wordcount(sender) {
	sender.nextAll(".wordcount_container").first().find(".wordcount_result").load("/workers/ajax_edit/wordcount", {"str": sender.val()});
}

function init_form() {
	$(".chzn-select").chosen();

	$(".my-datepicker").datepicker({ autoclose: true });

	var autocomplete_timer = false;

	$(".autocomplete").each(function(){
		var self = $(this);
		var self_val = '';
		var origel = this;
		self.keyup(function(){
			if ($.trim(self_val) != $.trim(self.val())) {
				self_val = self.val();
				clearTimeout(autocomplete_timer);
				autocomplete_timer = setTimeout(function(){
				var searchel=self.prev();
				var multiple_status = self.attr('multiple');
				var field_name = self.attr('fieldname');
				var search=self.prev().val();
				var optionel=self.parent().siblings('.options');
				var resultel=self.parent().siblings('.result_container');
				var search_content_type = self.attr("contenttypes");
				var url="/api/content/listing/";
				var search = self.val();
				var indicator = self.parent().siblings('.indicator');
				while(xhr_reqs.length>0) {
					jqXHR=xhr_reqs.pop();
					jqXHR.abort();
				}
				indicator.show();
				xhr_reqs.push(
					$.getJSON("/api/content", { search: search, content_type: search_content_type, limit: 20, fields: ["_id", "title"], order_by: "last_modified" }, function(data) {
						var pos = $.extend({}, searchel.offset(), {
							height: origel.offsetHeight
						});

						optionel.css({
							top: pos.top + pos.height
							, left: pos.left
						});

						if(data.content.length > 0){
							optionel.show();
						}else{
							optionel.hide();
							indicator.hide();
						}
						optionel.html('');
						_.each(data.content, function(item) {
							var el=$('
'+item.title+'
').click(function(e) {
								e.stopPropagation();
								e.preventDefault();
								optionel.hide();
								resultel.append(create_autocomplete_item(item, content_type, multiple_status, field_name));
								searchel.val("");
							});
							optionel.append(el);
							indicator.hide();
						});
					})
				)}, 500);
			}
		});
	});

	$(".countchars").each(function() {
		if ($(this).hasClass("countdown")) {
			var max=$(this).attr("max");
			var current=max-$(this).val().length;
			if (current>=0) {
				$(this).after("
"+current+" chars remaining
");
			} else {
				$(this).after("
"+Math.abs(current)+" chars over
");
			}

			$(this).keyup(function() {
				var max=$(this).attr("max");
				var current=max-$(this).val().length;
				if (current>=0) {
					$(this).next().html(current+" chars remaining").removeClass("red");
				} else {
					$(this).next().html(Math.abs(current)+" chars over").addClass("red");
				}
			});
		} else {
			var current=$(this).val().length;
			$(this).after("
"+current+" chars
");
			$(this).keyup(function() {
				current=$(this).val().length;
				$(this).next().html(current+" chars");
			});
		}
		$(this).removeClass("countchars");
	});

	if ($(".wysiwyg").length) {
		//init_tinymce();
		//clearCKEditor();
		initCKEditor();
	}

	var content_type=$(document.body).data('content_type');
	var urlid=$(document.body).data('urlid');
}<|endoftext|>


<commit_before>module.exports = function (grunt) {
  grunt.initConfig({
    clean: ['scratch/'],
    sprite: {
      'default': {
        // TODO: This order is forced due to png/jpg ordering. We should fix this.
        // src: 'test_files/*.{jpg,png}',
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.png',
        destCSS: 'scratch/sprite_positions.styl'
      },
      'jpg,json': {
        // TODO: This order is forced due to png/jpg ordering. We should fix this.
        // src: 'test_files/*.{jpg,png}',
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.jpg',
        destCSS: 'scratch/sprite_positions.json',
        engine: 'gm'
      },
      'overrides': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.overrides.png',
        destCSS: 'scratch/sprite_positions.overrides.styl',
        cssFormat: 'json',
        imgOpts: {
          'format': 'jpg'
        },
        algorithm: 'alt-diagonal',
        engine: 'gm'
      },
      'nested': {
        // TODO: This order is forced due to png/jpg ordering. We should fix this.
        // src: 'test_files/*.{jpg,png}',
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/nested/1/2/spritesheet.png',
        destCSS: 'scratch/3/4/sprite_positions.styl'
      },
      'empty': {
        src: [],
        destImg: 'scratch/empty/sprite.png',
        destCSS: 'scratch/empty/sprite_positions.json'
      },
      'css-opts': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/css_opts/sprite.png',
        destCSS: 'scratch/css_opts/sprite_positions.css',
        cssOpts: {
          cssClass: function (item) {
            return '#container .' + item.name;
          }
        }
      },
      'cssTemplate': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.png',
        destCSS: 'scratch/sprite_positions_custom_template.styl',
        cssTemplate: 'test_files/template.mustache'
      },
      'cssVarMap': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.png',
        destCSS: 'scratch/css_var_map/sprite_positions.styl',
        cssVarMap: function (sprite) {
          sprite.name = sprite.name.replace('sprite', 'icon');
        }
      }
    },
    test: {
      all: '*.test.js'
    }
  });

  grunt.loadTasks('../tasks');

  // Change directories for grunt@0.4
  process.chdir('..');
  grunt.loadNpmTasks('grunt-contrib-clean');
  process.chdir(__dirname);

  grunt.registerTask('default', 'clean sprite test');
};<commit_msg>Starting on cssFunctionTemplate<commit_after>module.exports = function (grunt) {
  grunt.initConfig({
    clean: ['scratch/'],
    sprite: {
      'default': {
        // TODO: This order is forced due to png/jpg ordering. We should fix this.
        // src: 'test_files/*.{jpg,png}',
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.png',
        destCSS: 'scratch/sprite_positions.styl'
      },
      'jpg,json': {
        // TODO: This order is forced due to png/jpg ordering. We should fix this.
        // src: 'test_files/*.{jpg,png}',
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.jpg',
        destCSS: 'scratch/sprite_positions.json',
        engine: 'gm'
      },
      'overrides': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.overrides.png',
        destCSS: 'scratch/sprite_positions.overrides.styl',
        cssFormat: 'json',
        imgOpts: {
          'format': 'jpg'
        },
        algorithm: 'alt-diagonal',
        engine: 'gm'
      },
      'nested': {
        // TODO: This order is forced due to png/jpg ordering. We should fix this.
        // src: 'test_files/*.{jpg,png}',
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/nested/1/2/spritesheet.png',
        destCSS: 'scratch/3/4/sprite_positions.styl'
      },
      'empty': {
        src: [],
        destImg: 'scratch/empty/sprite.png',
        destCSS: 'scratch/empty/sprite_positions.json'
      },
      'css-opts': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/css_opts/sprite.png',
        destCSS: 'scratch/css_opts/sprite_positions.css',
        cssOpts: {
          cssClass: function (item) {
            return '#container .' + item.name;
          }
        }
      },
      'cssFunctionTemplate': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.png',
        destCSS: 'scratch/sprite_positions_custom_template.styl',
        cssTemplate: function () {
          console.log(arguments);
        }
      },
      'cssMustacheTemplate': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.png',
        destCSS: 'scratch/sprite_positions_custom_template.styl',
        cssTemplate: 'test_files/template.mustache'
      },
      'cssVarMap': {
        src: ['test_files/sprite1.png','test_files/sprite2.jpg','test_files/sprite3.png'],
        destImg: 'scratch/sprite.png',
        destCSS: 'scratch/css_var_map/sprite_positions.styl',
        cssVarMap: function (sprite) {
          sprite.name = sprite.name.replace('sprite', 'icon');
        }
      }
    },
    test: {
      all: '*.test.js'
    }
  });

  grunt.loadTasks('../tasks');

  // Change directories for grunt@0.4
  process.chdir('..');
  grunt.loadNpmTasks('grunt-contrib-clean');
  process.chdir(__dirname);

  grunt.registerTask('default', 'clean sprite test');
};<|endoftext|>


<commit_before>(function() {
  var ui = {
    r: null,
    g: null,
    b: null
  };

  var blink1 = undefined;

  function initializeWindow() {
    for (var k in ui) {
      var id = k.replace(/([A-Z])/, '-$1').toLowerCase();
      var element = document.getElementById(id);
      if (!element) {
        throw "Missing UI element: " + k;
      }
      ui[k] = element;
    }
    setGradients();
    enableControls(false);
    ui.r.addEventListener('input', onColorChanged);
    ui.g.addEventListener('input', onColorChanged);
    ui.b.addEventListener('input', onColorChanged);
    enumerateDevices();
  };

  function enableControls(enabled) {
    ui.r.disabled = !enabled;
    ui.g.disabled = !enabled;
    ui.b.disabled = !enabled;
  };

  function enumerateDevices() {
    Blink1.getDevices(onDevicesEnumerated);
  };

  function onDevicesEnumerated(devices) {
    if (devices.length == 0) {
      console.warn("No devices found.");
      return;
    }

    blink1 = devices[0];
    blink1.connect(function(success) {
      if (!success) {
        return;
      }

      blink1.getVersion(function(version) {
        console.log("Hardware version " + version + ".");
        blink1.getRgb(0, function(r, g, b) {
          ui.r.value = r;
          ui.g.value = g;
          ui.b.value = b;
          setGradients();
        });
        enableControls(true);
      });
    });
  };

  function onColorChanged() {
    setGradients();
    blink1.fadeRgb(ui.r.value, ui.g.value, ui.b.value, 250, 0);
  }

  function setGradients() {
    var r = ui.r.value, g = ui.g.value, b = ui.b.value;
    ui.r.style.background =
       'linear-gradient(to right, rgb(0, ' + g + ', ' + b + '), ' +
                                 'rgb(255, ' + g + ', ' + b + '))';
    ui.g.style.background =
       'linear-gradient(to right, rgb(' + r + ', 0, ' + b + '), ' +
                                 'rgb(' + r + ', 255, ' + b + '))';
    ui.b.style.background =
       'linear-gradient(to right, rgb(' + r + ', ' + g + ', 0), ' +
                                 'rgb(' + r + ', ' + g + ', 255))';
  }

  window.addEventListener('load', initializeWindow);
}());
<commit_msg>blink1: Handle undefined results from Blink1.getRgb.<commit_after>(function() {
  var ui = {
    r: null,
    g: null,
    b: null
  };

  var blink1 = undefined;

  function initializeWindow() {
    for (var k in ui) {
      var id = k.replace(/([A-Z])/, '-$1').toLowerCase();
      var element = document.getElementById(id);
      if (!element) {
        throw "Missing UI element: " + k;
      }
      ui[k] = element;
    }
    setGradients();
    enableControls(false);
    ui.r.addEventListener('input', onColorChanged);
    ui.g.addEventListener('input', onColorChanged);
    ui.b.addEventListener('input', onColorChanged);
    enumerateDevices();
  };

  function enableControls(enabled) {
    ui.r.disabled = !enabled;
    ui.g.disabled = !enabled;
    ui.b.disabled = !enabled;
  };

  function enumerateDevices() {
    Blink1.getDevices(onDevicesEnumerated);
  };

  function onDevicesEnumerated(devices) {
    if (devices.length == 0) {
      console.warn("No devices found.");
      return;
    }

    blink1 = devices[0];
    blink1.connect(function(success) {
      if (!success) {
        return;
      }

      blink1.getVersion(function(version) {
        console.log("Hardware version " + version + ".");
        blink1.getRgb(0, function(r, g, b) {
          ui.r.value = r || 0;
          ui.g.value = g || 0;
          ui.b.value = b || 0;
          setGradients();
        });
        enableControls(true);
      });
    });
  };

  function onColorChanged() {
    setGradients();
    blink1.fadeRgb(ui.r.value, ui.g.value, ui.b.value, 250, 0);
  }

  function setGradients() {
    var r = ui.r.value, g = ui.g.value, b = ui.b.value;
    ui.r.style.background =
       'linear-gradient(to right, rgb(0, ' + g + ', ' + b + '), ' +
                                 'rgb(255, ' + g + ', ' + b + '))';
    ui.g.style.background =
       'linear-gradient(to right, rgb(' + r + ', 0, ' + b + '), ' +
                                 'rgb(' + r + ', 255, ' + b + '))';
    ui.b.style.background =
       'linear-gradient(to right, rgb(' + r + ', ' + g + ', 0), ' +
                                 'rgb(' + r + ', ' + g + ', 255))';
  }

  window.addEventListener('load', initializeWindow);
}());
<|endoftext|>


<commit_before>(function () {
	if (typeof define == "function" && define.amd)
		define(["graphjs/Graph"], factory);
	else if (typeof exports == "object")
		module.exports = factory(require("graphjs/Graph"));
	else
		root.Collection = factory(root.Graph);
}(this, function (Graph) {
	return function Collection(Generic) {
		return function(array) {
			return array.map(function (entry) {
				return Graph.parse(Generic, entry);
			});
		}
	};
}));<commit_msg>Fix bug with root parameter<commit_after>(function (root, factory) {
	if (typeof define == "function" && define.amd)
		define(["graphjs/Graph"], factory);
	else if (typeof exports == "object")
		module.exports = factory(require("graphjs/Graph"));
	else
		root.Collection = factory(root.Graph);
}(this, function (Graph) {
	return function Collection(Generic) {
		return function(array) {
			return array.map(function (entry) {
				return Graph.parse(Generic, entry);
			});
		}
	};
}));<|endoftext|>


<commit_before>import chroma from 'chroma-js';

function interpolator(type) {
  switch (type) {
    case 'HCL': return (start, end) => chroma.scale([start, end])
      .mode('hcl');
    case 'BEZIER':
    default: return (start, end) => chroma.bezier([start, end])
      .scale();
  }
}

// Returns a function that takes a value from 0 to 1
function createInterpolator(interpolatorType, start, end) {
  if (!interpolatorType) return interpolator()(start, end);
  return interpolator(interpolatorType)(start, end);
}

function createScale (start, end) {
  return createInterpolator(null , start, end);
}

// amount is 0 to 1
// function mix (a, b, amount) {
//   return a*(1-amount) + b*amount;
// }

function mix (themeScale, scaleAmount, fromColor) {
  let luminosityDiffThreshold = 20; // minimum difference to keep between bg and fg
  let minChroma = 25;

  let startL = chroma(themeScale(0)).get('hcl.l');
  let endL = chroma(themeScale(1)).get('hcl.l');
  let minL = Math.min(startL, endL);
  let maxL = Math.max(startL, endL);

  luminosityDiffThreshold = Math.max(Math.abs(startL - endL) / 2, luminosityDiffThreshold);

  // Midpoint of luminosity between the two colors;
  let toMatchColor = chroma(themeScale(scaleAmount));

  let c = Math.max(
    (
      chroma(themeScale(0)).get('hcl.c') +
      chroma(themeScale(1)).get('hcl.c') +
      chroma(fromColor).get('hcl.c') +
      toMatchColor.get('hcl.c')
    ) / 4,
    minChroma
  );
  // c = 40;

  let toMatchL = toMatchColor.get('hcl.l');

  // if (minL - luminosityDiffThreshold <= 0) {
  if (toMatchL - luminosityDiffThreshold <= minL) {
    // Mininal difference (prefer lighter)
    var minDiffLuminosity = toMatchL > 100 - luminosityDiffThreshold
      ? toMatchL - luminosityDiffThreshold
      : toMatchL + luminosityDiffThreshold;

  } else {
    // Minimal difference (prefer darker)
    var minDiffLuminosity = toMatchL <= 0
      ? toMatchL + luminosityDiffThreshold
      : toMatchL - luminosityDiffThreshold;
  }

  let color =  chroma.hcl(chroma(fromColor).get('hcl.h'), c, minDiffLuminosity);
  return color;
}

module.exports = {
  createInterpolator,
  mix,
  createScale
};
<commit_msg>Add color lightness correction because it kinda helps I guess<commit_after>import chroma from 'chroma-js';

function interpolator(type) {
  switch (type) {
    case 'HCL': return (start, end) => chroma.scale([start, end])
      .mode('hcl')
      .correctLightness();
    case 'BEZIER':
    default: return (start, end) => chroma.bezier([start, end])
      .scale()
      .correctLightness();
  }
}

// Returns a function that takes a value from 0 to 1
function createInterpolator(interpolatorType, start, end) {
  if (!interpolatorType) return interpolator()(start, end);
  return interpolator(interpolatorType)(start, end);
}

function createScale (start, end) {
  return createInterpolator(null , start, end);
}

// amount is 0 to 1
// function mix (a, b, amount) {
//   return a*(1-amount) + b*amount;
// }

function mix (themeScale, scaleAmount, fromColor) {
  let luminosityDiffThreshold = 20; // minimum difference to keep between bg and fg
  let minChroma = 25;

  let startL = chroma(themeScale(0)).get('hcl.l');
  let endL = chroma(themeScale(1)).get('hcl.l');
  let minL = Math.min(startL, endL);
  let maxL = Math.max(startL, endL);

  luminosityDiffThreshold = Math.max(Math.abs(startL - endL) / 2, luminosityDiffThreshold);

  // Midpoint of luminosity between the two colors;
  let toMatchColor = chroma(themeScale(scaleAmount));

  let c = Math.max(
    (
      chroma(themeScale(0)).get('hcl.c') +
      chroma(themeScale(1)).get('hcl.c') +
      chroma(fromColor).get('hcl.c') +
      toMatchColor.get('hcl.c')
    ) / 4,
    minChroma
  );
  // c = 40;

  let toMatchL = toMatchColor.get('hcl.l');

  // if (minL - luminosityDiffThreshold <= 0) {
  if (toMatchL - luminosityDiffThreshold <= minL) {
    // Mininal difference (prefer lighter)
    var minDiffLuminosity = toMatchL > 100 - luminosityDiffThreshold
      ? toMatchL - luminosityDiffThreshold
      : toMatchL + luminosityDiffThreshold;

  } else {
    // Minimal difference (prefer darker)
    var minDiffLuminosity = toMatchL <= 0
      ? toMatchL + luminosityDiffThreshold
      : toMatchL - luminosityDiffThreshold;
  }

  let color =  chroma.hcl(chroma(fromColor).get('hcl.h'), c, minDiffLuminosity);
  return color;
}

module.exports = {
  createInterpolator,
  mix,
  createScale
};
<|endoftext|>


<commit_before>import fs   from 'fs';
import path from 'path';

/**
 * Defines the data used by typhonjs-config-resolver to validate TJSDocConfig files including loading extended configs.
 */
export default class ConfigData
{
   /**
    * Creates the common TJSDoc config resolver data for default values and pre / post validation in addition to
    * mixing in any data from the callee.
    *
    * @param {EventProxy}           eventbus - An eventbus proxy.
    *
    * @param {ConfigResolverData}   mixin - An object structured as ConfigResolverData.
    *
    * @returns {ConfigResolverData}
    */
   static createResolverData(eventbus, mixin = {})
   {
      if (typeof mixin !== 'object') { throw new TypeError(`'mixin' is not an 'object'.`); }

      const defaultValues = ConfigData.defaultValues(eventbus);
      const preValidate = ConfigData.preValidate(eventbus);
      const postValidate = ConfigData.postValidate(eventbus);
      const upgradeMergeList = ConfigData.upgradeMergeList();

      return {
         defaultValues: typeof mixin.defaultValues === 'object' ? Object.assign(defaultValues, mixin.defaultValues) :
          defaultValues,

         preValidate: typeof mixin.preValidate === 'object' ? Object.assign(preValidate, mixin.preValidate) :
          preValidate,

         postValidate: typeof mixin.postValidate === 'object' ? Object.assign(postValidate, mixin.postValidate) :
          postValidate,

         upgradeMergeList: Array.isArray(mixin.upgradeMergeList) ? [...upgradeMergeList, ...mixin.upgradeMergeList] :
          upgradeMergeList
      };
   }

   /**
    * Generates the default values data structure set to a TJSDocConfig object after extended config files are resolved.
    * Any fields not already set will be set to the default values defined before.
    *
    * @returns {object}
    */
   static defaultValues()
   {
      return {
         'access': ['public', 'protected', 'private'],

         'autoPrivate': true,

         'builtinVirtual': true,

         'compactData': false,

         'compressData': false,

         'compressOutput': false,

         'compressFormat': 'tar.gz',

         'copyPackage': true,

         'debug': false,

         'docCoverage': true,

         'docLint': true,

         'emptyDestination': false,

         'excludes': [],

         'fullStackTrace': false,

         'includeSource': false,

         'index': './README.md',

         'logLevel': 'info',

         'outputASTData': false,

         'outputDocData': false,

         'package': './package.json',

         'plugins': [],

         'removeCommonPath': false,

         'separateDataArchives': false,

         'test.excludes': [],

         'undocumentIdentifier': true,

         'unexportIdentifier': false
      };
   }

   /**
    * Generates the post-validation data structure for bulk checking a TJSDocConfig object. If a field is present it will
    * be validated otherwise no particular fields are checked.
    *
    * @param {EventProxy}  eventbus - The plugin manager eventbus proxy.
    *
    * @returns {object}
    */
   static postValidate(eventbus)
   {
      const preValidateData = ConfigData.preValidate(eventbus);

      return Object.assign({}, preValidateData,
      {
         // Ensures that destination when resolved is a directory or that the parent directory exists and destination
         // doesn't exist.
         destination: { required: true, test: 'entry', type: 'string', expected: (entry) =>
         {
            const resolvedPath = path.resolve(entry);

            let resolvedParentPath = path.dirname(resolvedPath);

            // If the resolved path directory exists then destination is valid.
            try { if (fs.statSync(resolvedPath).isDirectory()) { return true; } }
            catch (err) { /* nop */ }

               // Allow parent depth of 3 levels back from top level parent.
               for (let cntr = 3; --cntr >= 0;)
               {
                  try
                  {
                     if (fs.statSync(resolvedParentPath).isDirectory())
                     {
                        if (!fs.existsSync(resolvedPath)) { return true; }
                     }
                  }
                  catch (err) { /* nop */ }

                  resolvedParentPath = path.dirname(resolvedParentPath);
               }

            return false;
         }, message: 'invalid directory' },

         publisher: { required: false, test: 'entry', expected:
          (entry) => (typeof entry === 'string' || typeof entry === 'object') }
      });
   }

   /**
    * Generates the pre-validation data structure for bulk checking a TJSDocConfig object. If a field is present it will
    * be validated otherwise no particular fields are checked.
    *
    * @param {EventProxy}  eventbus - The plugin manager eventbus proxy.
    *
    * @returns {object}
    */
   static preValidate(eventbus)
   {
      return {
         'access': { required: false, test: 'array', expected: ['private', 'protected', 'public'] },

         'autoPrivate': { required: false, test: 'entry', type: 'boolean' },

         'builtinVirtual': { required: false, test: 'entry', type: 'boolean' },

         'compactData': { required: false, test: 'entry', type: 'boolean' },

         'compressData': { required: false, test: 'entry', type: 'boolean' },

         'compressFormat': { required: false, test: 'entry', expected: ['tar.gz', 'zip'] },

         'compressOutput': { required: false, test: 'entry', type: 'boolean' },

         'copyPackage': { required: false, test: 'entry', type: 'boolean' },

         'debug': { required: false, test: 'entry', type: 'boolean' },

         'destination': { required: false, test: 'entry|array', type: 'string' },

         'docCoverage': { required: false, test: 'entry', type: 'boolean' },

         'docLint': { required: false, test: 'entry', type: 'boolean' },

         'excludes': { required: false, test: 'array', expected: (entry) => new RegExp(entry) },

         'emptyDestination': { required: false, test: 'entry', type: 'boolean' },

         'extends': { required: false, test: 'entry|array', expected: 'string' },

         'fullStackTrace': { required: false, test: 'entry', type: 'boolean' },

         'includeSource': { required: false, test: 'entry', type: 'boolean' },

         'index': { required: false, test: 'entry', type: 'string' },

         'logLevel': { required: false, test: 'entry', expected:
          (entry) => eventbus.triggerSync('log:level:is:valid', entry), message: 'invalid log level' },

         'outputASTData': { required: false, test: 'entry', type: 'boolean' },

         'outputDocData': { required: false, test: 'entry', type: 'boolean' },

         'package': { required: false, test: 'entry', type: 'string' },

         'plugins': { required: false, test: 'array', expected:
          (entry) => eventbus.triggerSync('plugins:is:valid:config', entry), message: 'invalid plugin config' },

         'publisher': { required: false, test: 'entry', expected:
          (entry) => (typeof entry === 'string' || typeof entry === 'object') && entry !== null },

         'scripts': { required: false, test: 'array', type: 'string' },

         'separateDataArchives': { required: false, test: 'entry', type: 'boolean' },

         'source': { required: false, test: 'entry|array', type: 'string' },

         'sourceFiles': { required: false, test: 'array', type: 'string' },

         'styles': { required: false, test: 'array', type: 'string' },

         'test': { required: false, test: 'entry', expected: (entry) => entry !== null && typeof entry === 'object' },

         'test.excludes': { required: false, test: 'array', expected: (entry) => new RegExp(entry) },

         'test.includes': { required: false, test: 'array', expected: (entry) => new RegExp(entry) },

         'test.source': { required: false, test: 'entry|array', type: 'string' },

         'test.sourceFiles': { required: false, test: 'array', type: 'string' },

         'test.type': { required: false, test: 'entry', expected: new Set(['mocha']) },

         'undocumentIdentifier': { required: false, test: 'entry', type: 'boolean' },

         'unexportIdentifier': { required: false, test: 'entry', type: 'boolean' }
      };
   }

   /**
    * Returns config keys that are a string and are upgraded to an array or are already an array to be merged.
    *
    * @returns {Array<string>}
    */
   static upgradeMergeList()
   {
      return [
         'access',
         'excludes',
         'extends',
         'includes',
         'pathExtensions',
         'plugins',
         'scripts',
         'source',
         'sourceFiles',
         'styles'
      ];
   }
}

<commit_msg>unexportIdentifier defaults to true.<commit_after>import fs   from 'fs';
import path from 'path';

/**
 * Defines the data used by typhonjs-config-resolver to validate TJSDocConfig files including loading extended configs.
 */
export default class ConfigData
{
   /**
    * Creates the common TJSDoc config resolver data for default values and pre / post validation in addition to
    * mixing in any data from the callee.
    *
    * @param {EventProxy}           eventbus - An eventbus proxy.
    *
    * @param {ConfigResolverData}   mixin - An object structured as ConfigResolverData.
    *
    * @returns {ConfigResolverData}
    */
   static createResolverData(eventbus, mixin = {})
   {
      if (typeof mixin !== 'object') { throw new TypeError(`'mixin' is not an 'object'.`); }

      const defaultValues = ConfigData.defaultValues(eventbus);
      const preValidate = ConfigData.preValidate(eventbus);
      const postValidate = ConfigData.postValidate(eventbus);
      const upgradeMergeList = ConfigData.upgradeMergeList();

      return {
         defaultValues: typeof mixin.defaultValues === 'object' ? Object.assign(defaultValues, mixin.defaultValues) :
          defaultValues,

         preValidate: typeof mixin.preValidate === 'object' ? Object.assign(preValidate, mixin.preValidate) :
          preValidate,

         postValidate: typeof mixin.postValidate === 'object' ? Object.assign(postValidate, mixin.postValidate) :
          postValidate,

         upgradeMergeList: Array.isArray(mixin.upgradeMergeList) ? [...upgradeMergeList, ...mixin.upgradeMergeList] :
          upgradeMergeList
      };
   }

   /**
    * Generates the default values data structure set to a TJSDocConfig object after extended config files are resolved.
    * Any fields not already set will be set to the default values defined before.
    *
    * @returns {object}
    */
   static defaultValues()
   {
      return {
         'access': ['public', 'protected', 'private'],

         'autoPrivate': true,

         'builtinVirtual': true,

         'compactData': false,

         'compressData': false,

         'compressOutput': false,

         'compressFormat': 'tar.gz',

         'copyPackage': true,

         'debug': false,

         'docCoverage': true,

         'docLint': true,

         'emptyDestination': false,

         'excludes': [],

         'fullStackTrace': false,

         'includeSource': false,

         'index': './README.md',

         'logLevel': 'info',

         'outputASTData': false,

         'outputDocData': false,

         'package': './package.json',

         'plugins': [],

         'removeCommonPath': false,

         'separateDataArchives': false,

         'test.excludes': [],

         'undocumentIdentifier': true,

         'unexportIdentifier': true
      };
   }

   /**
    * Generates the post-validation data structure for bulk checking a TJSDocConfig object. If a field is present it will
    * be validated otherwise no particular fields are checked.
    *
    * @param {EventProxy}  eventbus - The plugin manager eventbus proxy.
    *
    * @returns {object}
    */
   static postValidate(eventbus)
   {
      const preValidateData = ConfigData.preValidate(eventbus);

      return Object.assign({}, preValidateData,
      {
         // Ensures that destination when resolved is a directory or that the parent directory exists and destination
         // doesn't exist.
         destination: { required: true, test: 'entry', type: 'string', expected: (entry) =>
         {
            const resolvedPath = path.resolve(entry);

            let resolvedParentPath = path.dirname(resolvedPath);

            // If the resolved path directory exists then destination is valid.
            try { if (fs.statSync(resolvedPath).isDirectory()) { return true; } }
            catch (err) { /* nop */ }

               // Allow parent depth of 3 levels back from top level parent.
               for (let cntr = 3; --cntr >= 0;)
               {
                  try
                  {
                     if (fs.statSync(resolvedParentPath).isDirectory())
                     {
                        if (!fs.existsSync(resolvedPath)) { return true; }
                     }
                  }
                  catch (err) { /* nop */ }

                  resolvedParentPath = path.dirname(resolvedParentPath);
               }

            return false;
         }, message: 'invalid directory' },

         publisher: { required: false, test: 'entry', expected:
          (entry) => (typeof entry === 'string' || typeof entry === 'object') }
      });
   }

   /**
    * Generates the pre-validation data structure for bulk checking a TJSDocConfig object. If a field is present it will
    * be validated otherwise no particular fields are checked.
    *
    * @param {EventProxy}  eventbus - The plugin manager eventbus proxy.
    *
    * @returns {object}
    */
   static preValidate(eventbus)
   {
      return {
         'access': { required: false, test: 'array', expected: ['private', 'protected', 'public'] },

         'autoPrivate': { required: false, test: 'entry', type: 'boolean' },

         'builtinVirtual': { required: false, test: 'entry', type: 'boolean' },

         'compactData': { required: false, test: 'entry', type: 'boolean' },

         'compressData': { required: false, test: 'entry', type: 'boolean' },

         'compressFormat': { required: false, test: 'entry', expected: ['tar.gz', 'zip'] },

         'compressOutput': { required: false, test: 'entry', type: 'boolean' },

         'copyPackage': { required: false, test: 'entry', type: 'boolean' },

         'debug': { required: false, test: 'entry', type: 'boolean' },

         'destination': { required: false, test: 'entry|array', type: 'string' },

         'docCoverage': { required: false, test: 'entry', type: 'boolean' },

         'docLint': { required: false, test: 'entry', type: 'boolean' },

         'excludes': { required: false, test: 'array', expected: (entry) => new RegExp(entry) },

         'emptyDestination': { required: false, test: 'entry', type: 'boolean' },

         'extends': { required: false, test: 'entry|array', expected: 'string' },

         'fullStackTrace': { required: false, test: 'entry', type: 'boolean' },

         'includeSource': { required: false, test: 'entry', type: 'boolean' },

         'index': { required: false, test: 'entry', type: 'string' },

         'logLevel': { required: false, test: 'entry', expected:
          (entry) => eventbus.triggerSync('log:level:is:valid', entry), message: 'invalid log level' },

         'outputASTData': { required: false, test: 'entry', type: 'boolean' },

         'outputDocData': { required: false, test: 'entry', type: 'boolean' },

         'package': { required: false, test: 'entry', type: 'string' },

         'plugins': { required: false, test: 'array', expected:
          (entry) => eventbus.triggerSync('plugins:is:valid:config', entry), message: 'invalid plugin config' },

         'publisher': { required: false, test: 'entry', expected:
          (entry) => (typeof entry === 'string' || typeof entry === 'object') && entry !== null },

         'scripts': { required: false, test: 'array', type: 'string' },

         'separateDataArchives': { required: false, test: 'entry', type: 'boolean' },

         'source': { required: false, test: 'entry|array', type: 'string' },

         'sourceFiles': { required: false, test: 'array', type: 'string' },

         'styles': { required: false, test: 'array', type: 'string' },

         'test': { required: false, test: 'entry', expected: (entry) => entry !== null && typeof entry === 'object' },

         'test.excludes': { required: false, test: 'array', expected: (entry) => new RegExp(entry) },

         'test.includes': { required: false, test: 'array', expected: (entry) => new RegExp(entry) },

         'test.source': { required: false, test: 'entry|array', type: 'string' },

         'test.sourceFiles': { required: false, test: 'array', type: 'string' },

         'test.type': { required: false, test: 'entry', expected: new Set(['mocha']) },

         'undocumentIdentifier': { required: false, test: 'entry', type: 'boolean' },

         'unexportIdentifier': { required: false, test: 'entry', type: 'boolean' }
      };
   }

   /**
    * Returns config keys that are a string and are upgraded to an array or are already an array to be merged.
    *
    * @returns {Array<string>}
    */
   static upgradeMergeList()
   {
      return [
         'access',
         'excludes',
         'extends',
         'includes',
         'pathExtensions',
         'plugins',
         'scripts',
         'source',
         'sourceFiles',
         'styles'
      ];
   }
}

<|endoftext|>


<commit_before>/**
 * Created by truthlighting on 9/20/2016.
 */
/**
 * This guys does the other half of energy collection. The miner gets it from the source, and the helper does the
 * transportation. We don't want them just going for the nearest source, as that means that if we have more than one
 * miner, all the helpers will only go for the first miner. To counter this, we assign them to a miner the same way
 * we assign a miner to a source
 */

var helper = {
    parts: [
        [MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY, MOVE, CARRY]
    ],

    assignMiner: function () {
        var creep = this.creep;

        var miner = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (miner) {
                if (miner.memory.role == 'miner' && miner.memory.helpers.length < miner.memory.helpersNeeded)
                    return true;

                return false;
            }
        });

        if (miner == undefined)
            return;

        creep.memory.miner = miner.id;
        miner.memory.helpers.push(creep.id);
    },

    /**
     * @TODO: Make helpers smarter about avoiding miners, instead of just waiting till they're 5 tiles away
     * @TODO: When spawns are at .25, and extensions have >= 200, help builders before filling shit up
     */
    action: function () {
        var creep = this.creep;

        if (creep.memory.courier !== undefined && creep.memory.courier == true) {
            creep.memory.courier = false;
            return;
        }

        //If this helper isn't assigned to a miner, find one and assign him to it. If it is assigned to a miner,
        //then find that miner by his id
        if (creep.memory.miner == undefined)
            this.assignMiner();

        var miner = Game.getObjectById(creep.memory.miner);

        if (miner == null) {
            creep.suicide();
            return;
        }
        //console.log("i'm here1");
        //If we can still pick up energy, let's do that
        //console.log("miner: " + miner);
        //console.log("creep:" + creep);
        //console.log("creep.carry: (" + _.sum(creep.carry) + ") < creep.carryCapacity (" + creep.carryCapacity + ")");
        //console.log(_.sum(creep.carry) < creep.carryCapacity);
        if (_.sum(creep.carry) < creep.carryCapacity) {
            //console.log("i'm here");
            if (creep.pos.isNearTo(miner)) {
                var energy = creep.pos.findInRange(FIND_DROPPED_ENERGY, 1)[0];
                //console.log("energy: " + energy);
                creep.pickup(energy);
            }
            else {
                if (miner.memory.isNearSource)
                    creep.moveTo(miner);
            }

            return;
        }

        var target = null;
        //console.log("I'm here");
        //Okay, everything below is for dropping energy off

        if (!target) {
            //var spawn = creep.pos.findClosestByPath(FIND_MY_SPAWNS);
            var spawn = creep.room.find(FIND_STRUCTURES, {
                            filter: (structure) => {
                                return (structure.structureType == STRUCTURE_EXTENSION ||
                                structure.structureType == STRUCTURE_SPAWN) &&
                //            structure.structureType == STRUCTURE_TOWER) &&
                                (structure.energy < structure.energyCapacity);
                            }
            })

            //If we found it, set it as our target
            if (spawn)
                target = spawn;
        }
        //console.log("I'm here1");
        //Let's get the direction we want to go in
        var targetDirection = creep.pos.findPathTo(target, { ignoreCreeps: true })[0].direction;

        //Let's look for a courier in that direction. We'll check on making sure they're the right
        //role, if they can hold any energy, if they're in range and if they're in the same direction
        var leftDir = targetDirection - 1;
        var rightDir = targetDirection + 1;

        if (leftDir < 1)
            leftDir += 8;
        if (leftDir > 8)
            leftDir -= 8;

        if (rightDir < 1)
            rightDir += 8;
        if (rightDir > 8)
            rightDir -= 8;
        console.log("I'm here 2");
        var courier = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (possibleTarget) {
                return (
                    possibleTarget.memory.role == creep.memory.role
//					&& possibleTarget.memory.miner == creep.memory.miner
                    && _.sum(possibleTarget.carry) < possibleTarget.carryCapacity
                    && creep.pos.inRangeTo(possibleTarget, 1)
                    && (
                        creep.pos.getDirectionTo(possibleTarget) == targetDirection
                        || creep.pos.getDirectionTo(possibleTarget) == leftDir
                        || creep.pos.getDirectionTo(possibleTarget) == rightDir
                    )
                );
            }
        });
        console.log("im here");
        //If we found a courier, make that courier our new target
        if (courier !== null && !creep.pos.isNearTo(target)) {
            target = courier;
            target.memory.courier = true;
        }
        console.log("target: " + target);
        //If we're near to the target, either give it our energy or drop it
        if (creep.pos.isNearTo(target)) {
            if (_.sum(target.carry) < target.carryCapacity) {
                creep.transfer(target, RESOURCE_ENERGY);
            }
            else
                creep.drop(RESOURCE_ENERGY);
        }
        //Let's do the moving
        else {
            creep.moveTo(target);
        }
    }
};

module.exports = helper;<commit_msg>fixing miner<commit_after>/**
 * Created by truthlighting on 9/20/2016.
 */
/**
 * This guys does the other half of energy collection. The miner gets it from the source, and the helper does the
 * transportation. We don't want them just going for the nearest source, as that means that if we have more than one
 * miner, all the helpers will only go for the first miner. To counter this, we assign them to a miner the same way
 * we assign a miner to a source
 */

var helper = {
    parts: [
        [MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY, MOVE, CARRY]
    ],

    assignMiner: function () {
        var creep = this.creep;

        var miner = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (miner) {
                if (miner.memory.role == 'miner' && miner.memory.helpers.length < miner.memory.helpersNeeded)
                    return true;

                return false;
            }
        });

        if (miner == undefined)
            return;

        creep.memory.miner = miner.id;
        miner.memory.helpers.push(creep.id);
    },

    /**
     * @TODO: Make helpers smarter about avoiding miners, instead of just waiting till they're 5 tiles away
     * @TODO: When spawns are at .25, and extensions have >= 200, help builders before filling shit up
     */
    action: function () {
        var creep = this.creep;

        if (creep.memory.courier !== undefined && creep.memory.courier == true) {
            creep.memory.courier = false;
            return;
        }

        //If this helper isn't assigned to a miner, find one and assign him to it. If it is assigned to a miner,
        //then find that miner by his id
        if (creep.memory.miner == undefined)
            this.assignMiner();

        var miner = Game.getObjectById(creep.memory.miner);

        if (miner == null) {
            creep.suicide();
            return;
        }
        //console.log("i'm here1");
        //If we can still pick up energy, let's do that
        //console.log("miner: " + miner);
        //console.log("creep:" + creep);
        //console.log("creep.carry: (" + _.sum(creep.carry) + ") < creep.carryCapacity (" + creep.carryCapacity + ")");
        //console.log(_.sum(creep.carry) < creep.carryCapacity);
        if (_.sum(creep.carry) < creep.carryCapacity) {
            //console.log("i'm here");
            if (creep.pos.isNearTo(miner)) {
                var energy = creep.pos.findInRange(FIND_DROPPED_ENERGY, 1)[0];
                //console.log("energy: " + energy);
                creep.pickup(energy);
            }
            else {
                if (miner.memory.isNearSource)
                    creep.moveTo(miner);
            }

            return;
        }

        var target = null;
        //console.log("I'm here");
        //Okay, everything below is for dropping energy off

        if (!target) {
            //var spawn = creep.pos.findClosestByPath(FIND_MY_SPAWNS);
            var spawn = creep.room.find(FIND_STRUCTURES, {
                            filter: (structure) => {
                                return (structure.structureType == STRUCTURE_EXTENSION ||
                                structure.structureType == STRUCTURE_SPAWN) &&
                //            structure.structureType == STRUCTURE_TOWER) &&
                                (structure.energy < structure.energyCapacity);
                            }
            })

            //If we found it, set it as our target
            if (spawn)
                target = spawn;
        }
        //console.log("I'm here1");
        //Let's get the direction we want to go in
        var targetDirection = creep.pos.findPathTo(target, { ignoreCreeps: true })[0].direction;
        console.log("I'm here 3");
        //Let's look for a courier in that direction. We'll check on making sure they're the right
        //role, if they can hold any energy, if they're in range and if they're in the same direction
        var leftDir = targetDirection - 1;
        var rightDir = targetDirection + 1;

        if (leftDir < 1)
            leftDir += 8;
        if (leftDir > 8)
            leftDir -= 8;

        if (rightDir < 1)
            rightDir += 8;
        if (rightDir > 8)
            rightDir -= 8;
        console.log("I'm here 2");
        var courier = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (possibleTarget) {
                return (
                    possibleTarget.memory.role == creep.memory.role
//					&& possibleTarget.memory.miner == creep.memory.miner
                    && _.sum(possibleTarget.carry) < possibleTarget.carryCapacity
                    && creep.pos.inRangeTo(possibleTarget, 1)
                    && (
                        creep.pos.getDirectionTo(possibleTarget) == targetDirection
                        || creep.pos.getDirectionTo(possibleTarget) == leftDir
                        || creep.pos.getDirectionTo(possibleTarget) == rightDir
                    )
                );
            }
        });
        console.log("im here");
        //If we found a courier, make that courier our new target
        if (courier !== null && !creep.pos.isNearTo(target)) {
            target = courier;
            target.memory.courier = true;
        }
        console.log("target: " + target);
        //If we're near to the target, either give it our energy or drop it
        if (creep.pos.isNearTo(target)) {
            if (_.sum(target.carry) < target.carryCapacity) {
                creep.transfer(target, RESOURCE_ENERGY);
            }
            else
                creep.drop(RESOURCE_ENERGY);
        }
        //Let's do the moving
        else {
            creep.moveTo(target);
        }
    }
};

module.exports = helper;<|endoftext|>


<commit_before>import includePaths from 'rollup-plugin-includepaths';
import cjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import analyze from 'rollup-analyzer-plugin';

export default {
  name: `Alter`,
  input: `src/index.js`,
  output: {
    file: `docs/script.js`,
    format: `iife`,
    sourcemap: false
  },

  plugins: [
    includePaths({
      include: {},
      paths: [`src`],
      external: [],
      extensions: [`.js`]
    }),
    cjs({
      sourceMap: false
    }),
    resolve(),
    analyze()
  ],
};
<commit_msg>Remove unused<commit_after>import includePaths from 'rollup-plugin-includepaths';
import resolve from 'rollup-plugin-node-resolve';
import analyze from 'rollup-analyzer-plugin';

export default {
  name: `Alter`,
  input: `src/index.js`,
  output: {
    file: `docs/script.js`,
    format: `iife`,
    sourcemap: false
  },

  plugins: [
    includePaths({
      include: {},
      paths: [`src`],
      external: [],
      extensions: [`.js`]
    }),
    resolve(),
    analyze()
  ],
};
<|endoftext|>


<commit_before>import AllEntities from '../entities/all-entities';

export default class BattleState extends Phaser.State {
    constructor (game) {
        super(game);

        this.allEntities = new AllEntities();
    }

    init () {
        this.heroes = [
            {
                "attack": 30,
                "defense": 30,
                "hitPoints": 3000,
                "speed": 30,
            }, // new Entity()
        ];
        this.enemies = [
            {
                "attack": 20,
                "defense": 20,
                "hitPoints": 2000,
                "speed": 20,
            }, // new Entity()
        ];
        this.moveEnergy = 100;
        this.tickLength = 3000; // milliseconds
        this.tick = int(new Date.getTime() / this.tickLength);
        this.step()
    }

    preload () {
        this.game.load.atlas('mobs', '/assets/images/mobs_spritesheet.png', null, this.game.cache.getJSON('mobsJSON'), Phaser.Loader.TEXTURE_ATLAS_JSON_HASH);
    }

    create () {
        let ghost = new this.allEntities.mobHash.Ghost(this.game, 0, 0);

        this.game.add.existing(ghost);
    }
    update () {
        let tick = int(new Date.getTime() / this.tickLength);
        if (tick > this.tick) {
            this.step();
        }
    }

    step () {
        for (hero of this.heroes) {
            hero.energy += hero.speed;
            if (hero.speed >= this.moveEnergy) {
                hero.attack(enemies[0]);
            }
        }
        for (enemy of this.enemies) {
            enemy.energy += enemy.speed;
            if (enemy.speed >= this.moveEnergy) {
                enemy.attack(heroes[0]);
            }
        }

        console.log('===========');
        console.log('this.tick: ' + this.tick);
        console.log('this.heroes: ' + this.heroes);
        console.log('this.enemies: ' + this.enemies);
        console.log('===========');
        console.log('');
    }

    roll (max) {
        Math.floor(Math.random() * max) + 1;
    }

    attack (attacker, defender) {
        console.log(attacker + ' attacks ' + defender);
    }
}
<commit_msg>fixed timer<commit_after>import AllEntities from '../entities/all-entities';

export default class BattleState extends Phaser.State {
    constructor (game) {
        super(game);

        this.allEntities = new AllEntities();
    }

    init () {
        this.heroes = [
            {
                "attack": 30,
                "defense": 30,
                "hitPoints": 3000,
                "speed": 30,
            }, // new Entity()
        ];
        this.enemies = [
            {
                "attack": 20,
                "defense": 20,
                "hitPoints": 2000,
                "speed": 20,
            }, // new Entity()
        ];
        this.moveEnergy = 100;
    }

    preload () {
        this.game.load.atlas('mobs', '/assets/images/mobs_spritesheet.png', null, this.game.cache.getJSON('mobsJSON'), Phaser.Loader.TEXTURE_ATLAS_JSON_HASH);
    }

    create () {
        let ghost = new this.allEntities.mobHash.Ghost(this.game, 0, 0);

        this.game.add.existing(ghost);

        this.game.time.events.loop(Phaser.Timer.SECOND * 3, this.step, this);
    }

    step () {
        for (let hero of this.heroes) {
            hero.energy += hero.speed;
            if (hero.speed >= this.moveEnergy) {
                hero.attack(enemies[0]);
            }
        }
        for (let enemy of this.enemies) {
            enemy.energy += enemy.speed;
            if (enemy.speed >= this.moveEnergy) {
                enemy.attack(heroes[0]);
            }
        }

        console.log('===========');
        console.log('this.heroes: ', this.heroes);
        console.log('this.enemies: ',  this.enemies);
        console.log('===========');
        console.log('');
    }

    roll (max) {
        Math.floor(Math.random() * max) + 1;
    }

    attack (attacker, defender) {
        console.log(attacker + ' attacks ' + defender);
    }
}
<|endoftext|>


<commit_before>var async = require("async");
var fs = require("fs");
var path = require("path");
var chalk = require("chalk");
var gzip = require("zlib").gzip;
var mime = require("mime");
var join = function() {
  return path.join.apply(path, arguments).replace(/\\/g, "/");
};

var aws = require("aws-sdk");

var formatSize = function(input) {
  if (input > 1024 * 1024) {
    return Math.round(input * 10 / (1024 * 1024)) / 10 + "MB";
  }
  if (input > 1024) {
    return Math.round(input / 1024) + "KB";
  }
  return input + "B";
};

var gzippable = ["js", "html", "json", "map", "css", "txt"];

module.exports = function(grunt) {

  var config = require("../project.json");

  var findBuiltFiles = function() {
    var pattern = ["**/*"];
    var embargo = config.embargo;
    if (embargo) {
      if (!(embargo instanceof Array)) embargo = [embargo];
      embargo.forEach(function(item) {
        pattern.push("!" + item);
        console.log(chalk.bgRed.white("File embargoed: %s"), item);
      });
    }
    var files = grunt.file.expand({ cwd: "build", filter: "isFile" }, pattern);
    var list = files.map(function(file) {
      var buffer = fs.readFileSync(path.join("build", file));
      return {
        path: file,
        buffer: buffer
      };
    });
    return list;
  };

  grunt.registerTask("publish", "Pushes the build folder to S3", function(deploy) {

    var done = this.async();

    deploy = deploy || "stage";

    if (deploy == "simulated") {
      var uploads = findBuiltFiles();
      async.each(uploads, function(upload, c) {
        var extension = upload.path.split(".").pop();
        if (gzippable.indexOf(extension) > -1) {
          gzip(upload.buffer, function(err, zipped) {
            console.log("Uploading gzipped %s - %s => %s",
              upload.path,
              formatSize(upload.buffer.length),
              formatSize(zipped.length)
            );
            c();
          })
        } else {
          console.log("Uploading %s", upload.path);
          c();
        }
      }, done);
      return;
    }

    if (deploy == "live" && !config.production) {
      var checklist = grunt.file.read("tasks/checklist.txt");
      grunt.fail.fatal(checklist);
    }

    var bucketConfig = config.s3[deploy];

    var creds = require("../auth.json");
    aws.config.update(creds.s3);

    var s3 = new aws.S3();
    s3.createBucket({
      Bucket: bucketConfig.bucket
    }, function(err) {
      if (err && err.code != "BucketAlreadyOwnedByYou") {
        return console.log(err);
      }
      var uploads = findBuiltFiles();
      async.eachLimit(uploads, 10, function(upload, c) {
        var obj = {
          Bucket: bucketConfig.bucket,
          Key: join(bucketConfig.path, upload.path.replace(/^\\?build/, "")),
          Body: upload.buffer,
          ACL: "public-read",
          ContentType: mime.lookup(upload.path),
          CacheControl: "public,max-age=3000"
        };
        //if this matches GZip support, compress them before uploading to S3
        var extension = upload.path.split(".").pop();
        if (gzippable.indexOf(extension) > -1) {
          var before = upload.buffer.length;
          return gzip(upload.buffer, function(err, zipped) {
            if (!err) {
              obj.Body = zipped;
              var after = zipped.length;
              obj.ContentEncoding = "gzip";
              console.log("Uploading gzipped %s - %s %s %s (%s)",
                upload.path,

                chalk.cyan(formatSize(before)),
                chalk.yellow("=>"),
                chalk.cyan(formatSize(after)),
                chalk.bold.green(Math.round(after / before * 100) + "%")
              );
              s3.putObject(obj, c);
            }
          });
        }
        console.info("Uploading", obj.Key);
        s3.putObject(obj, c);
      }, function(err) {
        if (err) return console.log(err);
        console.log("All files uploaded successfully");
        done();
      });
    });
  });

};<commit_msg>SVG is gzippable<commit_after>var async = require("async");
var fs = require("fs");
var path = require("path");
var chalk = require("chalk");
var gzip = require("zlib").gzip;
var mime = require("mime");
var join = function() {
  return path.join.apply(path, arguments).replace(/\\/g, "/");
};

var aws = require("aws-sdk");

var formatSize = function(input) {
  if (input > 1024 * 1024) {
    return Math.round(input * 10 / (1024 * 1024)) / 10 + "MB";
  }
  if (input > 1024) {
    return Math.round(input / 1024) + "KB";
  }
  return input + "B";
};

var gzippable = ["js", "html", "json", "map", "css", "txt", "svg"];

module.exports = function(grunt) {

  var config = require("../project.json");

  var findBuiltFiles = function() {
    var pattern = ["**/*"];
    var embargo = config.embargo;
    if (embargo) {
      if (!(embargo instanceof Array)) embargo = [embargo];
      embargo.forEach(function(item) {
        pattern.push("!" + item);
        console.log(chalk.bgRed.white("File embargoed: %s"), item);
      });
    }
    var files = grunt.file.expand({ cwd: "build", filter: "isFile" }, pattern);
    var list = files.map(function(file) {
      var buffer = fs.readFileSync(path.join("build", file));
      return {
        path: file,
        buffer: buffer
      };
    });
    return list;
  };

  grunt.registerTask("publish", "Pushes the build folder to S3", function(deploy) {

    var done = this.async();

    deploy = deploy || "stage";

    if (deploy == "simulated") {
      var uploads = findBuiltFiles();
      async.each(uploads, function(upload, c) {
        var extension = upload.path.split(".").pop();
        if (gzippable.indexOf(extension) > -1) {
          gzip(upload.buffer, function(err, zipped) {
            console.log("Uploading gzipped %s - %s => %s",
              upload.path,
              formatSize(upload.buffer.length),
              formatSize(zipped.length)
            );
            c();
          })
        } else {
          console.log("Uploading %s", upload.path);
          c();
        }
      }, done);
      return;
    }

    if (deploy == "live" && !config.production) {
      var checklist = grunt.file.read("tasks/checklist.txt");
      grunt.fail.fatal(checklist);
    }

    var bucketConfig = config.s3[deploy];

    var creds = require("../auth.json");
    aws.config.update(creds.s3);

    var s3 = new aws.S3();
    s3.createBucket({
      Bucket: bucketConfig.bucket
    }, function(err) {
      if (err && err.code != "BucketAlreadyOwnedByYou") {
        return console.log(err);
      }
      var uploads = findBuiltFiles();
      async.eachLimit(uploads, 10, function(upload, c) {
        var obj = {
          Bucket: bucketConfig.bucket,
          Key: join(bucketConfig.path, upload.path.replace(/^\\?build/, "")),
          Body: upload.buffer,
          ACL: "public-read",
          ContentType: mime.lookup(upload.path),
          CacheControl: "public,max-age=3000"
        };
        //if this matches GZip support, compress them before uploading to S3
        var extension = upload.path.split(".").pop();
        if (gzippable.indexOf(extension) > -1) {
          var before = upload.buffer.length;
          return gzip(upload.buffer, function(err, zipped) {
            if (!err) {
              obj.Body = zipped;
              var after = zipped.length;
              obj.ContentEncoding = "gzip";
              console.log("Uploading gzipped %s - %s %s %s (%s)",
                upload.path,

                chalk.cyan(formatSize(before)),
                chalk.yellow("=>"),
                chalk.cyan(formatSize(after)),
                chalk.bold.green(Math.round(after / before * 100) + "%")
              );
              s3.putObject(obj, c);
            }
          });
        }
        console.info("Uploading", obj.Key);
        s3.putObject(obj, c);
      }, function(err) {
        if (err) return console.log(err);
        console.log("All files uploaded successfully");
        done();
      });
    });
  });

};<|endoftext|>