<commit_before>var gates = [
  {
    name: 'Merchants\' Gate',
    description: 'Columbus Circle',
    coordinates: [-73.981032371521,40.76825672305774]
  },
  {
    name: 'Women\'s Gate',
    description: 'Central Park West at West 72nd Street',
    coordinates: [-73.97596836090088,40.77621929333075]
  },
  {
    name: 'Hunters\'s Gate',
    description: 'CPW at West 81st Street',
    coordinates: [-73.97180557250977,40.78206873687405]
  },
  {
    name: 'Mariners\'s Gate',
    description: 'CPW at West 85th Street',
    coordinates: [-73.96974563598633,40.784668324219524]
  },
  {
    name: 'All Saints\'s Gate',
    description: 'CPW at West 97th Street',
    coordinates: [-73.96468162536621,40.79139428421785]
  },
  {
    name: 'Boys\'s Gate',
    description: 'CPW at West 100th Street',
    coordinates: [-73.96248726339071,40.794071110092574]
  },
  {
    name: 'Strangers\'s Gate',
    description: 'CPW at West 106th Street',
    coordinates: [-73.95978927612305,40.79756727106044]
  },
  {
    name: 'Warriors\'s Gate',
    description: 'Central Park North at Adam Clayton Powell Blvd. (7th Avenue)',
    coordinates: [-73.95498275756836,40.79932159415491]
  },
  {
    name: 'Farmers\'s Gate',
    description: 'CPN at Malcolm X Blvd. (Lenox Ave.)',
    coordinates: [-73.95271092653275,40.79838758531546]
  },
  {
    name: 'Pioneers\'s Gate',
    description: 'Duke Ellington/James Frawley Circle at 5th Avenue',
    coordinates: [-73.94970417022705,40.79665760379586]
  },
  {
    name: 'Vanderbilt Gate',
    description: '5th Ave. at East 106th Street',
    coordinates: [-73.95163536071777,40.79357113982765]
  },
  {
    name: 'Girls\'s Gate',
    description: '5th Avenue at East 102nd Street',
    coordinates: [-73.95313123164689,40.79192626129264]
  },
  {
    name: 'Engineers\'s Gate',
    description: '5th Avenue at East 90th Street',
    coordinates: [-73.95901679992676,40.78418090934269]
  },
  {
    name: 'Inventors\'s Gate',
    description: '5th Avenue at East 72nd Street',
    coordinates: [-73.9671277999878,40.772465629092785]
  },
  {
    name: 'Scholars\'s Gate',
    description: '5th Avenue at East 60th Street',
    coordinates: [-73.97262914830858,40.7650559902641]
  },
  {
    name: 'Artists\'s Gate',
    description: 'Central Park South at 6th Avenue',
    coordinates: [-73.97626876831055,40.765884017600165]
  },
  {
    name: 'Artisans\'s Gate',
    description: 'CPS at 7th Avenue',
    coordinates: [-73.9790153503418,40.766859112288344]
  }
];
attractionsObj = [];
attractionsGeoJson = {
  type: 'FeatureCollection',
  features: [ ]
};
featureTypes = [];

var parseAttractionXml = function(cb) {
  $.ajax({
    url: 'map-list.xml',
    dataType: 'xml',
    contentType: "text/xml; charset=\"utf-8\"",
    success: function(response) {
      processAttractionXml(response,cb);
    }
  });
};

var getAttractionCoords = function(node) {
  var lon = parseFloat(node.getElementsByTagName('longitude')[0].firstChild.nodeValue);
  var lat = parseFloat(node.getElementsByTagName('latitude')[0].firstChild.nodeValue);
  lon = (lon > 1) ? (lon * -1) : lon;
  lat = (lat < 1) ? (lat * -1) : lat;
  return [lon,lat];
};

var filterFeatures = [
  'arches-and-bridges',
  'fountain-monument-sculpture',
  'landscapes-points-of-interest',
  'recreation',
  'playground',
  'refreshments',
  'gate'
];
var processAttractionXml = function(doc,cb) {
  var attractionNodes = doc.getElementsByTagName('attraction');

  var attractions = _.map(attractionNodes, function(v,i) {
    var title = v.getElementsByTagName('title')[0].firstChild.nodeValue.trim();
    var coords = getAttractionCoords(v);
    var description = v.getElementsByTagName('description')[0].firstChild.nodeValue.trim();
    var link = v.getElementsByTagName('link')[0].firstChild.nodeValue;
    var featureNodes = v.getElementsByTagName('feature');

    var features = _.map(featureNodes, function(w,j) {
      return w.firstChild.nodeValue;
    });

    features = _.filter(features, function(v,i) {
      return _.contains(filterFeatures,v);
    });

    return {
      title: title,
      coordinates: coords,
      description: description,
      link: link,
      features: features
    };
  });

  attractionsObj = _.filter(attractions, function(v,i) {
    return v.coordinates[0] !== 0 &&
      v.features.length > 0;
  });

  toAttractionGeoJson(cb);
};

var toAttractionGeoJson = function(cb) {
  attractionsGeoJson.features = _.map(attractionsObj, function(v,i) {
    return {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: v.coordinates
      },
      properties: {
        name: v.title,
        description: v.description,
        link: v.link,
        features: v.features
      }
    };
  }).concat(_.map(gates, function(v,i) {
    return {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: v.coordinates
      },
      properties: {
        name: v.name,
        description: v.description,
        features: ['gate']
      }
    };
  }));
  restrictToBounds(cb);
};

var isInBounds = function(coord) {
  return coord[0] <= geoJson.bounds.maxLon &&
    coord[0] >= geoJson.bounds.minLon &&
    coord[1] <= geoJson.bounds.maxLat &&
    coord[1] >= geoJson.bounds.minLat;
};

var restrictToBounds = function(cb) {
  attractionsGeoJson.features = _.filter(attractionsGeoJson.features, function(v,i) {
    return isInBounds(v.geometry.coordinates);
  });
  manualFilter(cb);
};

var excludeArray = [
  'Gill Rustic Bridge',
  'Bow Bridge',
  'The Lake',
  'Bicycle Rental',
  'Loeb Boathouse Refreshments',
  'Loeb Boathouse',
  'Trefoil Arch',
  'Hans Christian Andersen',
  'Pilgrim Hill',
  'The Pilgrim'
];
var manualFilter = function(cb) {
  attractionsGeoJson.features = _.filter(attractionsGeoJson.features, function(v,i) {
    return !_.contains(excludeArray, v.properties.name);
  });
  getDistinctFeatureTypes(cb);
};

var getDistinctFeatureTypes = function(cb) {
  featureTypes = _.uniq(_.reduce(attractionsGeoJson.features, function(m,n) {
    return m.concat(n.properties.features);
  }, []));
  mapFeatures(cb);
};

var featureMap = {
  'arches-and-bridges': function() { return 'bridge'; },
  'fountain-monument-sculpture': function(feature) {
    if (feature.properties.name.toLowerCase().indexOf('fountain') !== -1)
      return 'fountain';
    return 'monument';
  },
  'landscapes-points-of-interest': function(feature) {
    if (feature.properties.name.toLowerCase().indexOf('bethesda') !== -1)
      return 'fountain';
    if (feature.properties.name.toLowerCase().indexOf('zoo') !== -1)
      return 'zoo';
    if (feature.properties.name.toLowerCase().indexOf('dairy') !== -1 ||
      feature.properties.name.toLowerCase().indexOf('cop cot') !== -1)
      return 'pavilion';
    return 'landscape';
  },
  'refreshments': function() { return 'restaurant'; },
  'recreation': function() { return 'recreation'; },
  'playground': function() { return 'playground'; },
  'gate': function() { return 'gate'; },
};
var mapFeatures = function(cb) {
  _.each(attractionsGeoJson.features, function(v,i) {
    v.properties.type = featureMap[v.properties.features[0]](v);
    delete v.properties.features;
  });
  cb();
};

var loadAttractions = function(cb) {
  $.ajax({
    url: 'coordinates.json',
    dataType: 'json',
    success: function(geoRes) {
      geoJson = geoRes;
      parseAttractionXml(cb);
    }
  });
};<commit_msg>add NYT article link to gates<commit_after>var gates = [
  {
    name: 'Merchants\' Gate',
    description: 'Columbus Circle',
    coordinates: [-73.981032371521,40.76825672305774]
  },
  {
    name: 'Women\'s Gate',
    description: 'Central Park West at West 72nd Street',
    coordinates: [-73.97596836090088,40.77621929333075]
  },
  {
    name: 'Hunters\'s Gate',
    description: 'CPW at West 81st Street',
    coordinates: [-73.97180557250977,40.78206873687405]
  },
  {
    name: 'Mariners\'s Gate',
    description: 'CPW at West 85th Street',
    coordinates: [-73.96974563598633,40.784668324219524]
  },
  {
    name: 'All Saints\'s Gate',
    description: 'CPW at West 97th Street',
    coordinates: [-73.96468162536621,40.79139428421785]
  },
  {
    name: 'Boys\'s Gate',
    description: 'CPW at West 100th Street',
    coordinates: [-73.96248726339071,40.794071110092574]
  },
  {
    name: 'Strangers\'s Gate',
    description: 'CPW at West 106th Street',
    coordinates: [-73.95978927612305,40.79756727106044]
  },
  {
    name: 'Warriors\'s Gate',
    description: 'Central Park North at Adam Clayton Powell Blvd. (7th Avenue)',
    coordinates: [-73.95498275756836,40.79932159415491]
  },
  {
    name: 'Farmers\'s Gate',
    description: 'CPN at Malcolm X Blvd. (Lenox Ave.)',
    coordinates: [-73.95271092653275,40.79838758531546]
  },
  {
    name: 'Pioneers\'s Gate',
    description: 'Duke Ellington/James Frawley Circle at 5th Avenue',
    coordinates: [-73.94970417022705,40.79665760379586]
  },
  {
    name: 'Vanderbilt Gate',
    description: '5th Ave. at East 106th Street',
    coordinates: [-73.95163536071777,40.79357113982765]
  },
  {
    name: 'Girls\'s Gate',
    description: '5th Avenue at East 102nd Street',
    coordinates: [-73.95313123164689,40.79192626129264]
  },
  {
    name: 'Engineers\'s Gate',
    description: '5th Avenue at East 90th Street',
    coordinates: [-73.95901679992676,40.78418090934269]
  },
  {
    name: 'Inventors\'s Gate',
    description: '5th Avenue at East 72nd Street',
    coordinates: [-73.9671277999878,40.772465629092785]
  },
  {
    name: 'Scholars\'s Gate',
    description: '5th Avenue at East 60th Street',
    coordinates: [-73.97262914830858,40.7650559902641]
  },
  {
    name: 'Artists\'s Gate',
    description: 'Central Park South at 6th Avenue',
    coordinates: [-73.97626876831055,40.765884017600165]
  },
  {
    name: 'Artisans\'s Gate',
    description: 'CPS at 7th Avenue',
    coordinates: [-73.9790153503418,40.766859112288344]
  }
];
attractionsObj = [];
attractionsGeoJson = {
  type: 'FeatureCollection',
  features: [ ]
};
featureTypes = [];

var parseAttractionXml = function(cb) {
  $.ajax({
    url: 'map-list.xml',
    dataType: 'xml',
    contentType: "text/xml; charset=\"utf-8\"",
    success: function(response) {
      processAttractionXml(response,cb);
    }
  });
};

var getAttractionCoords = function(node) {
  var lon = parseFloat(node.getElementsByTagName('longitude')[0].firstChild.nodeValue);
  var lat = parseFloat(node.getElementsByTagName('latitude')[0].firstChild.nodeValue);
  lon = (lon > 1) ? (lon * -1) : lon;
  lat = (lat < 1) ? (lat * -1) : lat;
  return [lon,lat];
};

var filterFeatures = [
  'arches-and-bridges',
  'fountain-monument-sculpture',
  'landscapes-points-of-interest',
  'recreation',
  'playground',
  'refreshments',
  'gate'
];
var processAttractionXml = function(doc,cb) {
  var attractionNodes = doc.getElementsByTagName('attraction');

  var attractions = _.map(attractionNodes, function(v,i) {
    var title = v.getElementsByTagName('title')[0].firstChild.nodeValue.trim();
    var coords = getAttractionCoords(v);
    var description = v.getElementsByTagName('description')[0].firstChild.nodeValue.trim();
    var link = v.getElementsByTagName('link')[0].firstChild.nodeValue;
    var featureNodes = v.getElementsByTagName('feature');

    var features = _.map(featureNodes, function(w,j) {
      return w.firstChild.nodeValue;
    });

    features = _.filter(features, function(v,i) {
      return _.contains(filterFeatures,v);
    });

    return {
      title: title,
      coordinates: coords,
      description: description,
      link: link,
      features: features
    };
  });

  attractionsObj = _.filter(attractions, function(v,i) {
    return v.coordinates[0] !== 0 &&
      v.features.length > 0;
  });

  toAttractionGeoJson(cb);
};

var toAttractionGeoJson = function(cb) {
  attractionsGeoJson.features = _.map(attractionsObj, function(v,i) {
    return {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: v.coordinates
      },
      properties: {
        name: v.title,
        description: v.description,
        link: v.link,
        features: v.features
      }
    };
  }).concat(_.map(gates, function(v,i) {
    return {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: v.coordinates
      },
      properties: {
        name: v.name,
        description: v.description,
        link: 'http://www.nytimes.com/1999/12/03/nyregion/central-park-entrances-in-a-return-to-the-past.html',
        features: ['gate']
      }
    };
  }));
  restrictToBounds(cb);
};

var isInBounds = function(coord) {
  return coord[0] <= geoJson.bounds.maxLon &&
    coord[0] >= geoJson.bounds.minLon &&
    coord[1] <= geoJson.bounds.maxLat &&
    coord[1] >= geoJson.bounds.minLat;
};

var restrictToBounds = function(cb) {
  attractionsGeoJson.features = _.filter(attractionsGeoJson.features, function(v,i) {
    return isInBounds(v.geometry.coordinates);
  });
  manualFilter(cb);
};

var excludeArray = [
  'Gill Rustic Bridge',
  'Bow Bridge',
  'The Lake',
  'Bicycle Rental',
  'Loeb Boathouse Refreshments',
  'Loeb Boathouse',
  'Trefoil Arch',
  'Hans Christian Andersen',
  'Pilgrim Hill',
  'The Pilgrim'
];
var manualFilter = function(cb) {
  attractionsGeoJson.features = _.filter(attractionsGeoJson.features, function(v,i) {
    return !_.contains(excludeArray, v.properties.name);
  });
  getDistinctFeatureTypes(cb);
};

var getDistinctFeatureTypes = function(cb) {
  featureTypes = _.uniq(_.reduce(attractionsGeoJson.features, function(m,n) {
    return m.concat(n.properties.features);
  }, []));
  mapFeatures(cb);
};

var featureMap = {
  'arches-and-bridges': function() { return 'bridge'; },
  'fountain-monument-sculpture': function(feature) {
    if (feature.properties.name.toLowerCase().indexOf('fountain') !== -1)
      return 'fountain';
    return 'monument';
  },
  'landscapes-points-of-interest': function(feature) {
    if (feature.properties.name.toLowerCase().indexOf('bethesda') !== -1)
      return 'fountain';
    if (feature.properties.name.toLowerCase().indexOf('zoo') !== -1)
      return 'zoo';
    if (feature.properties.name.toLowerCase().indexOf('dairy') !== -1 ||
      feature.properties.name.toLowerCase().indexOf('cop cot') !== -1)
      return 'pavilion';
    return 'landscape';
  },
  'refreshments': function() { return 'restaurant'; },
  'recreation': function() { return 'recreation'; },
  'playground': function() { return 'playground'; },
  'gate': function() { return 'gate'; },
};
var mapFeatures = function(cb) {
  _.each(attractionsGeoJson.features, function(v,i) {
    v.properties.type = featureMap[v.properties.features[0]](v);
    delete v.properties.features;
  });
  cb();
};

var loadAttractions = function(cb) {
  $.ajax({
    url: 'coordinates.json',
    dataType: 'json',
    success: function(geoRes) {
      geoJson = geoRes;
      parseAttractionXml(cb);
    }
  });
};<|endoftext|>


<commit_before>
var createClient = require('./swf').createClient;

/**
 * Class to make it easier to respond to activity tasks
 * @constructor
 */
var ActivityTask = exports.ActivityTask = function (config, swfClient) {

    this.config = config;

    this.swfClient = swfClient || createClient();
};

function stringify(str) {
    if(!str) {
        return "";
    }

    if (typeof str !== "string") {
        return JSON.stringify(str);
    }

    return str;
}

ActivityTask.prototype = {

    /**
     * Sends a "RespondActivityTaskCompleted" to AWS.
     * result will get stringified in JSON if not a string
     */
    respondCompleted: function (result, cb) {

        this.swfClient.client.respondActivityTaskCompleted({
            taskToken: this.config.taskToken,
            result: stringify(result)
        }, function (err) {

            if (err) {
                console.log("Error while sending RespondActivityTaskCompleted : ", err);
            }

            if (cb) {
                cb(err);
            }

        });

    },

    /**
     * Sends a "RespondActivityTaskFailed" to AWS.
     */
    respondFailed: function (reason, details, cb) {

        var o = {
            "taskToken": this.config.taskToken
        };
        if (reason) {
            o.reason = reason;
        }
        if (details) {
            o.details = stringify(details);
        }

        this.swfClient.client.respondActivityTaskFailed(o, function (err) {

            if (err) {
                console.log("Error while sending RespondActivityTaskFailed : ", err);
            }

            if (cb) {
                cb(err);
            }

        });

    },

    /**
     * Sends a heartbeat to AWS. Needed for long run activity
     *
     * Heartbeat message will get stringified in JSON if not a string
     */
    recordHeartbeat: function (heartbeat, cb) {

        this.swfClient.client.recordActivityTaskHeartbeat({
            taskToken: this.config.taskToken,
            details: stringify(heartbeat)
        }, function (err) {

            if (err) {
                console.log("Error while sending RecordActivityTaskHeartbeat : ", err);
            }

            if (cb) {
                cb(err);
            }

        });
    }

};
<commit_msg>Testing code climate<commit_after>
var createClient = require('./swf').createClient;

/**
 * Class to make it easier to respond to activity tasks
 * @constructor
 */
var ActivityTask = exports.ActivityTask = function (config, swfClient) {

    this.config = config;

    this.swfClient = swfClient || createClient();
};

function stringify(str) {
    if(!str) {
        return "";
    }

    if (typeof str !== "string") {
        return JSON.stringify(str);
    }

    return str;
}

ActivityTask.prototype = {

    /**
     * Sends a "RespondActivityTaskCompleted" to AWS.
     * result will get stringified in JSON if not a string
     */
    respondCompleted: function (result, cb) {

        this.swfClient.client.respondActivityTaskCompleted({
            result: stringify(result),
            taskToken: this.config.taskToken
        }, function (err) {

            if (err) {
                console.log("Error while sending RespondActivityTaskCompleted : ", err);
            }

            if (cb) {
                cb(err);
            }

        });

    },

    /**
     * Sends a "RespondActivityTaskFailed" to AWS.
     */
    respondFailed: function (reason, details, cb) {

        var o = {
            "taskToken": this.config.taskToken
        };
        if (reason) {
            o.reason = reason;
        }
        if (details) {
            o.details = stringify(details);
        }

        this.swfClient.client.respondActivityTaskFailed(o, function (err) {

            if (err) {
                console.log("Error while sending RespondActivityTaskFailed : ", err);
            }

            if (cb) {
                cb(err);
            }

        });

    },

    /**
     * Sends a heartbeat to AWS. Needed for long run activity
     *
     * Heartbeat message will get stringified in JSON if not a string
     */
    recordHeartbeat: function (heartbeat, cb) {

        this.swfClient.client.recordActivityTaskHeartbeat({
            taskToken: this.config.taskToken,
            details: stringify(heartbeat)
        }, function (err) {

            if (err) {
                console.log("Error while sending RecordActivityTaskHeartbeat : ", err);
            }

            if (cb) {
                cb(err);
            }

        });
    }

};
<|endoftext|>


<commit_before>// $Id$

var auto_save_submit = false;
var sending_auto_save = false;
var auto_save_debug = false;	// for development use

function remove_save(editorId, autoSaveId) {
	if (typeof editorId !== 'string' || !editorId || !autoSaveId || auto_save_submit) {
		return;	// seems to get jQuery events arriving here or has been submitted before
	}
	if (sending_auto_save) {	// wait if autosaving
		setTimeout(function () { remove_save(editorId, autoSaveId); }, 100);
	}
	auto_save_submit = true;
	$.ajax({
		url: $.service("autosave", "delete"),
		data: {
			editor_id: editorId,
			referer: autoSaveId
		},
		type: "POST",
		async: false,	// called on form submit (save or cancel) so need to wait otherwise the call gets cancelled
		// good callback
		success: function(data) {
			// act casual?
		},
		// bad callback - no good info in the params :(
		error: function(req, status, error) {
			if (error && auto_save_debug) {
				alert(tr("Auto Save removal returned an error: ") + error);
			}
		}
	});
}

function toggle_autosaved(editorId, autoSaveId) {
	if (typeof autoSaveId === 'undefined') { autoSaveId = ''; }
	var output = '', prefix = '';
	var $textarea = $('#' + editorId);
	var textareaEditor = syntaxHighlighter.get($textarea);
	var cked = typeof CKEDITOR !== 'undefined' ? CKEDITOR.instances[editorId] : null;
	if (!$textarea.data("original")) {	// no save version already?
		if (cked) { prefix = 'cke_contents_'; }
		ajaxLoadingShow(prefix + editorId);

		$.getJSON( $.service("autosave", "get"), {
				editor_id: editorId,
				referer: autoSaveId
			},
			function(data) {
				output = data.data;
				// back up current
				$textarea.data("original", $textarea.val());
				if (cked) {
					cked.setData(output);
				} else if (textareaEditor) {
					textareaEditor.setValue(output);
				} else if ($("#"+editorId).length) {	// wiki editor
					$textarea.val(output);
				}
				ajaxLoadingHide();
			}
		);

	} else {	// toggle back to original
		syntaxHighlighter.sync($textarea);

		output = $textarea.data("original");
		if (cked) {
			cked.setData(output);	// cked leaves the original content in the ta
		} else if (textareaEditor) {
			textareaEditor.setValue(output);
		} else if ($("#"+editorId).length) {	// wiki editor
			$("#"+editorId).val(output);
		}
		$textarea.data("original", "");
	}
	// swap the messages around (fixed to first textarea only for now)
	var msg = $(".autosave_message_2:first").text();
	$(".autosave_message_2:first").text($(".autosave_message:first").text());
	$(".autosave_message:first").text(msg);

	return output;
}

function auto_save_allowHtml(form) {
	return $("input[name=allowhtml]:checked", form).length ||
		($("input[name=allowhtml][type=hidden]", form).length &&
			$("input[name=allowhtml][type=hidden]", form).val() ? 1 : 0);
}

function auto_save( editorId ) {

	if (!editorId) { alert(tr("Auto save: No editorId set")) }

	if ( !auto_save_submit && !sending_auto_save) {

		var $textarea = $('#' + editorId);
		var autoSaveId = $textarea.data("autoSaveId");

		syntaxHighlighter.sync($textarea);

		var data = $textarea.val();
		var allowHtml = auto_save_allowHtml($textarea.prop("form"));

		if (data !== $textarea.data("original") || $textarea.data("last") !== data || $textarea.data("old_allowhtml") != allowHtml) {
			$textarea.data("last", data);
			sending_auto_save = true;
			$.ajax({
				url: $.service("autosave", "save"),
				data: {
					editor_id: editorId,
					referer: autoSaveId,
					data: data
				},
				type: "POST",
				// good callback
				success: function(data) {
					// update button when it's there (TODO)
					if (ajaxPreviewWindow && typeof ajaxPreviewWindow.get_new_preview === 'function') {
						 ajaxPreviewWindow.get_new_preview();
					} else {
						ajax_preview( editorId, autoSaveId, true );
					}
					$textarea.data("old_allowhtml", allowHtml);
					sending_auto_save = false;
				},
				// bad callback - no good info in the params :(
				error: function(req, status, error) {
					if (error && auto_save_debug) {
						alert(tr("Auto Save error: ") + error);
					}
					sending_auto_save = false;
				}
			});
		} else {	// not changed, reset timeout
		}
	}
}

function register_id( editorId, autoSaveId ) {
	var $textarea = $('#' + editorId);
	$textarea.data("autoSaveId", autoSaveId);
	syntaxHighlighter.sync($textarea);
	$textarea.parents('form').submit(function() { remove_save(editorId, autoSaveId); });
	$textarea.change(function () { auto_save( editorId ); });
}

var ajaxPreviewWindow;

function ajax_preview(editorId, autoSaveId, inPage) {
	if (editorId) {
		var $textarea = $('#' + editorId);
		var $autosavepreview = $("#autosave_preview");
		syntaxHighlighter.sync($textarea);
		var allowHtml = auto_save_allowHtml($textarea.prop("form"));
		if (!ajaxPreviewWindow) {
			if (inPage) {
				var $prvw = $("#autosave_preview:visible");
				if ($prvw.length) {
					ajaxLoadingShow($autosavepreview);
					var h = location.search.match(/&hdr=(\d?)/);
					h = h && h.length ? h[1] : "";
					$.get($.service("edit", "preview"), {
						editor_id: editorId,
						autoSaveId: autoSaveId,
						inPage: 1,
						hdr: h,
						allowHtml: allowHtml
					}, function(data) {
						// remove JS and disarm links
						data = data.replace(/\shref/gi, " tiki_href").
								replace(/\sonclick/gi, " tiki_onclick").
								replace(/<script[.\s\S]*?<\/script>/mgi, "");
						$(".preview_contents", $autosavepreview).html(data);
						$("#preview_diff_style").val(function(){return getCookie("preview_diff_style","preview","");});
						ajaxLoadingHide();
					});
				}
			} else {
				initPreviewWindow(editorId, autoSaveId, allowHtml);
			}
		} else {
			if (typeof ajaxPreviewWindow.get_new_preview === 'function') {
				ajaxPreviewWindow.get_new_preview();
				ajaxPreviewWindow.focus();
			} else {
				initPreviewWindow(editorId, autoSaveId, allowHtml);
			}
		}
	} else {
		if (auto_save_debug) {
			alert("Auto save data not found");
		}
	}

}

function initPreviewWindow (editorId, autoSaveId, allowHtml) {
	var features = 'menubar=no,toolbar=no,fullscreen=no,titlebar=no,status=no,width=600';
	var url = $.service("edit", "preview", {editor_id: editorId, autoSaveId: autoSaveId, allowHtml: allowHtml });
	window.open(url, "_blank", features);
};

$(window).unload(function () {
	if (ajaxPreviewWindow && typeof ajaxPreviewWindow.get_new_preview === 'function') {
		ajaxPreviewWindow.close();
	}
});
<commit_msg>[FIX] auto_save_debug (var) added in the "if condition" to avoid alert message.<commit_after>// $Id$

var auto_save_submit = false;
var sending_auto_save = false;
var auto_save_debug = false;	// for development use

function remove_save(editorId, autoSaveId) {
	if (typeof editorId !== 'string' || !editorId || !autoSaveId || auto_save_submit) {
		return;	// seems to get jQuery events arriving here or has been submitted before
	}
	if (sending_auto_save) {	// wait if autosaving
		setTimeout(function () { remove_save(editorId, autoSaveId); }, 100);
	}
	auto_save_submit = true;
	$.ajax({
		url: $.service("autosave", "delete"),
		data: {
			editor_id: editorId,
			referer: autoSaveId
		},
		type: "POST",
		async: false,	// called on form submit (save or cancel) so need to wait otherwise the call gets cancelled
		// good callback
		success: function(data) {
			// act casual?
		},
		// bad callback - no good info in the params :(
		error: function(req, status, error) {
			if (error && auto_save_debug) {
				alert(tr("Auto Save removal returned an error: ") + error);
			}
		}
	});
}

function toggle_autosaved(editorId, autoSaveId) {
	if (typeof autoSaveId === 'undefined') { autoSaveId = ''; }
	var output = '', prefix = '';
	var $textarea = $('#' + editorId);
	var textareaEditor = syntaxHighlighter.get($textarea);
	var cked = typeof CKEDITOR !== 'undefined' ? CKEDITOR.instances[editorId] : null;
	if (!$textarea.data("original")) {	// no save version already?
		if (cked) { prefix = 'cke_contents_'; }
		ajaxLoadingShow(prefix + editorId);

		$.getJSON( $.service("autosave", "get"), {
				editor_id: editorId,
				referer: autoSaveId
			},
			function(data) {
				output = data.data;
				// back up current
				$textarea.data("original", $textarea.val());
				if (cked) {
					cked.setData(output);
				} else if (textareaEditor) {
					textareaEditor.setValue(output);
				} else if ($("#"+editorId).length) {	// wiki editor
					$textarea.val(output);
				}
				ajaxLoadingHide();
			}
		);

	} else {	// toggle back to original
		syntaxHighlighter.sync($textarea);

		output = $textarea.data("original");
		if (cked) {
			cked.setData(output);	// cked leaves the original content in the ta
		} else if (textareaEditor) {
			textareaEditor.setValue(output);
		} else if ($("#"+editorId).length) {	// wiki editor
			$("#"+editorId).val(output);
		}
		$textarea.data("original", "");
	}
	// swap the messages around (fixed to first textarea only for now)
	var msg = $(".autosave_message_2:first").text();
	$(".autosave_message_2:first").text($(".autosave_message:first").text());
	$(".autosave_message:first").text(msg);

	return output;
}

function auto_save_allowHtml(form) {
	return $("input[name=allowhtml]:checked", form).length ||
		($("input[name=allowhtml][type=hidden]", form).length &&
			$("input[name=allowhtml][type=hidden]", form).val() ? 1 : 0);
}

function auto_save( editorId ) {

	if (!editorId && auto_save_debug) { alert(tr("Auto save: No editorId set")) }

	if ( !auto_save_submit && !sending_auto_save) {

		var $textarea = $('#' + editorId);
		var autoSaveId = $textarea.data("autoSaveId");

		syntaxHighlighter.sync($textarea);

		var data = $textarea.val();
		var allowHtml = auto_save_allowHtml($textarea.prop("form"));

		if (data !== $textarea.data("original") || $textarea.data("last") !== data || $textarea.data("old_allowhtml") != allowHtml) {
			$textarea.data("last", data);
			sending_auto_save = true;
			$.ajax({
				url: $.service("autosave", "save"),
				data: {
					editor_id: editorId,
					referer: autoSaveId,
					data: data
				},
				type: "POST",
				// good callback
				success: function(data) {
					// update button when it's there (TODO)
					if (ajaxPreviewWindow && typeof ajaxPreviewWindow.get_new_preview === 'function') {
						 ajaxPreviewWindow.get_new_preview();
					} else {
						ajax_preview( editorId, autoSaveId, true );
					}
					$textarea.data("old_allowhtml", allowHtml);
					sending_auto_save = false;
				},
				// bad callback - no good info in the params :(
				error: function(req, status, error) {
					if (error && auto_save_debug) {
						alert(tr("Auto Save error: ") + error);
					}
					sending_auto_save = false;
				}
			});
		} else {	// not changed, reset timeout
		}
	}
}

function register_id( editorId, autoSaveId ) {
	var $textarea = $('#' + editorId);
	$textarea.data("autoSaveId", autoSaveId);
	syntaxHighlighter.sync($textarea);
	$textarea.parents('form').submit(function() { remove_save(editorId, autoSaveId); });
	$textarea.change(function () { auto_save( editorId ); });
}

var ajaxPreviewWindow;

function ajax_preview(editorId, autoSaveId, inPage) {
	if (editorId) {
		var $textarea = $('#' + editorId);
		var $autosavepreview = $("#autosave_preview");
		syntaxHighlighter.sync($textarea);
		var allowHtml = auto_save_allowHtml($textarea.prop("form"));
		if (!ajaxPreviewWindow) {
			if (inPage) {
				var $prvw = $("#autosave_preview:visible");
				if ($prvw.length) {
					ajaxLoadingShow($autosavepreview);
					var h = location.search.match(/&hdr=(\d?)/);
					h = h && h.length ? h[1] : "";
					$.get($.service("edit", "preview"), {
						editor_id: editorId,
						autoSaveId: autoSaveId,
						inPage: 1,
						hdr: h,
						allowHtml: allowHtml
					}, function(data) {
						// remove JS and disarm links
						data = data.replace(/\shref/gi, " tiki_href").
								replace(/\sonclick/gi, " tiki_onclick").
								replace(/<script[.\s\S]*?<\/script>/mgi, "");
						$(".preview_contents", $autosavepreview).html(data);
						$("#preview_diff_style").val(function(){return getCookie("preview_diff_style","preview","");});
						ajaxLoadingHide();
					});
				}
			} else {
				initPreviewWindow(editorId, autoSaveId, allowHtml);
			}
		} else {
			if (typeof ajaxPreviewWindow.get_new_preview === 'function') {
				ajaxPreviewWindow.get_new_preview();
				ajaxPreviewWindow.focus();
			} else {
				initPreviewWindow(editorId, autoSaveId, allowHtml);
			}
		}
	} else {
		if (auto_save_debug) {
			alert("Auto save data not found");
		}
	}

}

function initPreviewWindow (editorId, autoSaveId, allowHtml) {
	var features = 'menubar=no,toolbar=no,fullscreen=no,titlebar=no,status=no,width=600';
	var url = $.service("edit", "preview", {editor_id: editorId, autoSaveId: autoSaveId, allowHtml: allowHtml });
	window.open(url, "_blank", features);
};

$(window).unload(function () {
	if (ajaxPreviewWindow && typeof ajaxPreviewWindow.get_new_preview === 'function') {
		ajaxPreviewWindow.close();
	}
});
<|endoftext|>


<commit_before>var cip = require('./cip-methods.js');
var Q = require('q');

var result_mapping = [
    {'key': 'id',
     'short': 'id'},
    {'key': '{af4b2e00-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'filename'
    },
    {'key': '{f5d1dcd8-c553-4346-8d4d-672c85bb59be}',
     'short': 'license',
    },
    {'key': '{9b071045-118c-4f42-afa1-c3121783ac66}',
     'short': 'creator',
    },
    {'key': '{af4b2e2c-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'copyright',
    },
    {'key': '{2ce9c8eb-b83d-4a91-9d09-2141cac7de12}',
     'short': 'description',
    },
    {'key': '{af4b2e12-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'img_height'
    },
    {'key': '{af4b2e11-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'img_width'
    },
    {'key': '{af4b2e0f-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'dpi',
    },
    {'key': '{418a4c92-fe63-11d3-9030-0080ad80c556}',
     'short': 'longitude',
    },
    {'key': '{418a4c91-fe63-11d3-9030-0080ad80c556}',
     'short': 'latitude',
    },
    {'key': '{ca6903b8-c3c4-47fa-9592-2d486d766ce0}',
     'short': 'actorname',
    },
    {'key': '{38664623-b081-4251-8c1c-383ef57ac54d}',
     'short': 'locationnote'
    },
    {'key': '{a02dd229-5aa8-4bb4-825a-038cf21f92bd}',
     'short': 'year'
    },
    {'key': '{76f2cca6-3652-40ee-b198-5d0afe931caa}',
     'short': 'assetno'
    },
    {'key': '{59ac5106-a3b4-4152-8647-66cebcb6af48}',
     'short': 'creation_time_from'
    },
    {'key': '{eaf2f030-2bfb-4d75-98ab-fb9bd33affcc}',
     'short': 'creation_time_to'
    },
    {'key': '{65f668d1-b070-494f-a9a3-7b6c3d370e65}',
     'short': 'acceptance_time_from'
    },
    {'key': '{0db7de9e-37fa-47a5-b087-0b1e6066ee86}',
     'short': 'acceptance_time_to'
    },
    {'key': '{1cb94319-9e1f-428e-993f-a78c78947f60}',
     'short': 'timenote'
    },
    {'key': '{8e820869-e338-4761-aa88-3dcd89f8cbae}',
     'short': 'archiveno'
    },
    {'key': '{d6025301-ef5e-4722-b101-78fd28262a98}',
     'short': 'topno'
    },
    {'key': '{8ac71e5d-5ca9-42cf-8c21-02c41e1af5cd}',
     'short': 'archivename'
    },
    {'key': '{9aef60d3-38b4-4e47-8104-d018b83ea6c6}',
     'short': 'unitno'
    },
    {'key': '{51b661a3-585e-4dbd-9e98-85e12ad91190}',
     'short': 'place'
    },
    {'key': '{24252838-de09-46e4-8f7d-f3fb85cde78f}',
     'short': 'city'
    },
    {'key': '{6fb1f61b-14a3-4851-bba0-cf7e71ef59cb}',
     'short': 'short_title'
    },
    {'key': '{af4b2e0c-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'categories'
    },
    {'key': '{659ca0c6-92d8-4f7a-af58-8a3c69df2ede}',
     'short': 'street'
    },
    {'key': '{ed64a9f8-8d19-4f60-a615-5bd3b188e98a}',
     'short': 'address'
    },
    {'key': '{5bbe594f-d029-4bb5-9c42-8f1ac8c94b7f}',
     'short': 'zipcode'
    },
    {'key': '{af4b2e02-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'modification_time'
    },
    {'key': '{a493be21-0f70-4cae-9394-703eca848bad}',
     'short': 'review_state'
    },
    {'key': '{bf7a30ac-e53b-4147-95e0-aea8c71340ca}',
     'short': 'cropping_status'
    },
    {'key': '{af4b2e71-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'related_sub_assets'
    },
    {'key': '{af4b2e72-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'related_master_assets'
    }
];

exports.result_mapping = result_mapping;

function format_result(fields) {
    var result = {};

    for(var i=0; i < result_mapping.length; ++i) {
        if(result_mapping[i].key in fields) {
            result[result_mapping[i].short] = fields[result_mapping[i].key];
        }
    }

    return result;
}

exports.format_result = format_result;

// This expects that the related_master_assets has been parsed using the
// cip-methods.js's parse_binary_relations
function extend_from_master(nm, metadata) {
    // We expect the formatted metadata to contain a binary field with related
    // master asset ids.
    if(!metadata.related_master_assets || metadata.related_master_assets.length === 0) {
        return metadata;
    }
    // We expect only one master asset.
    if(metadata.related_master_assets.length !== 1) {
        // Compile a textual representation of the master asset id's.
        var master_asset_summary = JSON.stringify(metadata.related_master_assets);
        throw new Error( 'Expected exactly one master asset, received ' +
            metadata.related_master_assets.length+ ': ' +master_asset_summary );
    }
    // Deriving the single master asset id.
    var master_asset_id = metadata.related_master_assets[0].id;

    return cip.get_asset(nm, metadata.catalog, master_asset_id)
    .then(function(master_assets) {
        // We assume only one is returned.
        if(master_assets.length !== 1) {
            throw new Error( 'Expected exactly one master asset, received ' +
                master_assets.length );
        }
        var master_asset = master_assets[0];
        var master_asset_metadata = format_result(master_asset.fields);
        // Overwrite where the original asset has no value.
        for(var f in metadata) {
            var original_value = metadata[f];
            var master_value = master_asset_metadata[f];
            if(!original_value && master_value) {
                // Overwrite with the master assets value.
                metadata[f] = master_value;
            }
        }
        console.log(metadata);
        return metadata;
    });
}

exports.extend_from_master = extend_from_master;
<commit_msg>Update asset-mapping.js<commit_after>var cip = require('./cip-methods.js');
var Q = require('q');

var result_mapping = [
    {'key': 'id',
     'short': 'id'},
    {'key': '{af4b2e00-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'filename'
    },
    {'key': '{f5d1dcd8-c553-4346-8d4d-672c85bb59be}',
     'short': 'license',
    },
    {'key': '{9b071045-118c-4f42-afa1-c3121783ac66}',
     'short': 'creator',
    },
    {'key': '{af4b2e2c-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'copyright',
    },
    {'key': '{2ce9c8eb-b83d-4a91-9d09-2141cac7de12}',
     'short': 'description',
    },
    {'key': '{af4b2e12-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'img_height'
    },
    {'key': '{af4b2e11-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'img_width'
    },
    {'key': '{af4b2e0f-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'dpi',
    },
    {'key': '{418a4c92-fe63-11d3-9030-0080ad80c556}',
     'short': 'longitude',
    },
    {'key': '{418a4c91-fe63-11d3-9030-0080ad80c556}',
     'short': 'latitude',
    },
    {'key': '{ca6903b8-c3c4-47fa-9592-2d486d766ce0}',
     'short': 'actorname',
    },
    {'key': '{38664623-b081-4251-8c1c-383ef57ac54d}',
     'short': 'locationnote'
    },
    {'key': '{a02dd229-5aa8-4bb4-825a-038cf21f92bd}',
     'short': 'year'
    },
    {'key': '{76f2cca6-3652-40ee-b198-5d0afe931caa}',
     'short': 'assetno'
    },
    {'key': '{59ac5106-a3b4-4152-8647-66cebcb6af48}',
     'short': 'creation_time_from'
    },
    {'key': '{eaf2f030-2bfb-4d75-98ab-fb9bd33affcc}',
     'short': 'creation_time_to'
    },
    {'key': '{65f668d1-b070-494f-a9a3-7b6c3d370e65}',
     'short': 'acceptance_time_from'
    },
    {'key': '{0db7de9e-37fa-47a5-b087-0b1e6066ee86}',
     'short': 'acceptance_time_to'
    },
    {'key': '{1cb94319-9e1f-428e-993f-a78c78947f60}',
     'short': 'timenote'
    },
    {'key': '{8e820869-e338-4761-aa88-3dcd89f8cbae}',
     'short': 'archiveno'
    },
    {'key': '{d6025301-ef5e-4722-b101-78fd28262a98}',
     'short': 'topno'
    },
    {'key': '{8ac71e5d-5ca9-42cf-8c21-02c41e1af5cd}',
     'short': 'archivename'
    },
    {'key': '{9aef60d3-38b4-4e47-8104-d018b83ea6c6}',
     'short': 'unitno'
    },
    {'key': '{51b661a3-585e-4dbd-9e98-85e12ad91190}',
     'short': 'place'
    },
    {'key': '{24252838-de09-46e4-8f7d-f3fb85cde78f}',
     'short': 'city'
    },
    {'key': '{6fb1f61b-14a3-4851-bba0-cf7e71ef59cb}',
     'short': 'short_title'
    },
    {'key': '{af4b2e0c-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'categories'
    },
    {'key': '{659ca0c6-92d8-4f7a-af58-8a3c69df2ede}',
     'short': 'street'
    },
    {'key': '{ed64a9f8-8d19-4f60-a615-5bd3b188e98a}',
     'short': 'address'
    },
    {'key': '{5bbe594f-d029-4bb5-9c42-8f1ac8c94b7f}',
     'short': 'zipcode'
    },
    {'key': '{af4b2e02-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'modification_time'
    },
    {'key': '{a493be21-0f70-4cae-9394-703eca848bad}',
     'short': 'review_state'
    },
    {'key': '{bf7a30ac-e53b-4147-95e0-aea8c71340ca}',
     'short': 'cropping_status'
    },
    {'key': '{af4b2e71-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'related_sub_assets'
    },
    {'key': '{af4b2e72-5f6a-11d2-8f20-0000c0e166dc}',
     'short': 'related_master_assets'
    }
];

exports.result_mapping = result_mapping;

function format_result(fields) {
    var result = {};

    for(var i=0; i < result_mapping.length; ++i) {
        if(result_mapping[i].key in fields) {
            result[result_mapping[i].short] = fields[result_mapping[i].key];
        }
    }

    return result;
}

exports.format_result = format_result;

// This expects that the related_master_assets has been parsed using the
// cip-methods.js's parse_binary_relations
function extend_from_master(nm, metadata) {
    console.log(metadata);
    // We expect the formatted metadata to contain a binary field with related
    // master asset ids.
    if(!metadata.related_master_assets || metadata.related_master_assets.length === 0) {
        return metadata;
    }
    // We expect only one master asset.
    if(metadata.related_master_assets.length !== 1) {
        // Compile a textual representation of the master asset id's.
        var master_asset_summary = JSON.stringify(metadata.related_master_assets);
        throw new Error( 'Expected exactly one master asset, received ' +
            metadata.related_master_assets.length+ ': ' +master_asset_summary );
    }
    // Deriving the single master asset id.
    var master_asset_id = metadata.related_master_assets[0].id;

    return cip.get_asset(nm, metadata.catalog, master_asset_id)
    .then(function(master_assets) {
        // We assume only one is returned.
        if(master_assets.length !== 1) {
            throw new Error( 'Expected exactly one master asset, received ' +
                master_assets.length );
        }
        var master_asset = master_assets[0];
        var master_asset_metadata = format_result(master_asset.fields);
        // Overwrite where the original asset has no value.
        for(var f in metadata) {
            var original_value = metadata[f];
            var master_value = master_asset_metadata[f];
            if(!original_value && master_value) {
                // Overwrite with the master assets value.
                metadata[f] = master_value;
            }
        }
        console.log(metadata);
        return metadata;
    });
}

exports.extend_from_master = extend_from_master;
<|endoftext|>


<commit_before>var convert = require('color-convert');
var EventEmitter = require('events');
var merge = require('merge');
var util = require('util');
var workerproxy = require('workerproxy');

var ResourceLoader = require('./resourceloader');

module.exports = AssetsManager;

function AssetsManager(opt_options) {
  EventEmitter.call(this);

  var options = {
    workerPath: __dirname + '/../worker.js',
    workers: 1
  };

  Object.seal(options);
  merge(options, opt_options);
  Object.freeze(options);

  this.options = options;

  // Create the number of workers specified in options.
  var workers = [];
  for (var i = 0; i < options.workers; i++) {
    workers.push(new Worker(options.workerPath));
  }

  // Create a proxy which will handle delegation to the workers.
  this.api = workerproxy(workers);

  this._emitting = {};
  this._blobCache = Object.create(null);
  // TODO: Make a more generic cache?
  this._framesCache = Object.create(null);
  this._imageCache = Object.create(null);
}
util.inherits(AssetsManager, EventEmitter);

/**
 * Indexes a directory. All files in the directory will be reachable through
 * the assets database after this completes. All .pak/.modpak files will also
 * be loaded into the index.
 *
 * The virtual path argument is a prefix for the entries in the directory.
 */
AssetsManager.prototype.addDirectory = function (path, dirEntry, callback) {
  var self = this;

  var pending = 1;
  var decrementPending = function () {
    pending--;
    if (!pending) {
      callback(null);
    }
  };

  var reader = dirEntry.createReader();
  var next = function () {
    reader.readEntries(function (entries) {
      if (!entries.length) {
        process.nextTick(decrementPending);
        return;
      }

      entries.forEach(function (entry) {
        if (entry.name[0] == '.') return;

        var entryPath = path + '/' + entry.name;

        if (entry.isDirectory) {
          pending++;
          self.addDirectory(entryPath, entry, decrementPending);
        } else {
          pending++;
          entry.file(function (file) {
            self.addFile(entryPath, file, decrementPending);
          }, decrementPending);
        }
      });
      next();
    });
  };
  next();
};

AssetsManager.prototype.addFile = function (path, file, callback) {
  // TODO: What to do about the callback being called once for each worker?
  this.api.addFile.broadcast(path, file, callback);
};

AssetsManager.prototype.addRoot = function (dirEntry, callback) {
  this.addDirectory('', dirEntry, callback);
};

AssetsManager.prototype.emitOncePerTick = function (event) {
  if (this._emitting[event]) return;
  this._emitting[event] = true;

  var self = this, args = Array.prototype.slice.call(arguments);
  process.nextTick(function () {
    self.emit.apply(self, args);
    delete self._emitting[event];
  });
};

AssetsManager.prototype.getBlobURL = function (path, callback) {
  if (path in this._blobCache) {
    callback(null, this._blobCache[path]);
    return;
  }

  var self = this;
  this.api.getBlobURL(path, function (err, url) {
    if (!err) self._blobCache[path] = url;
    callback(err, url);
  });
};

AssetsManager.prototype.getFrames = function (imagePath) {
  var dotOffset = imagePath.lastIndexOf('.');
  var path = imagePath.substr(0, dotOffset) + '.frames';

  if (path in this._framesCache) return this._framesCache[path];
  this._framesCache[path] = null;

  var self = this;
  this.api.getJSON(path, function (err, frames) {
    if (err) {
      console.error(err.stack);
      return;
    }

    self._framesCache[path] = frames;
  });

  return null;
};

/**
 * Gets the image for the specified path. This function is synchronous, but may
 * depend on asynchronous operations. If the image is not immediately available
 * this function will return null. Once more images are available, an "images"
 * event will be emitted.
 */
AssetsManager.prototype.getImage = function (path) {
  // Example path: "/directory/image.png?hueshift=60?fade=ffffff=0.1"
  if (path in this._imageCache) return this._imageCache[path];

  var self = this;

  // Extract image operations.
  var ops = path.split('?');
  // Get the plain path to the image file.
  var filePath = ops.shift();

  // If the image is not in the cache, load it and trigger an "images" event
  // when it's done.
  if (!(filePath in this._imageCache)) {
    this._imageCache[filePath] = null;

    this.getBlobURL(filePath, function (err, url) {
      if (err) {
        console.warn('Failed to load %s (%s)', filePath, err.message);
        return;
      }

      var image = new Image();
      image.src = url;
      image.onload = function () {
        self._imageCache[filePath] = image;
        self.emitOncePerTick('images');
      };
    });
  }

  var image = this._imageCache[filePath];
  if (!image) return null;

  // Apply operations (such as hue shift) on the image.
  var canvas = document.createElement('canvas');
  canvas.width = image.width;
  canvas.height = image.height;

  // Parse all the operations to be applied to the image.
  // TODO: addmask, brightness, fade, replace, saturation
  var hue = 0, flipEveryX = 0, replace;
  for (var i = 0; i < ops.length; i++) {
    var op = ops[i].split(/[=;]/);
    switch (op[0]) {
      // This operation doesn't exist in Starbound, but is helpful for us.
      case 'flipgridx':
        flipEveryX = parseInt(op[1]);
        if (image.width % flipEveryX) {
          console.warn(image.width + ' not divisible by ' + flipEveryX + ' (' + path + ')');
        }
        break;
      case 'hueshift':
        hue = parseFloat(op[1]);
        break;
      case 'replace':
        if (!replace) replace = {};
        for (var i = 1; i < op.length; i += 2) {
          var from = [
            parseInt(op[i].substr(0, 2), 16),
            parseInt(op[i].substr(2, 2), 16),
            parseInt(op[i].substr(4, 2), 16)
          ];

          var to = [
            parseInt(op[i + 1].substr(0, 2), 16),
            parseInt(op[i + 1].substr(2, 2), 16),
            parseInt(op[i + 1].substr(4, 2), 16)
          ];

          replace[from] = to;
        }
        break;
      default:
        console.warn('Unsupported image operation:', op);
    }
  }

  var context = canvas.getContext('2d');

  if (flipEveryX) {
    context.save();
    context.scale(-1, 1);
    for (var x = 0; x + flipEveryX <= image.width; x += flipEveryX) {
      var flippedX = -(x + flipEveryX), dw = flipEveryX, dh = image.height;
      context.drawImage(image, x, 0, dw, dh, flippedX, 0, dw, dh);
    }
    context.restore();
  } else {
    context.drawImage(image, 0, 0);
  }

  if (hue || replace) {
    var imageData = context.getImageData(0, 0, image.width, image.height),
        data = imageData.data;
    for (var i = 0; i < data.length; i += 4) {
      if (replace) {
        var color = replace[data[i] + ',' + data[i + 1] + ',' + data[i + 2]];
        if (color) {
          data[i] = color[0];
          data[i + 1] = color[1];
          data[i + 2] = color[2];
        }
      }

      if (hue) {
        hsv = convert.rgb2hsv(data[i], data[i + 1], data[i + 2]);

        hsv[0] += hue;
        if (hsv[0] < 0) hsv[0] += 360
        else if (hsv[0] >= 360) hsv[0] -= 360;

        rgb = convert.hsv2rgb(hsv);

        data[i] = rgb[0];
        data[i + 1] = rgb[1];
        data[i + 2] = rgb[2];
      }
    }
    context.putImageData(imageData, 0, 0);
  }

  self._imageCache[path] = null;

  // Create a new object for the modified image and cache it.
  image = new Image();
  image.onload = function () {
    self._imageCache[path] = image;
    self.emitOncePerTick('images');
  };
  image.src = canvas.toDataURL();

  return null;
};

AssetsManager.prototype.getResourceLoader = function (extension) {
  return new ResourceLoader(this, extension);
};

AssetsManager.prototype.getResourcePath = function (resource, path) {
  if (path[0] == '/') return path;
  var base = resource.__path__;
  return base.substr(0, base.lastIndexOf('/') + 1) + path;
};

AssetsManager.prototype.getTileImage = function (resource, field, opt_hueShift) {
  path = this.getResourcePath(resource, resource[field]);

  // Add hueshift image operation if needed.
  if (opt_hueShift) {
    path += '?hueshift=' + (opt_hueShift / 255 * 360);
  }

  return this.getImage(path);
};

AssetsManager.prototype.loadResources = function (extension, callback) {
  var self = this;
  this.api.loadResources(extension, function (err, resources) {
    callback(err, resources);
    if (!err) {
      self.emitOncePerTick('resources');
    }
  });
};
<commit_msg>Add error for rare corner case<commit_after>var convert = require('color-convert');
var EventEmitter = require('events');
var merge = require('merge');
var util = require('util');
var workerproxy = require('workerproxy');

var ResourceLoader = require('./resourceloader');

module.exports = AssetsManager;

function AssetsManager(opt_options) {
  EventEmitter.call(this);

  var options = {
    workerPath: __dirname + '/../worker.js',
    workers: 1
  };

  Object.seal(options);
  merge(options, opt_options);
  Object.freeze(options);

  this.options = options;

  // Create the number of workers specified in options.
  var workers = [];
  for (var i = 0; i < options.workers; i++) {
    workers.push(new Worker(options.workerPath));
  }

  // Create a proxy which will handle delegation to the workers.
  this.api = workerproxy(workers);

  this._emitting = {};
  this._blobCache = Object.create(null);
  // TODO: Make a more generic cache?
  this._framesCache = Object.create(null);
  this._imageCache = Object.create(null);
}
util.inherits(AssetsManager, EventEmitter);

/**
 * Indexes a directory. All files in the directory will be reachable through
 * the assets database after this completes. All .pak/.modpak files will also
 * be loaded into the index.
 *
 * The virtual path argument is a prefix for the entries in the directory.
 */
AssetsManager.prototype.addDirectory = function (path, dirEntry, callback) {
  var self = this;

  var pending = 1;
  var decrementPending = function () {
    pending--;
    if (!pending) {
      callback(null);
    }
  };

  var reader = dirEntry.createReader();
  var next = function () {
    reader.readEntries(function (entries) {
      if (!entries.length) {
        process.nextTick(decrementPending);
        return;
      }

      entries.forEach(function (entry) {
        if (entry.name[0] == '.') return;

        var entryPath = path + '/' + entry.name;

        if (entry.isDirectory) {
          pending++;
          self.addDirectory(entryPath, entry, decrementPending);
        } else {
          pending++;
          entry.file(function (file) {
            self.addFile(entryPath, file, decrementPending);
          }, decrementPending);
        }
      });
      next();
    });
  };
  next();
};

AssetsManager.prototype.addFile = function (path, file, callback) {
  // TODO: What to do about the callback being called once for each worker?
  this.api.addFile.broadcast(path, file, callback);
};

AssetsManager.prototype.addRoot = function (dirEntry, callback) {
  this.addDirectory('', dirEntry, callback);
};

AssetsManager.prototype.emitOncePerTick = function (event) {
  if (this._emitting[event]) return;
  this._emitting[event] = true;

  var self = this, args = Array.prototype.slice.call(arguments);
  process.nextTick(function () {
    self.emit.apply(self, args);
    delete self._emitting[event];
  });
};

AssetsManager.prototype.getBlobURL = function (path, callback) {
  if (path in this._blobCache) {
    callback(null, this._blobCache[path]);
    return;
  }

  var self = this;
  this.api.getBlobURL(path, function (err, url) {
    if (!err) self._blobCache[path] = url;
    callback(err, url);
  });
};

AssetsManager.prototype.getFrames = function (imagePath) {
  var dotOffset = imagePath.lastIndexOf('.');
  var path = imagePath.substr(0, dotOffset) + '.frames';

  if (path in this._framesCache) return this._framesCache[path];
  this._framesCache[path] = null;

  var self = this;
  this.api.getJSON(path, function (err, frames) {
    if (err) {
      console.error(err.stack);
      return;
    }

    self._framesCache[path] = frames;
  });

  return null;
};

/**
 * Gets the image for the specified path. This function is synchronous, but may
 * depend on asynchronous operations. If the image is not immediately available
 * this function will return null. Once more images are available, an "images"
 * event will be emitted.
 */
AssetsManager.prototype.getImage = function (path) {
  // Example path: "/directory/image.png?hueshift=60?fade=ffffff=0.1"
  if (path in this._imageCache) return this._imageCache[path];

  var self = this;

  // Extract image operations.
  var ops = path.split('?');
  // Get the plain path to the image file.
  var filePath = ops.shift();

  // If the image is not in the cache, load it and trigger an "images" event
  // when it's done.
  if (!(filePath in this._imageCache)) {
    this._imageCache[filePath] = null;

    this.getBlobURL(filePath, function (err, url) {
      if (err) {
        console.warn('Failed to load %s (%s)', filePath, err.message);
        return;
      }

      var image = new Image();
      image.src = url;
      image.onload = function () {
        self._imageCache[filePath] = image;
        self.emitOncePerTick('images');
      };
    });
  }

  var image = this._imageCache[filePath];
  if (!image) return null;

  // Apply operations (such as hue shift) on the image.
  var canvas = document.createElement('canvas');
  canvas.width = image.width;
  canvas.height = image.height;

  // Parse all the operations to be applied to the image.
  // TODO: addmask, brightness, fade, replace, saturation
  var hue = 0, flipEveryX = 0, replace;
  for (var i = 0; i < ops.length; i++) {
    var op = ops[i].split(/[=;]/);
    switch (op[0]) {
      // This operation doesn't exist in Starbound, but is helpful for us.
      case 'flipgridx':
        flipEveryX = parseInt(op[1]);
        if (image.width % flipEveryX) {
          console.warn(image.width + ' not divisible by ' + flipEveryX + ' (' + path + ')');
        }
        break;
      case 'hueshift':
        hue = parseFloat(op[1]);
        break;
      case 'replace':
        if (!replace) replace = {};
        for (var i = 1; i < op.length; i += 2) {
          var from = [
            parseInt(op[i].substr(0, 2), 16),
            parseInt(op[i].substr(2, 2), 16),
            parseInt(op[i].substr(4, 2), 16)
          ];

          var to = [
            parseInt(op[i + 1].substr(0, 2), 16),
            parseInt(op[i + 1].substr(2, 2), 16),
            parseInt(op[i + 1].substr(4, 2), 16)
          ];

          replace[from] = to;
        }
        break;
      default:
        console.warn('Unsupported image operation:', op);
    }
  }

  var context = canvas.getContext('2d');

  if (flipEveryX) {
    context.save();
    context.scale(-1, 1);
    for (var x = 0; x + flipEveryX <= image.width; x += flipEveryX) {
      var flippedX = -(x + flipEveryX), dw = flipEveryX, dh = image.height;
      context.drawImage(image, x, 0, dw, dh, flippedX, 0, dw, dh);
    }
    context.restore();
  } else {
    context.drawImage(image, 0, 0);
  }

  if (hue || replace) {
    var imageData = context.getImageData(0, 0, image.width, image.height),
        data = imageData.data;
    for (var i = 0; i < data.length; i += 4) {
      if (replace) {
        var color = replace[data[i] + ',' + data[i + 1] + ',' + data[i + 2]];
        if (color) {
          data[i] = color[0];
          data[i + 1] = color[1];
          data[i + 2] = color[2];
        }
      }

      if (hue) {
        hsv = convert.rgb2hsv(data[i], data[i + 1], data[i + 2]);

        hsv[0] += hue;
        if (hsv[0] < 0) hsv[0] += 360
        else if (hsv[0] >= 360) hsv[0] -= 360;

        rgb = convert.hsv2rgb(hsv);

        data[i] = rgb[0];
        data[i + 1] = rgb[1];
        data[i + 2] = rgb[2];
      }
    }
    context.putImageData(imageData, 0, 0);
  }

  self._imageCache[path] = null;

  // Create a new object for the modified image and cache it.
  image = new Image();
  image.onload = function () {
    self._imageCache[path] = image;
    self.emitOncePerTick('images');
  };
  image.src = canvas.toDataURL();

  return null;
};

AssetsManager.prototype.getResourceLoader = function (extension) {
  return new ResourceLoader(this, extension);
};

AssetsManager.prototype.getResourcePath = function (resource, path) {
  if (path[0] == '/') return path;
  var base = resource.__path__;
  return base.substr(0, base.lastIndexOf('/') + 1) + path;
};

AssetsManager.prototype.getTileImage = function (resource, field, opt_hueShift) {
  if (!(field in resource)) {
    throw new Error('Field "' + field + '" not in resource: ' + JSON.stringify(resource));
  }

  path = this.getResourcePath(resource, resource[field]);

  // Add hueshift image operation if needed.
  if (opt_hueShift) {
    path += '?hueshift=' + (opt_hueShift / 255 * 360);
  }

  return this.getImage(path);
};

AssetsManager.prototype.loadResources = function (extension, callback) {
  var self = this;
  this.api.loadResources(extension, function (err, resources) {
    callback(err, resources);
    if (!err) {
      self.emitOncePerTick('resources');
    }
  });
};
<|endoftext|>


<commit_before>var _ = require('underscore');

var fs = require('fs');
var cp = require('child_process');

var yaml = require('js-yaml');

var openssl = require('openssl-wrapper');

var clr = require('colors');
var inspect = require('util').inspect;

var util = require('./util.js');

var coreos_image_ids = {
  'stable': '2b171e93f07c4903bcad35bda10acf22__CoreOS-Stable-717.3.0',
  'beta': '2b171e93f07c4903bcad35bda10acf22__CoreOS-Beta-723.3.0', // untested
  'alpha': '2b171e93f07c4903bcad35bda10acf22__CoreOS-Alpha-745.1.0' // untested
};

var conf = {};

var hosts = {
  collection: [],
  ssh_port_counter: 2200,
};

var task_queue = [];

exports.run_task_queue = function (dummy) {
  var tasks = {
    todo: task_queue,
    done: [],
  };

  var pop_task = function() {
    console.log(clr.yellow('azure_wrapper/task:'), clr.grey(inspect(tasks)));
    var ret = {};
    ret.current = tasks.todo.shift();
    ret.remaining = tasks.todo.length;
    return ret;
  };

  (function iter (task) {
    if (task.current === undefined) {
      if (conf.destroying === undefined) {
        create_ssh_conf();
        save_state();
      }
      return;
    } else {
      if (task.current.length !== 0) {
        console.log(clr.yellow('azure_wrapper/exec:'), clr.blue(inspect(task.current)));
        cp.fork('node_modules/azure-cli/bin/azure', task.current)
          .on('exit', function (code, signal) {
            tasks.done.push({
              code: code,
              signal: signal,
              what: task.current.join(' '),
              remaining: task.remaining,
            });
            if (code !== 0 && conf.destroying === undefined) {
              console.log(clr.red('azure_wrapper/fail: Exiting due to an error.'));
              save_state();
              console.log(clr.cyan('azure_wrapper/info: You probably want to destroy and re-run.'));
              process.abort();
            } else {
              iter(pop_task());
            }
        });
      } else {
        iter(pop_task());
      }
    }
  })(pop_task());
};

var save_state = function () {
  var file_name = util.join_output_file_path(conf.name, 'deployment.yml');
  try {
    conf.hosts = hosts.collection;
    fs.writeFileSync(file_name, yaml.safeDump(conf));
    console.log(clr.yellow('azure_wrapper/info: Saved state into `%s`'), file_name);
  } catch (e) {
    console.log(clr.red(e));
  }
};

var load_state = function (file_name) {
  try {
    conf = yaml.safeLoad(fs.readFileSync(file_name, 'utf8'));
    console.log(clr.yellow('azure_wrapper/info: Loaded state from `%s`'), file_name);
    return conf;
  } catch (e) {
    console.log(clr.red(e));
  }
};

var create_ssh_key = function (prefix) {
  var opts = {
    x509: true,
    nodes: true,
    newkey: 'rsa:2048',
    subj: '/O=Weaveworks, Inc./L=London/C=GB/CN=weave.works',
    keyout: util.join_output_file_path(prefix, 'ssh.key'),
    out: util.join_output_file_path(prefix, 'ssh.pem'),
  };
  openssl.exec('req', opts, function (err, buffer) {
    if (err) console.log(clr.red(err));
    openssl.exec('rsa', { in: opts.keyout, out: opts.keyout }, function (err, buffer) {
       if (err) console.log(clr.red(err));
    });
    fs.chmod(opts.keyout, '0600', function (err) {
      if (err) console.log(clr.red(err));
    });
  });
  return {
    key: opts.keyout,
    pem: opts.out,
  }
}

var create_ssh_conf = function () {
  var file_name = util.join_output_file_path(conf.name, 'ssh_conf');
  var ssh_conf_head = [
    "Host *",
    "\tHostname " + conf.resources['service'] + ".cloudapp.net",
    "\tUser core",
    "\tCompression yes",
    "\tLogLevel FATAL",
    "\tStrictHostKeyChecking no",
    "\tUserKnownHostsFile /dev/null",
    "\tIdentitiesOnly yes",
    "\tIdentityFile " + conf.resources['ssh_key']['key'],
    "\n",
  ];

  fs.writeFileSync(file_name, ssh_conf_head.concat(_.map(hosts.collection, function (host) {
    return _.template("Host <%= name %>\n\tPort <%= port %>\n")(host);
  })).join('\n'));
  console.log(clr.yellow('azure_wrapper/info:'), clr.green('Saved SSH config, you can use it like so: `ssh -F ', file_name, '<hostname>`'));
  console.log(clr.yellow('azure_wrapper/info:'), clr.green('The hosts in this deployment are:\n'), _.map(hosts.collection, function (host) { return host.name; }));
};

var get_location = function () {
  if (process.env['AZ_AFFINITY']) {
    return '--affinity-group=' + process.env['AZ_AFFINITY'];
  } else if (process.env['AZ_LOCATION']) {
    return '--location=' + process.env['AZ_LOCATION'];
  } else {
    return '--location=West Europe';
  }
}
var get_vm_size = function () {
  if (process.env['AZ_VM_SIZE']) {
    return '--vm-size=' + process.env['AZ_VM_SIZE'];
  } else {
    return '--vm-size=Small';
  }
}

exports.queue_default_network = function () {
  task_queue.push([
    'network', 'vnet', 'create',
    get_location(),
    '--address-space=172.16.0.0',
    conf.resources['vnet'],
  ]);
}

exports.queue_storage_if_needed = function() {
  if (!process.env['AZURE_STORAGE_ACCOUNT']) {
    conf.resources['storage_account'] = util.rand_suffix;
    task_queue.push([
      'storage', 'account', 'create',
      '--type=LRS',
      get_location(),
      conf.resources['storage_account'],
    ]);
    process.env['AZURE_STORAGE_ACCOUNT'] = conf.resources['storage_account'];
  } else {
    // Preserve it for resizing, so we don't create a new one by accedent,
    // when the environment variable is unset
    conf.resources['storage_account'] = process.env['AZURE_STORAGE_ACCOUNT'];
  }
};

exports.queue_machines = function (name_prefix, coreos_update_channel, cloud_config_creator) {
  var x = conf.nodes[name_prefix];
  var vm_create_base_args = [
    'vm', 'create',
    get_location(),
    get_vm_size(),
    '--connect=' + conf.resources['service'],
    '--virtual-network-name=' + conf.resources['vnet'],
    '--no-ssh-password',
    '--ssh-cert=' + conf.resources['ssh_key']['pem'],
  ];

  var cloud_config = cloud_config_creator(x, conf);

  var next_host = function (n) {
    hosts.ssh_port_counter += 1;
    var host = { name: util.hostname(n, name_prefix), port: hosts.ssh_port_counter };
    if (cloud_config instanceof Array) {
      host.cloud_config_file = cloud_config[n];
    } else {
      host.cloud_config_file = cloud_config;
    }
    hosts.collection.push(host);
    return _.map([
        "--vm-name=<%= name %>",
        "--ssh=<%= port %>",
        "--custom-data=<%= cloud_config_file %>",
    ], function (arg) { return _.template(arg)(host); });
  };

  task_queue = task_queue.concat(_(x).times(function (n) {
    if (conf.resizing && n < conf.old_size) {
      return [];
    } else {
      return vm_create_base_args.concat(next_host(n), [
        coreos_image_ids[coreos_update_channel], 'core',
      ]);
    }
  }));
};

exports.create_config = function (name, nodes) {
  conf = {
    name: name,
    nodes: nodes,
    weave_salt: util.rand_string(),
    resources: {
      vnet: [name, 'internal-vnet', util.rand_suffix].join('-'),
      service: [name, util.rand_suffix].join('-'),
      ssh_key: create_ssh_key(name),
    }
  };

};

exports.destroy_cluster = function (state_file) {
  load_state(state_file);
  if (conf.hosts === undefined) {
    console.log(clr.red('azure_wrapper/fail: Nothing to delete.'));
    process.abort();
  }

  conf.destroying = true;
  task_queue = _.map(conf.hosts, function (host) {
    return ['vm', 'delete', '--quiet', '--blob-delete', host.name];
  });

  task_queue.push(['network', 'vnet', 'delete', '--quiet', conf.resources['vnet']]);
  task_queue.push(['storage', 'account', 'delete', '--quiet', conf.resources['storage_account']]);

  exports.run_task_queue();
};

exports.load_state_for_resizing = function (state_file, node_type, new_nodes) {
  load_state(state_file);
  if (conf.hosts === undefined) {
    console.log(clr.red('azure_wrapper/fail: Nothing to look at.'));
    process.abort();
  }
  conf.resizing = true;
  conf.old_size = conf.nodes[node_type];
  conf.old_state_file = state_file;
  conf.nodes[node_type] += new_nodes;
  hosts.collection = conf.hosts;
  hosts.ssh_port_counter += conf.hosts.length;
  process.env['AZURE_STORAGE_ACCOUNT'] = conf.resources['storage_account'];
}
<commit_msg>moved fs.chmod into openssl rsa callback function<commit_after>var _ = require('underscore');

var fs = require('fs');
var cp = require('child_process');

var yaml = require('js-yaml');

var openssl = require('openssl-wrapper');

var clr = require('colors');
var inspect = require('util').inspect;

var util = require('./util.js');

var coreos_image_ids = {
  'stable': '2b171e93f07c4903bcad35bda10acf22__CoreOS-Stable-717.3.0',
  'beta': '2b171e93f07c4903bcad35bda10acf22__CoreOS-Beta-723.3.0', // untested
  'alpha': '2b171e93f07c4903bcad35bda10acf22__CoreOS-Alpha-745.1.0' // untested
};

var conf = {};

var hosts = {
  collection: [],
  ssh_port_counter: 2200,
};

var task_queue = [];

exports.run_task_queue = function (dummy) {
  var tasks = {
    todo: task_queue,
    done: [],
  };

  var pop_task = function() {
    console.log(clr.yellow('azure_wrapper/task:'), clr.grey(inspect(tasks)));
    var ret = {};
    ret.current = tasks.todo.shift();
    ret.remaining = tasks.todo.length;
    return ret;
  };

  (function iter (task) {
    if (task.current === undefined) {
      if (conf.destroying === undefined) {
        create_ssh_conf();
        save_state();
      }
      return;
    } else {
      if (task.current.length !== 0) {
        console.log(clr.yellow('azure_wrapper/exec:'), clr.blue(inspect(task.current)));
        cp.fork('node_modules/azure-cli/bin/azure', task.current)
          .on('exit', function (code, signal) {
            tasks.done.push({
              code: code,
              signal: signal,
              what: task.current.join(' '),
              remaining: task.remaining,
            });
            if (code !== 0 && conf.destroying === undefined) {
              console.log(clr.red('azure_wrapper/fail: Exiting due to an error.'));
              save_state();
              console.log(clr.cyan('azure_wrapper/info: You probably want to destroy and re-run.'));
              process.abort();
            } else {
              iter(pop_task());
            }
        });
      } else {
        iter(pop_task());
      }
    }
  })(pop_task());
};

var save_state = function () {
  var file_name = util.join_output_file_path(conf.name, 'deployment.yml');
  try {
    conf.hosts = hosts.collection;
    fs.writeFileSync(file_name, yaml.safeDump(conf));
    console.log(clr.yellow('azure_wrapper/info: Saved state into `%s`'), file_name);
  } catch (e) {
    console.log(clr.red(e));
  }
};

var load_state = function (file_name) {
  try {
    conf = yaml.safeLoad(fs.readFileSync(file_name, 'utf8'));
    console.log(clr.yellow('azure_wrapper/info: Loaded state from `%s`'), file_name);
    return conf;
  } catch (e) {
    console.log(clr.red(e));
  }
};

var create_ssh_key = function (prefix) {
  var opts = {
    x509: true,
    nodes: true,
    newkey: 'rsa:2048',
    subj: '/O=Weaveworks, Inc./L=London/C=GB/CN=weave.works',
    keyout: util.join_output_file_path(prefix, 'ssh.key'),
    out: util.join_output_file_path(prefix, 'ssh.pem'),
  };
  openssl.exec('req', opts, function (err, buffer) {
    if (err) console.log(clr.red(err));
    openssl.exec('rsa', { in: opts.keyout, out: opts.keyout }, function (err, buffer) {
      if (err) console.log(clr.red(err));
      fs.chmod(opts.keyout, '0600', function (err) {
        if (err) console.log(clr.red(err));
      });
    });
  });
  return {
    key: opts.keyout,
    pem: opts.out,
  }
}

var create_ssh_conf = function () {
  var file_name = util.join_output_file_path(conf.name, 'ssh_conf');
  var ssh_conf_head = [
    "Host *",
    "\tHostname " + conf.resources['service'] + ".cloudapp.net",
    "\tUser core",
    "\tCompression yes",
    "\tLogLevel FATAL",
    "\tStrictHostKeyChecking no",
    "\tUserKnownHostsFile /dev/null",
    "\tIdentitiesOnly yes",
    "\tIdentityFile " + conf.resources['ssh_key']['key'],
    "\n",
  ];

  fs.writeFileSync(file_name, ssh_conf_head.concat(_.map(hosts.collection, function (host) {
    return _.template("Host <%= name %>\n\tPort <%= port %>\n")(host);
  })).join('\n'));
  console.log(clr.yellow('azure_wrapper/info:'), clr.green('Saved SSH config, you can use it like so: `ssh -F ', file_name, '<hostname>`'));
  console.log(clr.yellow('azure_wrapper/info:'), clr.green('The hosts in this deployment are:\n'), _.map(hosts.collection, function (host) { return host.name; }));
};

var get_location = function () {
  if (process.env['AZ_AFFINITY']) {
    return '--affinity-group=' + process.env['AZ_AFFINITY'];
  } else if (process.env['AZ_LOCATION']) {
    return '--location=' + process.env['AZ_LOCATION'];
  } else {
    return '--location=West Europe';
  }
}
var get_vm_size = function () {
  if (process.env['AZ_VM_SIZE']) {
    return '--vm-size=' + process.env['AZ_VM_SIZE'];
  } else {
    return '--vm-size=Small';
  }
}

exports.queue_default_network = function () {
  task_queue.push([
    'network', 'vnet', 'create',
    get_location(),
    '--address-space=172.16.0.0',
    conf.resources['vnet'],
  ]);
}

exports.queue_storage_if_needed = function() {
  if (!process.env['AZURE_STORAGE_ACCOUNT']) {
    conf.resources['storage_account'] = util.rand_suffix;
    task_queue.push([
      'storage', 'account', 'create',
      '--type=LRS',
      get_location(),
      conf.resources['storage_account'],
    ]);
    process.env['AZURE_STORAGE_ACCOUNT'] = conf.resources['storage_account'];
  } else {
    // Preserve it for resizing, so we don't create a new one by accedent,
    // when the environment variable is unset
    conf.resources['storage_account'] = process.env['AZURE_STORAGE_ACCOUNT'];
  }
};

exports.queue_machines = function (name_prefix, coreos_update_channel, cloud_config_creator) {
  var x = conf.nodes[name_prefix];
  var vm_create_base_args = [
    'vm', 'create',
    get_location(),
    get_vm_size(),
    '--connect=' + conf.resources['service'],
    '--virtual-network-name=' + conf.resources['vnet'],
    '--no-ssh-password',
    '--ssh-cert=' + conf.resources['ssh_key']['pem'],
  ];

  var cloud_config = cloud_config_creator(x, conf);

  var next_host = function (n) {
    hosts.ssh_port_counter += 1;
    var host = { name: util.hostname(n, name_prefix), port: hosts.ssh_port_counter };
    if (cloud_config instanceof Array) {
      host.cloud_config_file = cloud_config[n];
    } else {
      host.cloud_config_file = cloud_config;
    }
    hosts.collection.push(host);
    return _.map([
        "--vm-name=<%= name %>",
        "--ssh=<%= port %>",
        "--custom-data=<%= cloud_config_file %>",
    ], function (arg) { return _.template(arg)(host); });
  };

  task_queue = task_queue.concat(_(x).times(function (n) {
    if (conf.resizing && n < conf.old_size) {
      return [];
    } else {
      return vm_create_base_args.concat(next_host(n), [
        coreos_image_ids[coreos_update_channel], 'core',
      ]);
    }
  }));
};

exports.create_config = function (name, nodes) {
  conf = {
    name: name,
    nodes: nodes,
    weave_salt: util.rand_string(),
    resources: {
      vnet: [name, 'internal-vnet', util.rand_suffix].join('-'),
      service: [name, util.rand_suffix].join('-'),
      ssh_key: create_ssh_key(name),
    }
  };

};

exports.destroy_cluster = function (state_file) {
  load_state(state_file);
  if (conf.hosts === undefined) {
    console.log(clr.red('azure_wrapper/fail: Nothing to delete.'));
    process.abort();
  }

  conf.destroying = true;
  task_queue = _.map(conf.hosts, function (host) {
    return ['vm', 'delete', '--quiet', '--blob-delete', host.name];
  });

  task_queue.push(['network', 'vnet', 'delete', '--quiet', conf.resources['vnet']]);
  task_queue.push(['storage', 'account', 'delete', '--quiet', conf.resources['storage_account']]);

  exports.run_task_queue();
};

exports.load_state_for_resizing = function (state_file, node_type, new_nodes) {
  load_state(state_file);
  if (conf.hosts === undefined) {
    console.log(clr.red('azure_wrapper/fail: Nothing to look at.'));
    process.abort();
  }
  conf.resizing = true;
  conf.old_size = conf.nodes[node_type];
  conf.old_state_file = state_file;
  conf.nodes[node_type] += new_nodes;
  hosts.collection = conf.hosts;
  hosts.ssh_port_counter += conf.hosts.length;
  process.env['AZURE_STORAGE_ACCOUNT'] = conf.resources['storage_account'];
}
<|endoftext|>


<commit_before>'use strict'
var hash = require('../../util/hash')
/**
 * @property uid
 * injectable for generation of uids -- handy if you want weakmap-like behaviour
 * @memberOf Base#
 * @param {object} val
*/
exports.define = {
  uid: {
    get () {
      if (!this.hasOwnProperty('_uid')) {
        let parent = this
        let str = ''
        while (parent && parent.key) {
          str += parent.key
          parent = parent._parent
        }
        this._uid = '~' + str // hash // will create collisions -- so thats not so good -- make entry points on val?
      }
      return this._uid
    }
  },
  getHashedPath (cache) {
    if (this._context) {
      if (!cache) {
        cache = this.contextMap()
      }
      if (cache.val) {
        return cache.val
      }
      let parent = this
      let str = ''
      while (parent && parent.key) {
        str += parent.key
        let lparent = parent
        let cntx = parent._context
        let level = parent._contextLevel
        parent = parent.parent
        if (lparent._context !== cntx) {
          lparent._context = cntx || null
          lparent._contextLevel = level || null
        }
      }
      cache.val = '~' + str
      return cache.val
    } else {
      return this.uid
    }
  }
}
<commit_msg>hashed path uids<commit_after>'use strict'
var hash = require('../../util/hash')
/**
 * @property uid
 * injectable for generation of uids -- handy if you want weakmap-like behaviour
 * @memberOf Base#
 * @param {object} val
*/
exports.define = {
  uid: {
    get () {
      if (!this.hasOwnProperty('_uid')) {
        let parent = this
        let str = ''
        while (parent && parent.key) {
          str += parent.key
          parent = parent._parent
        }
        this._uid = hash(str) // hash // will create collisions -- so thats not so good -- make entry points on val?
      }
      return this._uid
    }
  },
  getHashedPath (cache) {
    if (this._context) {
      if (!cache) {
        cache = this.contextMap()
      }
      if (cache.val) {
        return cache.val
      }
      let parent = this
      let str = ''
      while (parent && parent.key) {
        str += parent.key
        let lparent = parent
        let cntx = parent._context
        let level = parent._contextLevel
        parent = parent.parent
        if (lparent._context !== cntx) {
          lparent._context = cntx || null
          lparent._contextLevel = level || null
        }
      }
      cache.val = hash(str)
      return cache.val
    } else {
      return this.uid
    }
  }
}
<|endoftext|>


<commit_before>/** @jsx React.DOM */

/*
 * billpanel
 * https://github.com//billpanel
 *
 * Copyright (c) 2014
 * Licensed under the MIT license.
 */

'use strict';

var React = require('react');

exports.initialize = function() {
    React.renderComponent(
        /* jshint ignore:start */
        React.DOM.h1(null ,  " Hello, world! " ),
        /* jshint ignore:end */
        document.querySelector('#content')
    );
};

exports.initialize();
<commit_msg>removed stuff<commit_after><|endoftext|>


<commit_before>require.define('lib/browser/graph', function (require, module) {
    var renderer = require('lib/browser/graph/renderer').renderer;

    function drawGraph() {
        var deps = window.deps,
            colors = {
                blue: '#3333FF',
                lightblue: '#487DFF',
                red: '#FF1717',
                green: '#07C500',
                grey: '#666666',
                lightgrey: '#CCCCCC'
            },
            nodes = {},
            count = 0,
            sys = arbor.ParticleSystem();

        function addNode(path, opts) {
            if (!nodes[path]) {
                count++;
                nodes[path] = {
                    id: count,
                    path: path
                };
                sys.addNode(nodes[path].id, opts)
            }
            return nodes[path];
        }

        function viewportHeight() {
            var dh = jQuery(document).height(),
                // TODO: this needs to be more linear (and not hacked out)
                h = parseInt(count / (count.toString().split('').length / 190), 10);
            return h > dh ? dh : h;
        }

        function viewportWidth() {
            var dw = jQuery(document).width(),
                // TODO: this needs to be more linear (and not hacked out)
                w = parseInt(count / (count.toString().split('').length / 190), 10);
            return w > dw ? dw : w;
        }

        Object.keys(deps).forEach(function (key) {
            var dep = deps[key],
                base = addNode(key, {
                    color: dep.external ? colors.lightblue : colors.grey,
                    title: key
                });

            dep.forEach(function (item) {
                var node = addNode(item.path, {
                    color: item.external ? colors.lightblue : colors.grey,
                    title: item.path
                });

                sys.addEdge(base.id, node.id, {
                    color: colors.lightgrey
                })
            })
        });

        jQuery('#viewport').attr({
            height: viewportHeight(),
            width: viewportWidth()
        });

        sys.parameters({stiffness: 100, repulsion: 1000, gravity: true, dt: 0.015});
        sys.renderer = renderer("#viewport")
    }

    module.exports.draw = drawGraph
});
<commit_msg>The hacky width/height calculation (while graphing) is a lost cause.<commit_after>require.define('lib/browser/graph', function (require, module) {
    var renderer = require('lib/browser/graph/renderer').renderer;

    function drawGraph() {
        var deps = window.deps,
            colors = {
                blue: '#3333FF',
                lightblue: '#487DFF',
                red: '#FF1717',
                green: '#07C500',
                grey: '#666666',
                lightgrey: '#CCCCCC'
            },
            nodes = {},
            count = 0,
            sys = arbor.ParticleSystem();

        function addNode(path, opts) {
            if (!nodes[path]) {
                count++;
                nodes[path] = {
                    id: count,
                    path: path
                };
                sys.addNode(nodes[path].id, opts)
            }
            return nodes[path];
        }

        Object.keys(deps).forEach(function (key) {
            var dep = deps[key],
                base = addNode(key, {
                    color: dep.external ? colors.lightblue : colors.grey,
                    title: key
                });

            dep.forEach(function (item) {
                var node = addNode(item.path, {
                    color: item.external ? colors.lightblue : colors.grey,
                    title: item.path
                });

                sys.addEdge(base.id, node.id, {
                    color: colors.lightgrey
                })
            })
        });

        jQuery('#viewport').attr({
            height: (jQuery(document).height() - 5) + "px",
            width: (jQuery(document).width() - 5) + "px"
        });

        sys.parameters({stiffness: 100, repulsion: 1000, gravity: true, dt: 0.015});
        sys.renderer = renderer("#viewport")
    }

    module.exports.draw = drawGraph
});
<|endoftext|>


<commit_before>'use strict';

const mkdirp        = require('mkdirp');
const fs            = require('fs');
const crypto        = require('crypto');
const path          = require('path');
const { promisify } = require('util');
const gzip          = promisify(require('zlib').gzip);
const write         = promisify(require('write-file-atomic'));

const asset_classes = [
  require('./assets/concat'),
  require('./assets/lang'),
  require('./assets/file')
];

const plugins = [
  'load_bin',
  'load_text',
  'wrapper',
  'stylus',
  'less',
  'sass',
  'auto',
  'pug',
  'ejs',
  'handlebars',
  'macros',
  'autoprefixer',
  'terser',
  'clean-css'
].reduce((acc, name) => {
  acc[name] = require(path.join(__dirname, 'plugins', name));
  return acc;
}, {});

function Bundler(options) {
  if (!options) throw new Error('Bundler: missed constructor options');

  if (!options.root) throw new Error('Bundler: "root" should be defined');

  this.root = options.root;

  const opts = Object.assign({
    version: '',
    sourceMaps: true,
    compress: false
  }, options);

  this.version = opts.version;
  this.sourceMaps = opts.sourceMaps;
  this.compress = opts.compress;

  this.__assets_classes__ = {};
  this.__plugins__ = {};

  for (let cls of asset_classes) this.registerAssetClass(cls);
  for (let [ name, fn ] of Object.entries(plugins)) this.registerPlugin(name, fn);

  this.__helpers__ = {};
  this.__assets__ = {};

  this.cache = {
    get: (key, cb) => {
      cb();
    },
    put: (key, val, opt, cb) => {
      cb();
    }
  };
}

Bundler.prototype.registerHelper = function (name, fn) {
  this.__helpers__[name] = fn;
};

Bundler.prototype.registerPlugin = function (name, fn) {
  this.__plugins__[name] = fn;
};

Bundler.prototype.findAsset = function (path) {
  return this.__assets__[path];
};

Bundler.prototype.registerAssetClass = function (cls) {
  this.__assets_classes__[cls.type] = cls;
};

Bundler.prototype.createClass = function (name, options) {
  if (this.findAsset(options.logicalPath)) {
    throw new Error(`Bundler: asset "${options.logicalPath}" already exists`);
  }

  if (!this.__assets_classes__[name]) {
    throw new Error(`Bundler: asset class "${name}" not found`);
  }

  const asset = new this.__assets_classes__[name](this, options);

  this.__assets__[asset.logicalPath] = asset;

  return asset;
};

Object.defineProperty(Bundler.prototype, 'hasher', {
  get() {
    return crypto.createHash('md5').update(this.version, 'utf8');
  }
});

Bundler.prototype.getFileDigest = function (pathname) {
  const stat = this.stat(pathname);

  if (stat && stat.isDirectory()) {
    throw new Error(`Bundler: can't create digest on directory (${pathname})`);
  }

  // If file, digest the contents
  return this.hasher.update(this.readFile(pathname) || '').digest('hex');
};

Bundler.prototype.stat = function (pathname) {
  try {
    return fs.statSync(pathname);
  } catch (err) {
    if (err.code !== 'ENOENT') { throw err; }
  }

  return null;
};

Bundler.prototype.readFile = function (filename, encoding) {
  encoding = encoding || null;
  try {
    return fs.readFileSync(filename, encoding);
  } catch (__) {}

  return null;
};

// Compile assets and create manifest file
//
Bundler.prototype.compile = async function () {
  // Resolve public assets only. Dependencies will ve resolved automatically.
  const public_assets = Object.values(this.__assets__).filter(asset => !asset.virtual);

  // Resolve public assets
  await Promise.all(public_assets.map(asset => asset.resolve()));

  // Write assets
  for (let asset of public_assets) {
    let target = path.join(this.root, asset.digestPath);

    try {
      fs.statSync(target);
      // if no error - file exists, skip
      continue;
    } catch (__) {}

    let buffer = asset.buffer;

    if (asset.sourceMap) {
      let comment;

      if (target.endsWith('.js')) {
        comment = Buffer.from('\n//# sourceMappingURL=' + path.basename(target) + '.map');
      } else if (target.endsWith('.css')) {
        comment = Buffer.from('\n/*# sourceMappingURL=' + path.basename(target) + '.map */');
      }

      if (comment) buffer = Buffer.concat([ buffer, comment ]);
    }

    mkdirp.sync(path.dirname(target));

    // Can be done in parallel

    await Promise.all([
      // Write asset
      write(target, buffer),

      // Write gzipped asset
      Promise.resolve().then(async () => {
        if (!this.compress) return;
        let res = await gzip(buffer);
        await write(target + '.gz', res);
      }),

      // Write source map
      Promise.resolve().then(async () => {
        let map = asset.sourceMap;

        if (!map) return;

        // eslint-disable-next-line func-style
        let patch_map_sources = map => {
          if (map.sections) {
            map.sections.forEach(s => patch_map_sources(s.map));
          } else {
            map.sources = map.sources.map(src => {
              if (src.startsWith(this.root)) {
                src = path.relative(this.root, src);

                let a = this.findAsset(src);
                if (!a) throw new Error(`Cannot find asset: ${src}`);

                // replace logicalPath for autogenerated assets with digestPath;
                // couldn't do it earlier because digest was not yet known
                src = path.resolve(this.root, a.digestPath);
              }

              // assume that assets are served as /assets/*.js,
              // and return relative path from root as `../nodeca_modules/nodeca.core/path/to/asset.js`
              return path.join('..', path.relative('./', src));
            });
          }
        };

        patch_map_sources(map);

        await write(target + '.map', JSON.stringify(map));
      })
    ]);
  }

  let manifest = {};

  for (let [ path, asset ] of Object.entries(this.__assets__)) {
    if (!asset.resolved) continue;
    if (asset.virtual) continue;

    manifest[path] = {
      virtual: asset.virtual,
      digest: asset.digest,
      //dependencies: asset.dependencies,
      digestPath: asset.digestPath
    };
  }

  return manifest;
};

Bundler.DependencyError = Bundler.prototype.DependencyError = require('./utils/dependency_error');

module.exports = Bundler;
<commit_msg>Drop unneeded promisify<commit_after>'use strict';

const mkdirp        = require('mkdirp');
const fs            = require('fs');
const crypto        = require('crypto');
const path          = require('path');
const { promisify } = require('util');
const gzip          = promisify(require('zlib').gzip);
const write         = require('write-file-atomic');

const asset_classes = [
  require('./assets/concat'),
  require('./assets/lang'),
  require('./assets/file')
];

const plugins = [
  'load_bin',
  'load_text',
  'wrapper',
  'stylus',
  'less',
  'sass',
  'auto',
  'pug',
  'ejs',
  'handlebars',
  'macros',
  'autoprefixer',
  'terser',
  'clean-css'
].reduce((acc, name) => {
  acc[name] = require(path.join(__dirname, 'plugins', name));
  return acc;
}, {});

function Bundler(options) {
  if (!options) throw new Error('Bundler: missed constructor options');

  if (!options.root) throw new Error('Bundler: "root" should be defined');

  this.root = options.root;

  const opts = Object.assign({
    version: '',
    sourceMaps: true,
    compress: false
  }, options);

  this.version = opts.version;
  this.sourceMaps = opts.sourceMaps;
  this.compress = opts.compress;

  this.__assets_classes__ = {};
  this.__plugins__ = {};

  for (let cls of asset_classes) this.registerAssetClass(cls);
  for (let [ name, fn ] of Object.entries(plugins)) this.registerPlugin(name, fn);

  this.__helpers__ = {};
  this.__assets__ = {};

  this.cache = {
    get: (key, cb) => {
      cb();
    },
    put: (key, val, opt, cb) => {
      cb();
    }
  };
}

Bundler.prototype.registerHelper = function (name, fn) {
  this.__helpers__[name] = fn;
};

Bundler.prototype.registerPlugin = function (name, fn) {
  this.__plugins__[name] = fn;
};

Bundler.prototype.findAsset = function (path) {
  return this.__assets__[path];
};

Bundler.prototype.registerAssetClass = function (cls) {
  this.__assets_classes__[cls.type] = cls;
};

Bundler.prototype.createClass = function (name, options) {
  if (this.findAsset(options.logicalPath)) {
    throw new Error(`Bundler: asset "${options.logicalPath}" already exists`);
  }

  if (!this.__assets_classes__[name]) {
    throw new Error(`Bundler: asset class "${name}" not found`);
  }

  const asset = new this.__assets_classes__[name](this, options);

  this.__assets__[asset.logicalPath] = asset;

  return asset;
};

Object.defineProperty(Bundler.prototype, 'hasher', {
  get() {
    return crypto.createHash('md5').update(this.version, 'utf8');
  }
});

Bundler.prototype.getFileDigest = function (pathname) {
  const stat = this.stat(pathname);

  if (stat && stat.isDirectory()) {
    throw new Error(`Bundler: can't create digest on directory (${pathname})`);
  }

  // If file, digest the contents
  return this.hasher.update(this.readFile(pathname) || '').digest('hex');
};

Bundler.prototype.stat = function (pathname) {
  try {
    return fs.statSync(pathname);
  } catch (err) {
    if (err.code !== 'ENOENT') { throw err; }
  }

  return null;
};

Bundler.prototype.readFile = function (filename, encoding) {
  encoding = encoding || null;
  try {
    return fs.readFileSync(filename, encoding);
  } catch (__) {}

  return null;
};

// Compile assets and create manifest file
//
Bundler.prototype.compile = async function () {
  // Resolve public assets only. Dependencies will ve resolved automatically.
  const public_assets = Object.values(this.__assets__).filter(asset => !asset.virtual);

  // Resolve public assets
  await Promise.all(public_assets.map(asset => asset.resolve()));

  // Write assets
  for (let asset of public_assets) {
    let target = path.join(this.root, asset.digestPath);

    try {
      fs.statSync(target);
      // if no error - file exists, skip
      continue;
    } catch (__) {}

    let buffer = asset.buffer;

    if (asset.sourceMap) {
      let comment;

      if (target.endsWith('.js')) {
        comment = Buffer.from('\n//# sourceMappingURL=' + path.basename(target) + '.map');
      } else if (target.endsWith('.css')) {
        comment = Buffer.from('\n/*# sourceMappingURL=' + path.basename(target) + '.map */');
      }

      if (comment) buffer = Buffer.concat([ buffer, comment ]);
    }

    mkdirp.sync(path.dirname(target));

    // Can be done in parallel

    await Promise.all([
      // Write asset
      write(target, buffer),

      // Write gzipped asset
      Promise.resolve().then(async () => {
        if (!this.compress) return;
        let res = await gzip(buffer);
        await write(target + '.gz', res);
      }),

      // Write source map
      Promise.resolve().then(async () => {
        let map = asset.sourceMap;

        if (!map) return;

        // eslint-disable-next-line func-style
        let patch_map_sources = map => {
          if (map.sections) {
            map.sections.forEach(s => patch_map_sources(s.map));
          } else {
            map.sources = map.sources.map(src => {
              if (src.startsWith(this.root)) {
                src = path.relative(this.root, src);

                let a = this.findAsset(src);
                if (!a) throw new Error(`Cannot find asset: ${src}`);

                // replace logicalPath for autogenerated assets with digestPath;
                // couldn't do it earlier because digest was not yet known
                src = path.resolve(this.root, a.digestPath);
              }

              // assume that assets are served as /assets/*.js,
              // and return relative path from root as `../nodeca_modules/nodeca.core/path/to/asset.js`
              return path.join('..', path.relative('./', src));
            });
          }
        };

        patch_map_sources(map);

        await write(target + '.map', JSON.stringify(map));
      })
    ]);
  }

  let manifest = {};

  for (let [ path, asset ] of Object.entries(this.__assets__)) {
    if (!asset.resolved) continue;
    if (asset.virtual) continue;

    manifest[path] = {
      virtual: asset.virtual,
      digest: asset.digest,
      //dependencies: asset.dependencies,
      digestPath: asset.digestPath
    };
  }

  return manifest;
};

Bundler.DependencyError = Bundler.prototype.DependencyError = require('./utils/dependency_error');

module.exports = Bundler;
<|endoftext|>


<commit_before>"use strict";

const handlebars = require("handlebars");

const packageJson = require("./package-json");

const indexFile = handlebars.compile(`import React from "react";
import { StyleSheet, Text } from "react-native";

const styles = StyleSheet.create({});

export default function {{{component}}} () {
  return <Text>{{{component}}}</Text>;
}
`);

const storyFile = handlebars.compile(`import "react-native";
import React from "react";
import { storiesOf } from "@storybook/react-native";
import {{{component}}} from "./{{{packageName}}}";

storiesOf("{{{component}}}", module).add("{{{component}}}", () =>
  <{{{component}}} />
);
`);

const testFile = handlebars.compile(`import "react-native";
import React from "react";
import {{{component}}} from "./{{{packageName}}}";
import renderer from "react-test-renderer";

it("renders correctly", () => {
  const tree = renderer.create(<{{{component}}} />).toJSON();

  expect(tree).to.exist;
});
`);

const packageJsonFile = (variables) =>
  JSON.stringify(packageJson(variables), null, 2);

module.exports = variables => [
  [ indexFile, variables.packageName + ".js" ],
  [ testFile, variables.packageName + ".test.js" ],
  [ storyFile, variables.packageName + ".stories.js" ],
  [ packageJsonFile, "package.json" ],
];

<commit_msg>fix: remove space before opening paren<commit_after>"use strict";

const handlebars = require("handlebars");

const packageJson = require("./package-json");

const indexFile = handlebars.compile(`import React from "react";
import { StyleSheet, Text } from "react-native";

const styles = StyleSheet.create({});

export default function {{{component}}}() {
  return <Text>{{{component}}}</Text>;
}
`);

const storyFile = handlebars.compile(`import "react-native";
import React from "react";
import { storiesOf } from "@storybook/react-native";
import {{{component}}} from "./{{{packageName}}}";

storiesOf("{{{component}}}", module).add("{{{component}}}", () =>
  <{{{component}}} />
);
`);

const testFile = handlebars.compile(`import "react-native";
import React from "react";
import {{{component}}} from "./{{{packageName}}}";
import renderer from "react-test-renderer";

it("renders correctly", () => {
  const tree = renderer.create(<{{{component}}} />).toJSON();

  expect(tree).to.exist;
});
`);

const packageJsonFile = (variables) =>
  JSON.stringify(packageJson(variables), null, 2);

module.exports = variables => [
  [ indexFile, variables.packageName + ".js" ],
  [ testFile, variables.packageName + ".test.js" ],
  [ storyFile, variables.packageName + ".stories.js" ],
  [ packageJsonFile, "package.json" ],
];

<|endoftext|>