<commit_before>'use strict';

function TaskListController($scope, $timeout, $state, tasks, NotifyingService, BoldedService,
                            MultipleSelectService, DiscussionsService, TasksService, ProjectsService, context,
                            UsersService, OfficeDocumentsService) {

    let me;
    UsersService.getMe().then(function(result) {
        me = result;
    });

    $scope.items = tasks.data || tasks;

    var subTasks = [];
    $scope.items.forEach(function (item) {
        if (item.subTasks && item.subTasks.length > 0) {
            return subTasks = subTasks.concat(item.subTasks.filter(function (subTask) {
                return subTask !== 'undefined';
            }));
        }
    });

    if(context.entityName !== 'my'){
        subTasks && subTasks.forEach(function (item) {
            $scope.items.push(item);
        });
    }

    $scope.loadNext = tasks.next;
    $scope.loadPrev = tasks.prev;

    $scope.entityName = 'tasks';
    $scope.entityRowTpl = '/icu/components/task-list/task-row.html';

    var creatingStatuses = {
        NotCreated: 0,
        Creating: 1,
        Created: 2
    };

    $scope.getBoldedClass = function(entity){
        return BoldedService.getBoldedClass(entity, 'tasks');
    };

    $scope.update = function(item) {
        return TasksService.update(item);
    };

    $scope.create = function(parent) {
        var newItem = {
            title: '',
            watchers: [],
            tags: [],
            __state: creatingStatuses.NotCreated,
            __autocomplete: false
        };
        if(parent){
            newItem[parent.type] = parent.id;
        }
        return TasksService.create(newItem).then(function(result) {
            $scope.items.push(result);
            TasksService.data.push(result);
            return result;
        }).then( item => {
            let updated = false;
            if(parent && parent.type === 'project') {
                return ProjectsService.getById(context.entityId)
                    .then((parentEntity) => {
                      let parentParams = _.pick(parentEntity, ['watchers', 'permissions']);
                      Object.assign(item, parentParams);
                      updated = !updated;
                      return {item, updated};
                    }).then( res => {
                  if(res.updated)TasksService.update(res.item);
                    return res.item;
                } );
            } else if(parent && parent.type === 'officeDocument'){
                OfficeDocumentsService.getById(context.entityId)
                    .then(parentEntity => {
                        parentEntity.tasks = parentEntity.tasks ||  [];
                        parentEntity.tasks.push(item._id);

                        let context = {
                            name: "tasks",
                            newVal: parentEntity.tasks
                        };
                        OfficeDocumentsService.updateDocument(parentEntity._id, context);
                    })
            }
            return item;
        })
    };

    $scope.getFilter = function() {
        var a = TasksService.filterValue;
        switch (a) {
        case 'today':
            return 'tasksDueToday';
        case 'week':
            return 'tasksDueThisWeek';
        case 'watched':
            return 'watchedTasks';
        case 'overdue':
            return 'overdueTasks';
        default:
            return ''
        }
    }

    function init() {
        if (context.entity) {
            if (!context.entity.parent) {
                if (context.entity.project) {
                    $scope.parentState = 'byentity';
                    $scope.parentEntity = 'project';
                    $scope.parentEntityId = context.entity.project._id;
                    $scope.parentId = context.entity.id;
                } else if (context.entity.discussions) {
                    $scope.parentState = 'byentity';
                    $scope.parentEntity = 'discussion';
                    if (context.entity.discussions[0])
                        $scope.parentEntityId = context.entity.discussions[0]._id;
                    $scope.parentId = context.entity.id;
                }
            }
            if (context.entityName === 'project') {
                ProjectsService.selected = context.entity;
            } else if (context.entityName === 'discussion') {
                $scope.discussionContext = context.entity;
                $scope.firstStr = '';
                $scope.secondStr = '';
                if ($scope.discussionContext.startDate) {
                    $scope.discussionContext.startDate = new Date($scope.discussionContext.startDate);
                    var startStr = $scope.discussionContext.startDate.getDate() + "/" + ($scope.discussionContext.startDate.getMonth() + 1) + "/" + $scope.discussionContext.startDate.getFullYear();
                    $scope.firstStr = startStr;
                }
                if ($scope.discussionContext.allDay) {
                    $scope.secondStr = "All day long";
                } else {
                    if ($scope.discussionContext.startTime) {
                        $scope.discussionContext.startTime = new Date($scope.discussionContext.startTime);
                        var ho = $scope.discussionContext.startTime.getHours().toString().length == 1 ? "0" + $scope.discussionContext.startTime.getHours().toString() : $scope.discussionContext.startTime.getHours().toString();
                        var min = $scope.discussionContext.startTime.getMinutes().toString().length == 1 ? "0" + $scope.discussionContext.startTime.getMinutes().toString() : $scope.discussionContext.startTime.getMinutes().toString();
                        startStr = ho + ":" + min;
                        $scope.firstStr = $scope.discussionContext.startDate ? $scope.firstStr + " " + startStr : '';
                    }
                    if ($scope.discussionContext.endDate) {
                        $scope.discussionContext.endDate = new Date($scope.discussionContext.endDate);
                        if ($scope.firstStr != 'deadline') {
                            $scope.firstStr = $scope.firstStr;
                        } else {
                            $scope.firstStr = "";
                        }
                        var endStr = $scope.discussionContext.endDate.getDate() + "/" + ($scope.discussionContext.endDate.getMonth() + 1) + "/" + $scope.discussionContext.endDate.getFullYear();
                        $scope.secondStr = endStr;
                        if ($scope.discussionContext.endTime) {
                            $scope.discussionContext.endTime = new Date($scope.discussionContext.endTime);
                            var ho = $scope.discussionContext.endTime.getHours().toString().length == 1 ? "0" + $scope.discussionContext.endTime.getHours().toString() : $scope.discussionContext.endTime.getHours().toString();
                            var min = $scope.discussionContext.endTime.getMinutes().toString().length == 1 ? "0" + $scope.discussionContext.endTime.getMinutes().toString() : $scope.discussionContext.endTime.getMinutes().toString();
                            endStr = ho + ":" + min;
                            $scope.secondStr = $scope.secondStr + " " + endStr;
                        }
                    }
                }

            }
        } else {
            $scope.parentState = 'byparent';
            $scope.parentEntity = 'task';
            if (context.entity) {
                $scope.parentEntityId = context.entity.parent;
                $scope.parentId = context.entity.id;
            }
        }
    }

    init();

    $scope.getProjName = function() {
        var entityType = $scope.currentContext.entityName;
        if ($scope.currentContext != undefined && $scope.currentContext.entity != undefined && $scope.currentContext.entity.title != undefined) {
            return $scope.currentContext.entity.title;
        } else if ($scope.currentContext != undefined && $scope.currentContext.entity != undefined && $scope.currentContext.entity.name != undefined) {
            return $scope.currentContext.entity.name;
        } else {
            if (entityType == "discussion" && DiscussionsService.currentDiscussionName != undefined) {
                return DiscussionsService.currentDiscussionName;
            } else if (ProjectsService.currentProjectName != undefined) {
                return ProjectsService.currentProjectName;
            } else {
                var tasks = $scope.tasks;
                if (tasks.length == 1) {
                    $state.go('401');
                    return "you dont have permission";
                } else if (tasks.length) {
                    var task = tasks[0];
                    var result;
                    if (task.project != undefined) {
                        result = task.project.title
                    } else if (task.discussions != undefined && task.discussions.title != undefined) {
                        result = task.discussions[0].title;
                    } else {
                        result = "you dont have permission";
                    }
                    return result;
                }
            }

        }
    };

    $scope.subEntity = $scope.getProjName();
}

angular.module('mean.icu.ui.tasklist', []).controller('TaskListController', TaskListController);
<commit_msg>Remove unexpected 401 error<commit_after>'use strict';

function TaskListController($scope, $timeout, $state, tasks, NotifyingService, BoldedService,
                            MultipleSelectService, DiscussionsService, TasksService, ProjectsService, context,
                            UsersService, OfficeDocumentsService) {

    let me;
    UsersService.getMe().then(function(result) {
        me = result;
    });

    $scope.items = tasks.data || tasks;

    var subTasks = [];
    $scope.items.forEach(function (item) {
        if (item.subTasks && item.subTasks.length > 0) {
            return subTasks = subTasks.concat(item.subTasks.filter(function (subTask) {
                return subTask !== 'undefined';
            }));
        }
    });

    if(context.entityName !== 'my'){
        subTasks && subTasks.forEach(function (item) {
            $scope.items.push(item);
        });
    }

    $scope.loadNext = tasks.next;
    $scope.loadPrev = tasks.prev;

    $scope.entityName = 'tasks';
    $scope.entityRowTpl = '/icu/components/task-list/task-row.html';

    var creatingStatuses = {
        NotCreated: 0,
        Creating: 1,
        Created: 2
    };

    $scope.getBoldedClass = function(entity){
        return BoldedService.getBoldedClass(entity, 'tasks');
    };

    $scope.update = function(item) {
        return TasksService.update(item);
    };

    $scope.create = function(parent) {
        var newItem = {
            title: '',
            watchers: [],
            tags: [],
            __state: creatingStatuses.NotCreated,
            __autocomplete: false
        };
        if(parent){
            newItem[parent.type] = parent.id;
        }
        return TasksService.create(newItem).then(function(result) {
            $scope.items.push(result);
            TasksService.data.push(result);
            return result;
        }).then( item => {
            let updated = false;
            if(parent && parent.type === 'project') {
                return ProjectsService.getById(context.entityId)
                    .then((parentEntity) => {
                      let parentParams = _.pick(parentEntity, ['watchers', 'permissions']);
                      Object.assign(item, parentParams);
                      updated = !updated;
                      return {item, updated};
                    }).then( res => {
                  if(res.updated)TasksService.update(res.item);
                    return res.item;
                } );
            } else if(parent && parent.type === 'officeDocument'){
                OfficeDocumentsService.getById(context.entityId)
                    .then(parentEntity => {
                        parentEntity.tasks = parentEntity.tasks ||  [];
                        parentEntity.tasks.push(item._id);

                        let context = {
                            name: "tasks",
                            newVal: parentEntity.tasks
                        };
                        OfficeDocumentsService.updateDocument(parentEntity._id, context);
                    })
            }
            return item;
        })
    };

    $scope.getFilter = function() {
        var a = TasksService.filterValue;
        switch (a) {
        case 'today':
            return 'tasksDueToday';
        case 'week':
            return 'tasksDueThisWeek';
        case 'watched':
            return 'watchedTasks';
        case 'overdue':
            return 'overdueTasks';
        default:
            return ''
        }
    }

    function init() {
        if (context.entity) {
            if (!context.entity.parent) {
                if (context.entity.project) {
                    $scope.parentState = 'byentity';
                    $scope.parentEntity = 'project';
                    $scope.parentEntityId = context.entity.project._id;
                    $scope.parentId = context.entity.id;
                } else if (context.entity.discussions) {
                    $scope.parentState = 'byentity';
                    $scope.parentEntity = 'discussion';
                    if (context.entity.discussions[0])
                        $scope.parentEntityId = context.entity.discussions[0]._id;
                    $scope.parentId = context.entity.id;
                }
            }
            if (context.entityName === 'project') {
                ProjectsService.selected = context.entity;
            } else if (context.entityName === 'discussion') {
                $scope.discussionContext = context.entity;
                $scope.firstStr = '';
                $scope.secondStr = '';
                if ($scope.discussionContext.startDate) {
                    $scope.discussionContext.startDate = new Date($scope.discussionContext.startDate);
                    var startStr = $scope.discussionContext.startDate.getDate() + "/" + ($scope.discussionContext.startDate.getMonth() + 1) + "/" + $scope.discussionContext.startDate.getFullYear();
                    $scope.firstStr = startStr;
                }
                if ($scope.discussionContext.allDay) {
                    $scope.secondStr = "All day long";
                } else {
                    if ($scope.discussionContext.startTime) {
                        $scope.discussionContext.startTime = new Date($scope.discussionContext.startTime);
                        var ho = $scope.discussionContext.startTime.getHours().toString().length == 1 ? "0" + $scope.discussionContext.startTime.getHours().toString() : $scope.discussionContext.startTime.getHours().toString();
                        var min = $scope.discussionContext.startTime.getMinutes().toString().length == 1 ? "0" + $scope.discussionContext.startTime.getMinutes().toString() : $scope.discussionContext.startTime.getMinutes().toString();
                        startStr = ho + ":" + min;
                        $scope.firstStr = $scope.discussionContext.startDate ? $scope.firstStr + " " + startStr : '';
                    }
                    if ($scope.discussionContext.endDate) {
                        $scope.discussionContext.endDate = new Date($scope.discussionContext.endDate);
                        if ($scope.firstStr != 'deadline') {
                            $scope.firstStr = $scope.firstStr;
                        } else {
                            $scope.firstStr = "";
                        }
                        var endStr = $scope.discussionContext.endDate.getDate() + "/" + ($scope.discussionContext.endDate.getMonth() + 1) + "/" + $scope.discussionContext.endDate.getFullYear();
                        $scope.secondStr = endStr;
                        if ($scope.discussionContext.endTime) {
                            $scope.discussionContext.endTime = new Date($scope.discussionContext.endTime);
                            var ho = $scope.discussionContext.endTime.getHours().toString().length == 1 ? "0" + $scope.discussionContext.endTime.getHours().toString() : $scope.discussionContext.endTime.getHours().toString();
                            var min = $scope.discussionContext.endTime.getMinutes().toString().length == 1 ? "0" + $scope.discussionContext.endTime.getMinutes().toString() : $scope.discussionContext.endTime.getMinutes().toString();
                            endStr = ho + ":" + min;
                            $scope.secondStr = $scope.secondStr + " " + endStr;
                        }
                    }
                }

            }
        } else {
            $scope.parentState = 'byparent';
            $scope.parentEntity = 'task';
            if (context.entity) {
                $scope.parentEntityId = context.entity.parent;
                $scope.parentId = context.entity.id;
            }
        }
    }

    init();

    $scope.getProjName = function() {
        var entityType = $scope.currentContext.entityName;
        if ($scope.currentContext != undefined && $scope.currentContext.entity != undefined && $scope.currentContext.entity.title != undefined) {
            return $scope.currentContext.entity.title;
        } else if ($scope.currentContext != undefined && $scope.currentContext.entity != undefined && $scope.currentContext.entity.name != undefined) {
            return $scope.currentContext.entity.name;
        } else {
            if (entityType == "discussion" && DiscussionsService.currentDiscussionName != undefined) {
                return DiscussionsService.currentDiscussionName;
            } else if (ProjectsService.currentProjectName != undefined) {
                return ProjectsService.currentProjectName;
            } else {
                var tasks = $scope.tasks;
                if (tasks.length) {
                    var task = tasks[0];
                    var result;
                    if (task.project != undefined) {
                        result = task.project.title
                    } else if (task.discussions != undefined && task.discussions.title != undefined) {
                        result = task.discussions[0].title;
                    } else {
                        result = "you dont have permission";
                    }
                    return result;
                }
            }

        }
    };

    $scope.subEntity = $scope.getProjName();
}

angular.module('mean.icu.ui.tasklist', []).controller('TaskListController', TaskListController);
<|endoftext|>


<commit_before><commit_msg>Change config to default to all years test data.<commit_after><|endoftext|>


<commit_before>'use strict';

describe('Directive: GCE Group Capacity Selector', function() {

  beforeEach(module('spinnaker.serverGroup.configure.gce'));
  beforeEach(module('spinnaker.templates'));

  beforeEach(inject(function($rootScope, $compile, $templateCache) {
    this.scope = $rootScope.$new();
    this.scope.command = {capacity: {}};
    this.elem = angular.element("<gce-server-group-capacity-selector command='command' />");
    this.element = $compile(this.elem)(this.scope)
    this.scope.$digest();
  }));

  it('should correctly assign min/max/desired capacity to the same values', function() {
    expect(this.scope.command.capacity.max).toBeUndefined();
    expect(this.scope.command.capacity.desired).toBeUndefined();
    expect(this.scope.command.capacity.min).toBeUndefined();

    this.elem.find('input').val(3).trigger('input');
    this.scope.$apply();

    expect(this.scope.command.capacity.max).toEqual(3);
    expect(this.scope.command.capacity.desired).toEqual(3);
    expect(this.scope.command.capacity.min).toEqual(3);
  });
});
<commit_msg>small formatting fixes<commit_after>'use strict';

describe('Directive: GCE Group Capacity Selector', function() {

  beforeEach(module('spinnaker.serverGroup.configure.gce'));
  beforeEach(module('spinnaker.templates'));

  beforeEach(inject(function($rootScope, $compile) {
    this.scope = $rootScope.$new();
    this.scope.command = {capacity: {}};
    this.elem = angular.element('<gce-server-group-capacity-selector command="command" />');
    this.element = $compile(this.elem)(this.scope)
    this.scope.$digest();
  }));

  it('should correctly assign min/max/desired capacity to the same values', function() {
    expect(this.scope.command.capacity.max).toBeUndefined();
    expect(this.scope.command.capacity.desired).toBeUndefined();
    expect(this.scope.command.capacity.min).toBeUndefined();

    this.elem.find('input').val(3).trigger('input');
    this.scope.$apply();

    expect(this.scope.command.capacity.max).toEqual(3);
    expect(this.scope.command.capacity.desired).toEqual(3);
    expect(this.scope.command.capacity.min).toEqual(3);
  });
});
<|endoftext|>


<commit_before><commit_msg>Update draft.js<commit_after><|endoftext|>


<commit_before>/*global define*/
define([
	"dojo/_base/declare",
	"dojo/Evented",
	"dojo/Deferred",
	"esri/request",
	"esri/tasks/QueryTask"
], function (declare, Evented, Deferred, request, QueryTask) {

	/**
	 * @typedef {Object} LayerInfo
	 * @property {number} maxRecordCount
	 * @property {string} objectIdField
	 * @property {Field[]} fields
	 * @property {string} displayField
	 */

	/**
	 * Gets information about a layer.
	 * @param {(string|esri/layer/FeatureLayer)} urlOrFeatureLayer - Either the URL to a feature layer or a FeatureLayer object.
	 * @returns {dojo/Deferred}
	 */
	function getLayerInfo(urlOrFeatureLayer) {
		var deferred;
		if (typeof urlOrFeatureLayer === "string") {
			deferred = request({
				url: urlOrFeatureLayer,
				content: {
					f: "json"
				}
			});
		} else {
			deferred = new Deferred();
			deferred.resolve(urlOrFeatureLayer);
		}

		return deferred;
	}

	/**
	 * @param {number[]} objectIds
	 * @param {number} maxRecordCount
	 * @returns {Array.<Array.<number>>}
	 */
	function breakObjectIdsIntoGroups(objectIds, maxRecordCount) {
		var output = [], currentGroup;

		if (maxRecordCount == null) {
			output.push(objectIds);
		} else {
			for (var i = 0, l = objectIds.length; i < l; i += 1) {
				if (i % maxRecordCount === 0) {
					currentGroup = [];
					output.push(currentGroup);
				}
				currentGroup.push(objectIds[i]);
			}
		}

		return output;
	}

	/**
	 * @property {(LayerInfo|FeatureLayer)} layerInfo
	 * @property {QueryTask} [queryTask=undefined] - This property is only necessary if layerInfo is not a FeatureLayer.
	 * @returns {dojo/Deferred}
	 */
	function getAllFeaturesForLayer(layerInfo, queryTask) {
		var query, deferred, idsDeferred;

		/** Reject the output deferred object. */
		function handleError(err) {
			deferred.reject(err);
		}

		deferred = new Deferred();
		query = new Query();
		query.where = "1=1"; // Return all features.
		idsDeferred = layerInfo.queryIds ? layerInfo.queryIds(query) : (queryTask && queryTask.executeForIds) ? queryTask.executeForIds(query) : null;
		if (!idsDeferred) {
			throw new TypeError("Invalid parameters");
		}
		idsDeferred.then(function (objectIds) {
			deferred.progress("retrieved object ids");
			var oidGroups = breakObjectIdsIntoGroups(objectIds, layerInfo.maxRecordCount);
			// TODO: query each set of OID groups for features.
		},handleError);
	}

	return declare([Evented], {
		select: null,
		queryTask: null,
		layer: null,
		/**
		 * @param {(HTMLSelectElement|string)} domNode - Either an HTMLSelectElement or the "id" attribute of a select element.
		 * @param {esri/layers/Layer} layer
		 * @constructs
		 * @throws {TypeError} Thrown if domNode is an invalid type.
		 */
		constructor: function (domNode, layer) {
			var self = this;
			// Setup the this.select property.
			if (domNode) {
				if (typeof domNode === "string") {
					this.select = document.getElementById(domNode);
				} else if (domNode instanceof HTMLSelectElement) {
					this.select = domNode;
				}
			}
			// Throw an error if select was not valid.
			if (!this.select) {
				throw new TypeError("The domNode must be either an HTMLSelectElement or the id of one.");
			}

			if (!layer) {
				throw new TypeError("The layer parameter must be provided.");
			} else if (layer.queryFeatures) {
				// Feature layer. No query task needs to be created.
				this.layer = layer;
				this.queryTask = null;
			} else if (layer.capabilities && layer.url && layer.capabilities.contains("Query")){
				// Store layer (may not actually be necessary for this layer type).
				this.layer = layer;
				// Create a query task for the first child layer.
				this.queryTask = new QueryTask([layer.url.trimRight("/"), "0"].join("/"));
			}

			getLayerInfo(this.queryTask ? this.queryTask.url : this.layer).then(function (layerInfo) {
				// TODO: Query all features.
			});
		}
	});
});<commit_msg>Added code for querying all features in order to populate a select element.<commit_after>/*global define*/
define([
	"dojo/_base/declare",
	"dojo/Evented",
	"dojo/Deferred",
	"esri/request",
	"esri/tasks/QueryTask",
	"esri/tasks/Query"
], function (declare, Evented, Deferred, request, QueryTask, Query) {

	/**
	 * @typedef {Object} LayerInfo
	 * @property {number} maxRecordCount
	 * @property {string} objectIdField
	 * @property {Field[]} fields
	 * @property {string} displayField
	 */

	/**
	 * Gets information about a layer.
	 * @param {(string|esri/layer/FeatureLayer)} urlOrFeatureLayer - Either the URL to a feature layer or a FeatureLayer object.
	 * @returns {dojo/Deferred}
	 */
	function getLayerInfo(urlOrFeatureLayer) {
		var deferred;
		if (typeof urlOrFeatureLayer === "string") {
			deferred = request({
				url: urlOrFeatureLayer,
				content: {
					f: "json"
				}
			});
		} else {
			deferred = new Deferred();
			deferred.resolve(urlOrFeatureLayer);
		}

		return deferred;
	}

	/**
	 * @param {number[]} objectIds
	 * @param {number} maxRecordCount
	 * @returns {Array.<Array.<number>>}
	 */
	function breakObjectIdsIntoGroups(objectIds, maxRecordCount) {
		var output = [], currentGroup;
		/*jshint eqnull:true*/
		if (maxRecordCount == null) {
		/*jshint eqnull:false*/
			output.push(objectIds);
		} else {
			for (var i = 0, l = objectIds.length; i < l; i += 1) {
				if (i % maxRecordCount === 0) {
					currentGroup = [];
					output.push(currentGroup);
				}
				currentGroup.push(objectIds[i]);
			}
		}

		return output;
	}

	/**
	 * @param {(QueryTask|FeatureLayer)} queryTaskOrLayer
	 * @param {number[]} oids
	 * @param {string} displayField
	 * @returns {dojo/Deferred}
	 */
	function queryForFeaturesWithMatchingOids(queryTaskOrLayer, oids, displayField) {
		var query = new Query();
		query.objectIds = oids;
		query.outFields = [displayField];
		query.returnGeometry = true;
		return queryTaskOrLayer.execute ?
			queryTaskOrLayer.execute(query)
			: queryTaskOrLayer.queryFeatures ? queryTaskOrLayer.queryFeatures(query)
			: null;
	}

	/**
	 * @property {(LayerInfo|FeatureLayer)} layerInfo
	 * @property {QueryTask} [queryTask=undefined] - This property is only necessary if layerInfo is not a FeatureLayer.
	 * @returns {dojo/Deferred}
	 */
	function getAllFeaturesForLayer(layerInfo, queryTask) {
		var query, deferred, idsDeferred;

		/** Reject the output deferred object. */
		function handleError(err) {
			deferred.reject(err);
		}

		var outFeatureSet = null;
		var deferredCompleteCount = 0; // Count of completed deferrred (errors count here, too).
		var errors = null;

		deferred = new Deferred();
		query = new Query();
		query.where = "1=1"; // Return all features.
		idsDeferred = layerInfo.queryIds ? layerInfo.queryIds(query) : (queryTask && queryTask.executeForIds) ? queryTask.executeForIds(query) : null;
		if (!idsDeferred) {
			throw new TypeError("Invalid parameters");
		}
		idsDeferred.then(function (objectIds) {
			deferred.progress("retrieved object ids");
			var oidGroups = breakObjectIdsIntoGroups(objectIds, layerInfo.maxRecordCount);

			function resolveIfCompleted() {
				if (deferredCompleteCount === oidGroups.length) {
					deferred.resolve({
						featureSet: outFeatureSet,
						errors: errors
					});
				}
			}

			function updateProgress(featureSet, error) {
				deferredCompleteCount += 1;
				deferred.progress({
					queriesCompleted: deferredCompleteCount,
					totalQueries: oidGroups.length,
					featureSet: featureSet || null,
					error: error || null
				});
			}

			function onFeatureQueryComplete(featureSet) {
				updateProgress(featureSet, null);
				if (!outFeatureSet) {
					outFeatureSet = featureSet;
				} else {
					featureSet.features.forEach(function (v) {
						outFeatureSet.features.push(v);
					});
				}
				resolveIfCompleted();
			}

			function onFeatureQueryError(err) {
				updateProgress(null, err);
				if (!errors) {
					errors = [err];
				} else {
					errors.push(err);
				}
				resolveIfCompleted();
			}

			// query each set of OID groups for features.
			oidGroups.forEach(function (oids) {
				queryForFeaturesWithMatchingOids(queryTask || layerInfo, oids, layerInfo.displayField).then(onFeatureQueryComplete, onFeatureQueryError);
			});
		},handleError);

		return deferred;
	}

	return declare([Evented], {
		select: null,
		queryTask: null,
		layer: null,
		/**
		 * @param {(HTMLSelectElement|string)} domNode - Either an HTMLSelectElement or the "id" attribute of a select element.
		 * @param {esri/layers/Layer} layer
		 * @constructs
		 * @throws {TypeError} Thrown if domNode is an invalid type.
		 */
		constructor: function (domNode, layer) {
			var self = this;
			// Setup the this.select property.
			if (domNode) {
				if (typeof domNode === "string") {
					this.select = document.getElementById(domNode);
				} else if (domNode instanceof HTMLSelectElement) {
					this.select = domNode;
				}
			}
			// Throw an error if select was not valid.
			if (!this.select) {
				throw new TypeError("The domNode must be either an HTMLSelectElement or the id of one.");
			}

			if (!layer) {
				throw new TypeError("The layer parameter must be provided.");
			} else if (layer.queryFeatures) {
				// Feature layer. No query task needs to be created.
				this.layer = layer;
				this.queryTask = null;
			} else if (layer.capabilities && layer.url && layer.capabilities.contains("Query")){
				// Store layer (may not actually be necessary for this layer type).
				this.layer = layer;
				// Create a query task for the first child layer.
				this.queryTask = new QueryTask([layer.url.trimRight("/"), "0"].join("/"));
			}

			getLayerInfo(this.queryTask ? this.queryTask.url : this.layer).then(function (layerInfo) {
				function populateSelect(result) {
					var featureSet = result.featureSet;
					var frag = document.createDocumentFragment();
					featureSet.features.forEach(function (feature) {
						var option = document.createElement("option");
						option.textContent = feature.attributes[layerInfo.displayField];
						option.value = JSON.stringify(feature.geometry.toJson());
						frag.appendChild(option);
					});
					self.select.appendChild(frag);
				}

				// Query all features. Populate the select element with corresponding options.
				getAllFeaturesForLayer(layerInfo, self.queryTask).then(populateSelect);
			});
		}
	});
});<|endoftext|>


<commit_before>import Ember from 'ember';
import {adminPattern} from  '../utils/patterns';

export default Ember.Controller.extend({
    filteredPermissions: Ember.computed('model', function() {
        var permissions = this.get('model.permissions');
        var users = {};
        var system = {};
        for (let k of Object.getOwnPropertyNames(permissions)) {
            var dest = adminPattern.test(k) ? users : system;
            dest[k] = permissions[k];
        }
        return [users, system];
    }),

    /* Return permissions strings that correspond to admin users (those who log in via OSF) */
    _userPermissions:  Ember.computed('filteredPermissions', function() {
        var filtered = this.get('filteredPermissions');
        return filtered[0];
    }),
    userPermissions: Ember.computed.readOnly('_userPermissions'), // TODO: is this necessary?

    /* Return permissions strings that do not match OSF users */
    systemPermissions:  Ember.computed('filteredPermissions', function() {
        var filtered = this.get('filteredPermissions');
        return filtered[1];
    }),

    actions: {
        permissionsUpdated(permissions) {
            // Save updated permissions, and avoid overwriting system-level permissions not displayed to the user

            var payload = Object.assign({}, permissions, this.get('systemPermissions'));
            this.set('model.permissions', payload);
            this.get('model').save();
        }
    }
});
<commit_msg>Add missing breadcrumb<commit_after>import Ember from 'ember';
import {adminPattern} from  '../utils/patterns';

export default Ember.Controller.extend({
    breadCrumb: 'Project configuration',

    filteredPermissions: Ember.computed('model', function() {
        var permissions = this.get('model.permissions');
        var users = {};
        var system = {};
        for (let k of Object.getOwnPropertyNames(permissions)) {
            var dest = adminPattern.test(k) ? users : system;
            dest[k] = permissions[k];
        }
        return [users, system];
    }),

    /* Return permissions strings that correspond to admin users (those who log in via OSF) */
    _userPermissions:  Ember.computed('filteredPermissions', function() {
        var filtered = this.get('filteredPermissions');
        return filtered[0];
    }),
    userPermissions: Ember.computed.readOnly('_userPermissions'), // TODO: is this necessary?

    /* Return permissions strings that do not match OSF users */
    systemPermissions:  Ember.computed('filteredPermissions', function() {
        var filtered = this.get('filteredPermissions');
        return filtered[1];
    }),

    actions: {
        permissionsUpdated(permissions) {
            // Save updated permissions, and avoid overwriting system-level permissions not displayed to the user

            var payload = Object.assign({}, permissions, this.get('systemPermissions'));
            this.set('model.permissions', payload);
            this.get('model').save();
        }
    }
});
<|endoftext|>


<commit_before>define([
        './Cartesian2',
        './Cartesian3',
        './Check',
        './DeveloperError',
        './Math'
    ], function(
        Cartesian2,
        Cartesian3,
        Check,
        DeveloperError,
        CesiumMath) {
    'use strict';

    /**
     * Attribute compression and decompression functions.
     *
     * @exports AttributeCompression
     *
     * @private
     */
    var AttributeCompression = {};

    /**
     * Encodes a normalized vector into 2 SNORM values in the range of [0-rangeMax] following the 'oct' encoding.
     *
     * Oct encoding is a compact representation of unit length vectors.
     * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors",
     * Cigolle et al 2014: {@link http://jcgt.org/published/0003/02/01/}
     *
     * @param {Cartesian3} vector The normalized vector to be compressed into 2 component 'oct' encoding.
     * @param {Cartesian2} result The 2 component oct-encoded unit length vector.
     * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits.
     * @returns {Cartesian2} The 2 component oct-encoded unit length vector.
     *
     * @exception {DeveloperError} vector must be normalized.
     *
     * @see AttributeCompression.octDecodeInRange
     */
    AttributeCompression.octEncodeInRange = function(vector, rangeMax, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('vector', vector);
        Check.defined('result', result);
        var magSquared = Cartesian3.magnitudeSquared(vector);
        if (Math.abs(magSquared - 1.0) > CesiumMath.EPSILON6) {
            throw new DeveloperError('vector must be normalized.');
        }
        //>>includeEnd('debug');

        result.x = vector.x / (Math.abs(vector.x) + Math.abs(vector.y) + Math.abs(vector.z));
        result.y = vector.y / (Math.abs(vector.x) + Math.abs(vector.y) + Math.abs(vector.z));
        if (vector.z < 0) {
            var x = result.x;
            var y = result.y;
            result.x = (1.0 - Math.abs(y)) * CesiumMath.signNotZero(x);
            result.y = (1.0 - Math.abs(x)) * CesiumMath.signNotZero(y);
        }

        result.x = CesiumMath.toSNorm(result.x, rangeMax);
        result.y = CesiumMath.toSNorm(result.y, rangeMax);

        return result;
    };

    /**
     * Encodes a normalized vector into 2 SNORM values in the range of [0-255] following the 'oct' encoding.
     *
     * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding.
     * @param {Cartesian2} result The 2 byte oct-encoded unit length vector.
     * @returns {Cartesian2} The 2 byte oct-encoded unit length vector.
     *
     * @exception {DeveloperError} vector must be normalized.
     *
     * @see AttributeCompression.octEncodeInRange
     * @see AttributeCompression.octDecode
     */
    AttributeCompression.octEncode = function(vector, result) {
        return AttributeCompression.octEncodeInRange(vector, 255, result);
    };

    /**
     * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component vector.
     *
     * @param {Number} x The x component of the oct-encoded unit length vector.
     * @param {Number} y The y component of the oct-encoded unit length vector.
     * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits.
     * @param {Cartesian3} result The decoded and normalized vector
     * @returns {Cartesian3} The decoded and normalized vector.
     *
     * @exception {DeveloperError} x and y must be an unsigned normalized integer between 0 and rangeMax.
     *
     * @see AttributeCompression.octEncodeInRange
     */
    AttributeCompression.octDecodeInRange = function(x, y, rangeMax, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('result', result);
        if (x < 0 || x > rangeMax || y < 0 || y > rangeMax) {
            throw new DeveloperError('x and y must be a signed normalized integer between 0 and ' + rangeMax);
        }
        //>>includeEnd('debug');

        result.x = CesiumMath.fromSNorm(x, rangeMax);
        result.y = CesiumMath.fromSNorm(y, rangeMax);
        result.z = 1.0 - (Math.abs(result.x) + Math.abs(result.y));

        if (result.z < 0.0)
        {
            var oldVX = result.x;
            result.x = (1.0 - Math.abs(result.y)) * CesiumMath.signNotZero(oldVX);
            result.y = (1.0 - Math.abs(oldVX)) * CesiumMath.signNotZero(result.y);
        }

        return Cartesian3.normalize(result, result);
    };

    /**
     * Decodes a unit-length vector in 2 byte 'oct' encoding to a normalized 3-component vector.
     *
     * @param {Number} x The x component of the oct-encoded unit length vector.
     * @param {Number} y The y component of the oct-encoded unit length vector.
     * @param {Cartesian3} result The decoded and normalized vector.
     * @returns {Cartesian3} The decoded and normalized vector.
     *
     * @exception {DeveloperError} x and y must be an unsigned normalized integer between 0 and 255.
     *
     * @see AttributeCompression.octDecodeInRange
     */
    AttributeCompression.octDecode = function(x, y, result) {
        return AttributeCompression.octDecodeInRange(x, y, 255, result);
    };

    /**
     * Packs an oct encoded vector into a single floating-point number.
     *
     * @param {Cartesian2} encoded The oct encoded vector.
     * @returns {Number} The oct encoded vector packed into a single float.
     *
     */
    AttributeCompression.octPackFloat = function(encoded) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('encoded', encoded);
        //>>includeEnd('debug');
        return 256.0 * encoded.x + encoded.y;
    };

    var scratchEncodeCart2 = new Cartesian2();

    /**
     * Encodes a normalized vector into 2 SNORM values in the range of [0-255] following the 'oct' encoding and
     * stores those values in a single float-point number.
     *
     * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding.
     * @returns {Number} The 2 byte oct-encoded unit length vector.
     *
     * @exception {DeveloperError} vector must be normalized.
     */
    AttributeCompression.octEncodeFloat = function(vector) {
        AttributeCompression.octEncode(vector, scratchEncodeCart2);
        return AttributeCompression.octPackFloat(scratchEncodeCart2);
    };

    /**
     * Decodes a unit-length vector in 'oct' encoding packed in a floating-point number to a normalized 3-component vector.
     *
     * @param {Number} value The oct-encoded unit length vector stored as a single floating-point number.
     * @param {Cartesian3} result The decoded and normalized vector
     * @returns {Cartesian3} The decoded and normalized vector.
     *
     */
    AttributeCompression.octDecodeFloat = function(value, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('value', value);
        //>>includeEnd('debug');

        var temp = value / 256.0;
        var x = Math.floor(temp);
        var y = (temp - x) * 256.0;

        return AttributeCompression.octDecode(x, y, result);
    };

    /**
     * Encodes three normalized vectors into 6 SNORM values in the range of [0-255] following the 'oct' encoding and
     * packs those into two floating-point numbers.
     *
     * @param {Cartesian3} v1 A normalized vector to be compressed.
     * @param {Cartesian3} v2 A normalized vector to be compressed.
     * @param {Cartesian3} v3 A normalized vector to be compressed.
     * @param {Cartesian2} result The 'oct' encoded vectors packed into two floating-point numbers.
     * @returns {Cartesian2} The 'oct' encoded vectors packed into two floating-point numbers.
     *
     */
    AttributeCompression.octPack = function(v1, v2, v3, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('v1', v1);
        Check.defined('v2', v2);
        Check.defined('v3', v3);
        Check.defined('result', result);
        //>>includeEnd('debug');

        var encoded1 = AttributeCompression.octEncodeFloat(v1);
        var encoded2 = AttributeCompression.octEncodeFloat(v2);

        var encoded3 = AttributeCompression.octEncode(v3, scratchEncodeCart2);
        result.x = 65536.0 * encoded3.x + encoded1;
        result.y = 65536.0 * encoded3.y + encoded2;
        return result;
    };

    /**
     * Decodes three unit-length vectors in 'oct' encoding packed into a floating-point number to a normalized 3-component vector.
     *
     * @param {Cartesian2} packed The three oct-encoded unit length vectors stored as two floating-point number.
     * @param {Cartesian3} v1 One decoded and normalized vector.
     * @param {Cartesian3} v2 One decoded and normalized vector.
     * @param {Cartesian3} v3 One decoded and normalized vector.
     */
    AttributeCompression.octUnpack = function(packed, v1, v2, v3) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('packed', packed);
        Check.defined('v1', v1);
        Check.defined('v2', v2);
        Check.defined('v3', v3);
        //>>includeEnd('debug');

        var temp = packed.x / 65536.0;
        var x = Math.floor(temp);
        var encodedFloat1 = (temp - x) * 65536.0;

        temp = packed.y / 65536.0;
        var y = Math.floor(temp);
        var encodedFloat2 = (temp - y) * 65536.0;

        AttributeCompression.octDecodeFloat(encodedFloat1, v1);
        AttributeCompression.octDecodeFloat(encodedFloat2, v2);
        AttributeCompression.octDecode(x, y, v3);
    };

    /**
     * Pack texture coordinates into a single float. The texture coordinates will only preserve 12 bits of precision.
     *
     * @param {Cartesian2} textureCoordinates The texture coordinates to compress.  Both coordinates must be in the range 0.0-1.0.
     * @returns {Number} The packed texture coordinates.
     *
     */
    AttributeCompression.compressTextureCoordinates = function(textureCoordinates) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('textureCoordinates', textureCoordinates);
        //>>includeEnd('debug');

        // Move x and y to the range 0-4095;
        var x = (textureCoordinates.x * 4095.0) | 0;
        var y = (textureCoordinates.y * 4095.0) | 0;
        return 4096.0 * x + y;
    };

    /**
     * Decompresses texture coordinates that were packed into a single float.
     *
     * @param {Number} compressed The compressed texture coordinates.
     * @param {Cartesian2} result The decompressed texture coordinates.
     * @returns {Cartesian2} The modified result parameter.
     *
     */
    AttributeCompression.decompressTextureCoordinates = function(compressed, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('compressed', compressed);
        Check.defined('result', result);
        //>>includeEnd('debug');

        var temp = compressed / 4096.0;
        var xZeroTo4095 = Math.floor(temp);
        result.x = xZeroTo4095 / 4095.0;
        result.y = (compressed - xZeroTo4095 * 4096) / 4095;
        return result;
    };

    function zigZagDecode(value) {
        return (value >> 1) ^ (-(value & 1));
    }

    /**
     * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place.
     *
     * @param {Uint16Array} uBuffer The buffer or buffer view of u values.
     * @param {Uint16Array} vBuffer The buffer or buffer view of v values.
     * @param {Uint16Array} [heightBuffer] The buffer or buffer view of height values.
     *
     * @see {@link http://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format}
     */
    AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('uBuffer', uBuffer);
        Check.defined('vBuffer', vBuffer);
        Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length);
        if (defined(heightBuffer)) {
            Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length);
        }
        //>>includeEnd('debug');

        var count = uBuffer.length;

        var u = 0;
        var v = 0;
        var height = 0;

        for (var i = 0; i < count; ++i) {
            u += zigZagDecode(uBuffer[i]);
            v += zigZagDecode(vBuffer[i]);

            uBuffer[i] = u;
            vBuffer[i] = v;

            if (defined(heightBuffer)) {
                height += zigZagDecode(heightBuffer[i]);
                heightBuffer[i] = height;
            }
        }
    };

    return AttributeCompression;
});
<commit_msg>Fix merge error.<commit_after>define([
        './Cartesian2',
        './Cartesian3',
        './Check',
        './defined',
        './DeveloperError',
        './Math'
    ], function(
        Cartesian2,
        Cartesian3,
        Check,
        defined,
        DeveloperError,
        CesiumMath) {
    'use strict';

    /**
     * Attribute compression and decompression functions.
     *
     * @exports AttributeCompression
     *
     * @private
     */
    var AttributeCompression = {};

    /**
     * Encodes a normalized vector into 2 SNORM values in the range of [0-rangeMax] following the 'oct' encoding.
     *
     * Oct encoding is a compact representation of unit length vectors.
     * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors",
     * Cigolle et al 2014: {@link http://jcgt.org/published/0003/02/01/}
     *
     * @param {Cartesian3} vector The normalized vector to be compressed into 2 component 'oct' encoding.
     * @param {Cartesian2} result The 2 component oct-encoded unit length vector.
     * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits.
     * @returns {Cartesian2} The 2 component oct-encoded unit length vector.
     *
     * @exception {DeveloperError} vector must be normalized.
     *
     * @see AttributeCompression.octDecodeInRange
     */
    AttributeCompression.octEncodeInRange = function(vector, rangeMax, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('vector', vector);
        Check.defined('result', result);
        var magSquared = Cartesian3.magnitudeSquared(vector);
        if (Math.abs(magSquared - 1.0) > CesiumMath.EPSILON6) {
            throw new DeveloperError('vector must be normalized.');
        }
        //>>includeEnd('debug');

        result.x = vector.x / (Math.abs(vector.x) + Math.abs(vector.y) + Math.abs(vector.z));
        result.y = vector.y / (Math.abs(vector.x) + Math.abs(vector.y) + Math.abs(vector.z));
        if (vector.z < 0) {
            var x = result.x;
            var y = result.y;
            result.x = (1.0 - Math.abs(y)) * CesiumMath.signNotZero(x);
            result.y = (1.0 - Math.abs(x)) * CesiumMath.signNotZero(y);
        }

        result.x = CesiumMath.toSNorm(result.x, rangeMax);
        result.y = CesiumMath.toSNorm(result.y, rangeMax);

        return result;
    };

    /**
     * Encodes a normalized vector into 2 SNORM values in the range of [0-255] following the 'oct' encoding.
     *
     * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding.
     * @param {Cartesian2} result The 2 byte oct-encoded unit length vector.
     * @returns {Cartesian2} The 2 byte oct-encoded unit length vector.
     *
     * @exception {DeveloperError} vector must be normalized.
     *
     * @see AttributeCompression.octEncodeInRange
     * @see AttributeCompression.octDecode
     */
    AttributeCompression.octEncode = function(vector, result) {
        return AttributeCompression.octEncodeInRange(vector, 255, result);
    };

    /**
     * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component vector.
     *
     * @param {Number} x The x component of the oct-encoded unit length vector.
     * @param {Number} y The y component of the oct-encoded unit length vector.
     * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits.
     * @param {Cartesian3} result The decoded and normalized vector
     * @returns {Cartesian3} The decoded and normalized vector.
     *
     * @exception {DeveloperError} x and y must be an unsigned normalized integer between 0 and rangeMax.
     *
     * @see AttributeCompression.octEncodeInRange
     */
    AttributeCompression.octDecodeInRange = function(x, y, rangeMax, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('result', result);
        if (x < 0 || x > rangeMax || y < 0 || y > rangeMax) {
            throw new DeveloperError('x and y must be a signed normalized integer between 0 and ' + rangeMax);
        }
        //>>includeEnd('debug');

        result.x = CesiumMath.fromSNorm(x, rangeMax);
        result.y = CesiumMath.fromSNorm(y, rangeMax);
        result.z = 1.0 - (Math.abs(result.x) + Math.abs(result.y));

        if (result.z < 0.0)
        {
            var oldVX = result.x;
            result.x = (1.0 - Math.abs(result.y)) * CesiumMath.signNotZero(oldVX);
            result.y = (1.0 - Math.abs(oldVX)) * CesiumMath.signNotZero(result.y);
        }

        return Cartesian3.normalize(result, result);
    };

    /**
     * Decodes a unit-length vector in 2 byte 'oct' encoding to a normalized 3-component vector.
     *
     * @param {Number} x The x component of the oct-encoded unit length vector.
     * @param {Number} y The y component of the oct-encoded unit length vector.
     * @param {Cartesian3} result The decoded and normalized vector.
     * @returns {Cartesian3} The decoded and normalized vector.
     *
     * @exception {DeveloperError} x and y must be an unsigned normalized integer between 0 and 255.
     *
     * @see AttributeCompression.octDecodeInRange
     */
    AttributeCompression.octDecode = function(x, y, result) {
        return AttributeCompression.octDecodeInRange(x, y, 255, result);
    };

    /**
     * Packs an oct encoded vector into a single floating-point number.
     *
     * @param {Cartesian2} encoded The oct encoded vector.
     * @returns {Number} The oct encoded vector packed into a single float.
     *
     */
    AttributeCompression.octPackFloat = function(encoded) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('encoded', encoded);
        //>>includeEnd('debug');
        return 256.0 * encoded.x + encoded.y;
    };

    var scratchEncodeCart2 = new Cartesian2();

    /**
     * Encodes a normalized vector into 2 SNORM values in the range of [0-255] following the 'oct' encoding and
     * stores those values in a single float-point number.
     *
     * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding.
     * @returns {Number} The 2 byte oct-encoded unit length vector.
     *
     * @exception {DeveloperError} vector must be normalized.
     */
    AttributeCompression.octEncodeFloat = function(vector) {
        AttributeCompression.octEncode(vector, scratchEncodeCart2);
        return AttributeCompression.octPackFloat(scratchEncodeCart2);
    };

    /**
     * Decodes a unit-length vector in 'oct' encoding packed in a floating-point number to a normalized 3-component vector.
     *
     * @param {Number} value The oct-encoded unit length vector stored as a single floating-point number.
     * @param {Cartesian3} result The decoded and normalized vector
     * @returns {Cartesian3} The decoded and normalized vector.
     *
     */
    AttributeCompression.octDecodeFloat = function(value, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('value', value);
        //>>includeEnd('debug');

        var temp = value / 256.0;
        var x = Math.floor(temp);
        var y = (temp - x) * 256.0;

        return AttributeCompression.octDecode(x, y, result);
    };

    /**
     * Encodes three normalized vectors into 6 SNORM values in the range of [0-255] following the 'oct' encoding and
     * packs those into two floating-point numbers.
     *
     * @param {Cartesian3} v1 A normalized vector to be compressed.
     * @param {Cartesian3} v2 A normalized vector to be compressed.
     * @param {Cartesian3} v3 A normalized vector to be compressed.
     * @param {Cartesian2} result The 'oct' encoded vectors packed into two floating-point numbers.
     * @returns {Cartesian2} The 'oct' encoded vectors packed into two floating-point numbers.
     *
     */
    AttributeCompression.octPack = function(v1, v2, v3, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('v1', v1);
        Check.defined('v2', v2);
        Check.defined('v3', v3);
        Check.defined('result', result);
        //>>includeEnd('debug');

        var encoded1 = AttributeCompression.octEncodeFloat(v1);
        var encoded2 = AttributeCompression.octEncodeFloat(v2);

        var encoded3 = AttributeCompression.octEncode(v3, scratchEncodeCart2);
        result.x = 65536.0 * encoded3.x + encoded1;
        result.y = 65536.0 * encoded3.y + encoded2;
        return result;
    };

    /**
     * Decodes three unit-length vectors in 'oct' encoding packed into a floating-point number to a normalized 3-component vector.
     *
     * @param {Cartesian2} packed The three oct-encoded unit length vectors stored as two floating-point number.
     * @param {Cartesian3} v1 One decoded and normalized vector.
     * @param {Cartesian3} v2 One decoded and normalized vector.
     * @param {Cartesian3} v3 One decoded and normalized vector.
     */
    AttributeCompression.octUnpack = function(packed, v1, v2, v3) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('packed', packed);
        Check.defined('v1', v1);
        Check.defined('v2', v2);
        Check.defined('v3', v3);
        //>>includeEnd('debug');

        var temp = packed.x / 65536.0;
        var x = Math.floor(temp);
        var encodedFloat1 = (temp - x) * 65536.0;

        temp = packed.y / 65536.0;
        var y = Math.floor(temp);
        var encodedFloat2 = (temp - y) * 65536.0;

        AttributeCompression.octDecodeFloat(encodedFloat1, v1);
        AttributeCompression.octDecodeFloat(encodedFloat2, v2);
        AttributeCompression.octDecode(x, y, v3);
    };

    /**
     * Pack texture coordinates into a single float. The texture coordinates will only preserve 12 bits of precision.
     *
     * @param {Cartesian2} textureCoordinates The texture coordinates to compress.  Both coordinates must be in the range 0.0-1.0.
     * @returns {Number} The packed texture coordinates.
     *
     */
    AttributeCompression.compressTextureCoordinates = function(textureCoordinates) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('textureCoordinates', textureCoordinates);
        //>>includeEnd('debug');

        // Move x and y to the range 0-4095;
        var x = (textureCoordinates.x * 4095.0) | 0;
        var y = (textureCoordinates.y * 4095.0) | 0;
        return 4096.0 * x + y;
    };

    /**
     * Decompresses texture coordinates that were packed into a single float.
     *
     * @param {Number} compressed The compressed texture coordinates.
     * @param {Cartesian2} result The decompressed texture coordinates.
     * @returns {Cartesian2} The modified result parameter.
     *
     */
    AttributeCompression.decompressTextureCoordinates = function(compressed, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('compressed', compressed);
        Check.defined('result', result);
        //>>includeEnd('debug');

        var temp = compressed / 4096.0;
        var xZeroTo4095 = Math.floor(temp);
        result.x = xZeroTo4095 / 4095.0;
        result.y = (compressed - xZeroTo4095 * 4096) / 4095;
        return result;
    };

    function zigZagDecode(value) {
        return (value >> 1) ^ (-(value & 1));
    }

    /**
     * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place.
     *
     * @param {Uint16Array} uBuffer The buffer or buffer view of u values.
     * @param {Uint16Array} vBuffer The buffer or buffer view of v values.
     * @param {Uint16Array} [heightBuffer] The buffer or buffer view of height values.
     *
     * @see {@link http://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format}
     */
    AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) {
        //>>includeStart('debug', pragmas.debug);
        Check.defined('uBuffer', uBuffer);
        Check.defined('vBuffer', vBuffer);
        Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length);
        if (defined(heightBuffer)) {
            Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length);
        }
        //>>includeEnd('debug');

        var count = uBuffer.length;

        var u = 0;
        var v = 0;
        var height = 0;

        for (var i = 0; i < count; ++i) {
            u += zigZagDecode(uBuffer[i]);
            v += zigZagDecode(vBuffer[i]);

            uBuffer[i] = u;
            vBuffer[i] = v;

            if (defined(heightBuffer)) {
                height += zigZagDecode(heightBuffer[i]);
                heightBuffer[i] = height;
            }
        }
    };

    return AttributeCompression;
});
<|endoftext|>


<commit_before>var _ = require('lodash')
    , AWS = require('aws-sdk')
    , changeCase = require('change-case')
    , CfnStack = require('../aws-utils/cfn-stack')
    , Component = require('../component')
    , novalib = require('../nova-lib')
    , NovaError = require('../nova-error')
    , moment = require('moment')
    , novaform = require('../novaform')
    , novastl = require('../novastl')
    , path = require('path')
    , program = require('../program')
    , ProjectRef = require('../project-ref')
    , Project = require('../project')
    , utils = require('../utils')
    , util = require('util');

function Command(opts) {
    if (!(this instanceof Command)) {
        return new Command(opts);
    }

    this.opts = opts;
    this.commandOptions = this.opts.options;

    if (_(opts.argv).isEmpty()) {
        throw new Error('Missing project/component reference');
    } else if (opts.argv.length !== 1) {
        throw new Error('Too many project/component references specified');
    }

    var ref = new ProjectRef(opts.argv[0]);
    this.project = new Project(ref.name);
    this.componentName = ref.subname;

    if (!this.componentName) {
        throw new Error('Deploy command needs a component name.');
    }
}

Command.options = [
    ['w', 'wait', 'Wait for completion'],
    ['n', 'noop', 'Do not actually deploy. But generates stack and validates it.'],
    ['', 'template-output=ARG', 'Dump the generated CloudFormation template to a file'],
];
Command.usageText = '[options] project_name/component_name';
Command.descriptionText = 'Deploys project component';

function waitForStack(stackName, region, shouldStopCallback, checkInterval) {
    return new Promise((resolve, reject) => {
        var cfn = new AWS.CloudFormation({ region: region });
        checkInterval = checkInterval || 1000;
        function f() {
            CfnStack.getStackStatus(cfn, stackName).then(status => {
                var shouldStop = shouldStopCallback(status)
                if (shouldStop) {
                    return resolve();
                }
                setTimeout(f, checkInterval);
            }).catch (err => {
                reject(err);
            });
        }
        f();
    });
};

function ensureStackStateOk(stackName, region, noop) {
    var cfn = new AWS.CloudFormation({ region: region });
    return CfnStack.getStackStatus(cfn, stackName).then(status => {
        if (status !== CfnStack.Status.ROLLBACK_COMPLETE) {
            return status;
        }

        if (noop) {
            console.log('Stack ' + stackName + ' is stuck in a rollback state.');
            return CfnStack.Status.ROLLBACK_COMPLETE;
        }

        var question = util.format(
            'Stack %s is stuck in a rollback state. Would you like nova to delete it for you and then continue?',
            stackName
            );
        return utils.yesorno(question).then(shouldDelete => {
            if (!shouldDelete) {
                return Promise.reject('Stack is in inconsistent state. Cannot deploy.');
            }

            var deleteStack = utils.pbind(cfn.deleteStack, cfn, {
                StackName: stackName,
            });
            return deleteStack().then(() => {
                process.stdout.write('Deleting stack ...');
                return waitForStack(stackName, region, status => {
                    if (status === CfnStack.Status.DOES_NOT_EXIST) {
                        return true;
                    }
                    process.stdout.write('.');
                }).then(() => {
                    process.stdout.write(' done! \n');
                    return CfnStack.Status.DOES_NOT_EXIST;
                }, err => {
                    process.stdout.write('\n');
                    throw err;
                });
            });
        });
    });
}

function updateMetaData(projectName, componentName, metaData) {
    var novaBucket = program.getNovaBucket();
    var s3 = new AWS.S3({ region: novaBucket.region });

    var latestMetaKeyPath = path.join(
        'meta',
        projectName,
        'templates',
        componentName,
        'latest.json'
        );
    getObject = utils.pbind(s3.getObject, s3, {
        Bucket: novaBucket.name,
        Key: latestMetaKeyPath,
    });
    return getObject().then(data => {
        return JSON.parse(data.Body.toString());
    }, err => {
        if (err.code === 'NoSuchKey') {
            return '';
        }
        throw err;
    }).then(previousMeta => {
        if (previousMeta) {
            metaData.previousMeta = `meta/${projectName}/templates/${componentName}/${previousMeta.timestamp}.json`;
        }

        var upload = utils.pbind(s3.upload, s3);

        var uploadLatestPromise = upload({
            Bucket: novaBucket.name,
            Key: latestMetaKeyPath,
            Body: JSON.stringify(metaData, null, 2),
        });

        var uploadPreviousPromise = previousMeta
            ? upload({
                Bucket: novaBucket.name,
                Key: metaData.previousMeta,
                Body: JSON.stringify(previousMeta, null, 2),
            })
            : null;

        return Promise.all(_.compact([uploadLatestPromise, uploadPreviousPromise]));
    });
}

Command.prototype.execute = function() {
    if (program.options.verbose) {
        console.log('Loading project ' + this.project.name);
    }

    this.project.load(novalib.init({
        projectName: this.project.name,
    }));

    var componentDef = this.project.findComponent(this.componentName);
    if (!componentDef) {
        throw new Error(`Failed to find component '${this.componentName}' in project '${this.project.name}'`);
    }

    this.stackName = Component.makeStackName(this.project.name, this.componentName)
    var dependantComponents = this.project.getComponentDependencies(this.componentName);

    if (program.options.verbose) {
        console.log('Fetching outputs of dependent stacks.');
    }

    var stackInfoPromises = _.map(dependantComponents, componentName => {
        dependantComponentDef = this.project.findComponent(componentName);
        stackName = Component.makeStackName(this.project.name, dependantComponentDef.name);
        var cfn = new AWS.CloudFormation({ region : dependantComponentDef.region });
        return CfnStack.getStackInfo(cfn, stackName);
    });

    return Promise.all(stackInfoPromises).then(values => {
        var invalidStacks = _.filter(values, function(stackInfo) {
            return !CfnStack.isStatusValidCompleteState(stackInfo.status);
        });
        if (invalidStacks.length !== 0) {
            throw new Error('One of the dependent stacks is not yet deployed!');
        }
        var outputs = _.map(values, function(stackInfo) {
            return stackInfo.outputs;
        });
        return utils.zipObject(dependantComponents, outputs);
    }, err => {
        if (err === CfnStack.Status.DOES_NOT_EXIST) {
            throw new Error('One of the dependent stacks is not yet deployed!');
        }
        throw e;
    }).then(dependencyObject => {
        if (program.options.verbose) {
            console.log('Building component ' + this.componentName);
        }

        return utils.pdone(componentDef.build, componentDef, dependencyObject);
    }).then(buildResult => {
        this.buildResult = buildResult;
        this.buildResult.novaId = moment().utc().format('YYYYMMDDTHHmmss');

        if (program.options.verbose) {
            console.log('Generating cloudformation template...');
        }

        if (buildResult.resources && !(buildResult.resources instanceof Array)) {
            throw new Error('component resources must be array');
        }

        if (buildResult.outputs && !(buildResult.outputs instanceof Array)) {
            throw new Error('component outputs must be array');
        }

        if (buildResult.parameters && !(buildResult.parameters instanceof Array)) {
            throw new Error('component parameters must be array');
        }

        var stack = novaform.Stack(this.stackName);

        // Allow nova definition file components to be stl templates, we can extract the
        // resources ourselves then
        var resources = _.reduce(buildResult.resources, (memo, resource) => {
            if (resource instanceof novastl.Template) {
                return memo.concat(resource.resources());
            }
            return memo.concat(resource);
        }, []);

        stack.add(resources);
        stack.add(_.map(buildResult.parameters, 'param'));
        stack.add(buildResult.outputs || []);

        if (stack.isEmpty()) {
            throw new NovaError('Stack empty. We can pretend it was a success though.');
        }

        stack.add(novaform.Output('novaId', this.buildResult.novaId));

        var templateBody = stack.toJson();

        // Output template if reuquested
        var templateOutput = this.commandOptions['template-output'];
        if (templateOutput === '-') {
            console.log(templateBody);
        } else if (templateOutput) {
            var fd = fs.openSync(templateOutput, 'w');
            fs.writeSync(fd, templateBody);
            fs.closeSync(fd);
        }

        return templateBody;
    }).then(templateBody => {
        if (program.options.verbose) {
            console.log('Validating cloudformation template ...');
        }

        var novaBucket = program.getNovaBucket();
        var keyPath = path.join(
            'meta',
            this.project.name,
            'tmp',
            'template-to-validate.json');

        var s3 = new AWS.S3({ region: novaBucket.region });
        var upload = utils.pbind(s3.upload, s3, {
            Bucket: novaBucket.name,
            Key: keyPath,
            Body: templateBody,
        });
        return upload().then(data => {
            var cfn = new AWS.CloudFormation({ region: componentDef.region });
            var validateTemplate = utils.pbind(cfn.validateTemplate, cfn, {
                TemplateURL: data.Location,
            });
            return validateTemplate();
        }).then(data => {
            return templateBody;
        }, err => {
            if (err.code === 'ValidationError') {
                var message = 'AWS says your template is silly - ' + err.message;
                throw new NovaError(message);
            }
            throw err;
        });
    }).then(templateBody => {
        if (program.options.verbose) {
            console.log('Uploading cloudformation template to S3...');
        }

        var novaBucket = program.getNovaBucket();
        var s3 = new AWS.S3({ region: novaBucket.region });

        var timestamp = moment().utc().format('YYYYMMDDTHHmmss');
        var keyPath = path.join(
            'data',
            this.project.name,
            'templates',
            this.componentName,
            timestamp + '.json'
            );

        var upload = utils.pbind(s3.upload, s3);
        return upload({
            Bucket: novaBucket.name,
            Key: keyPath,
            Body: templateBody,
        }).then(data => {
            this.templateMetaData = {
                timestamp: this.buildResult.novaId,
                region: componentDef.region,
                keyPath: keyPath,
                location: data.Location,
            };
        }).then(() => {
            if (program.options.verbose) {
                console.log('Checking cloudformation stack status...');
            }

            return ensureStackStateOk(this.stackName, componentDef.region, this.commandOptions.noop);
        }).then(status => {
            if (program.options.verbose) {
                console.log('Deploying cloudformation stack...');
            }

            var parameters = _.map(this.buildResult.parameters, function(paramObject){
                if (paramObject.value === null || typeof paramObject.value === 'undefined') {
                    throw new Error(`Parameter values for '${paramObject.param.name}' cannot be null`);
                }
                return {
                    ParameterKey: paramObject.param.name,
                    ParameterValue: paramObject.value
                };
            });

            if (this.commandOptions.noop) {
                return 'noop-stack-id';
            }

            var cfn = new AWS.CloudFormation({ region: componentDef.region });
            var promise;
            if (status === CfnStack.Status.DOES_NOT_EXIST) {
                promise = utils.pbind(cfn.createStack, cfn, {
                    Capabilities: [ 'CAPABILITY_IAM' ], // TODO: Only use this is template validations says to
                    StackName: this.stackName,
                    TemplateURL: this.templateMetaData.location,
                    Tags: [
                        { Key: 'nova-project-name', Value: this.project.name },
                        { Key: 'nova-component-name', Value: this.componentName },
                        { Key: 'nova-initial-id', Value: this.buildResult.novaId },
                    ],
                    Parameters: parameters,
                });
            } else {
                if (!CfnStack.isStatusComplete(status)) {
                    // already in progress?
                    throw new NovaError(util.format('Stack is not in a valid state for deployment: %s', status));
                }
                promise = utils.pbind(cfn.updateStack, cfn, {
                    Capabilities: [ 'CAPABILITY_IAM' ], // TODO: Only use this is template validations says to
                    StackName: this.stackName,
                    TemplateURL: this.templateMetaData.location,
                    Parameters: parameters,
                });
            }

            return promise().then(data => {
                return data.StackId;
            }, err => {
                if (err.code === 'ValidationError') {
                    var message = 'AWS says your template no good - ' + err.message;
                    throw new NovaError(message);
                }

                throw err;
            });
        }).then(stackId => {
            if (program.options.verbose) {
                console.log('Deployed stack id ' + stackId);
            }

            this.templateMetaData.stackId = stackId;

            if (program.options.verbose) {
                console.log('Updating meta data...');
            }

            if (this.commandOptions.noop) {
                return;
            }

            return updateMetaData(this.project.name, this.componentName, this.templateMetaData);
        }).then(() => {
            if (!this.commandOptions.wait) {
                return;
            }

            process.stdout.write('Waiting for stack ...');

            if (this.commandOptions.noop) {
                process.stdout.write(' not\n');
                return;
            }
            return waitForStack(this.stackName, componentDef.region, status => {
                if (CfnStack.isStatusFailed(status)
                    || CfnStack.isStatusRolledBack(status)
                    || CfnStack.isStatusRollingback(status)) {
                    // TODO: revert meta data update?
                    throw new NovaError(util.format('Stack deployment failed: %s', status));
                }
                if (CfnStack.isStatusComplete(status)) {
                    return true;
                }

                process.stdout.write('.');
            }).then(() => {
                process.stdout.write(' done! \n');
            }, err => {
                process.stdout.write('\n');
                throw err;
            }).then(() => {
                var cfn = new AWS.CloudFormation({ region: componentDef.region });
                return CfnStack.getStackInfo(cfn, Component.makeStackName(this.project.name, this.componentName));
            }).then(stack => {
                if (!program.options.verbose) {
                    return;
                }

                if (stack.outputs) {
                    console.log('Outputs:');
                }
                _.forEach(stack.outputs, (value, key) => {
                    console.log(` * ${key}: ${value}`);
                });
            });
        });
    });

};

module.exports = Command;
<commit_msg>use this.componentDef/this.stackName in deploy command<commit_after>var _ = require('lodash')
    , AWS = require('aws-sdk')
    , changeCase = require('change-case')
    , CfnStack = require('../aws-utils/cfn-stack')
    , Component = require('../component')
    , novalib = require('../nova-lib')
    , NovaError = require('../nova-error')
    , moment = require('moment')
    , novaform = require('../novaform')
    , novastl = require('../novastl')
    , path = require('path')
    , program = require('../program')
    , ProjectRef = require('../project-ref')
    , Project = require('../project')
    , utils = require('../utils')
    , util = require('util');

function Command(opts) {
    if (!(this instanceof Command)) {
        return new Command(opts);
    }

    this.opts = opts;
    this.commandOptions = this.opts.options;

    if (_(opts.argv).isEmpty()) {
        throw new Error('Missing project/component reference');
    } else if (opts.argv.length !== 1) {
        throw new Error('Too many project/component references specified');
    }

    var ref = new ProjectRef(opts.argv[0]);
    this.project = new Project(ref.name);
    this.componentName = ref.subname;

    if (!this.componentName) {
        throw new Error('Deploy command needs a component name.');
    }
}

Command.options = [
    ['w', 'wait', 'Wait for completion'],
    ['n', 'noop', 'Do not actually deploy. But generates stack and validates it.'],
    ['', 'template-output=ARG', 'Dump the generated CloudFormation template to a file'],
];
Command.usageText = '[options] project_name/component_name';
Command.descriptionText = 'Deploys project component';

function waitForStack(stackName, region, shouldStopCallback, checkInterval) {
    return new Promise((resolve, reject) => {
        var cfn = new AWS.CloudFormation({ region: region });
        checkInterval = checkInterval || 1000;
        function f() {
            CfnStack.getStackStatus(cfn, stackName).then(status => {
                var shouldStop = shouldStopCallback(status)
                if (shouldStop) {
                    return resolve();
                }
                setTimeout(f, checkInterval);
            }).catch (err => {
                reject(err);
            });
        }
        f();
    });
};

function ensureStackStateOk(stackName, region, noop) {
    var cfn = new AWS.CloudFormation({ region: region });
    return CfnStack.getStackStatus(cfn, stackName).then(status => {
        if (status !== CfnStack.Status.ROLLBACK_COMPLETE) {
            return status;
        }

        if (noop) {
            console.log('Stack ' + stackName + ' is stuck in a rollback state.');
            return CfnStack.Status.ROLLBACK_COMPLETE;
        }

        var question = util.format(
            'Stack %s is stuck in a rollback state. Would you like nova to delete it for you and then continue?',
            stackName
            );
        return utils.yesorno(question).then(shouldDelete => {
            if (!shouldDelete) {
                return Promise.reject('Stack is in inconsistent state. Cannot deploy.');
            }

            var deleteStack = utils.pbind(cfn.deleteStack, cfn, {
                StackName: stackName,
            });
            return deleteStack().then(() => {
                process.stdout.write('Deleting stack ...');
                return waitForStack(stackName, region, status => {
                    if (status === CfnStack.Status.DOES_NOT_EXIST) {
                        return true;
                    }
                    process.stdout.write('.');
                }).then(() => {
                    process.stdout.write(' done! \n');
                    return CfnStack.Status.DOES_NOT_EXIST;
                }, err => {
                    process.stdout.write('\n');
                    throw err;
                });
            });
        });
    });
}

function updateMetaData(projectName, componentName, metaData) {
    var novaBucket = program.getNovaBucket();
    var s3 = new AWS.S3({ region: novaBucket.region });

    var latestMetaKeyPath = path.join(
        'meta',
        projectName,
        'templates',
        componentName,
        'latest.json'
        );
    getObject = utils.pbind(s3.getObject, s3, {
        Bucket: novaBucket.name,
        Key: latestMetaKeyPath,
    });
    return getObject().then(data => {
        return JSON.parse(data.Body.toString());
    }, err => {
        if (err.code === 'NoSuchKey') {
            return '';
        }
        throw err;
    }).then(previousMeta => {
        if (previousMeta) {
            metaData.previousMeta = `meta/${projectName}/templates/${componentName}/${previousMeta.timestamp}.json`;
        }

        var upload = utils.pbind(s3.upload, s3);

        var uploadLatestPromise = upload({
            Bucket: novaBucket.name,
            Key: latestMetaKeyPath,
            Body: JSON.stringify(metaData, null, 2),
        });

        var uploadPreviousPromise = previousMeta
            ? upload({
                Bucket: novaBucket.name,
                Key: metaData.previousMeta,
                Body: JSON.stringify(previousMeta, null, 2),
            })
            : null;

        return Promise.all(_.compact([uploadLatestPromise, uploadPreviousPromise]));
    });
}

Command.prototype.execute = function() {
    if (program.options.verbose) {
        console.log('Loading project ' + this.project.name);
    }

    this.project.load(novalib.init({
        projectName: this.project.name,
    }));

    this.comopnentDef = this.project.findComponent(this.componentName);
    if (!this.comopnentDef) {
        throw new Error(`Failed to find component '${this.componentName}' in project '${this.project.name}'`);
    }

    this.stackName = Component.makeStackName(this.project.name, this.componentName);
    var dependantComponents = this.project.getComponentDependencies(this.componentName);

    if (program.options.verbose) {
        console.log('Fetching outputs of dependent stacks.');
    }

    var stackInfoPromises = _.map(dependantComponents, componentName => {
        dependantComponentDef = this.project.findComponent(componentName);
        stackName = Component.makeStackName(this.project.name, dependantComponentDef.name);
        var cfn = new AWS.CloudFormation({ region : dependantComponentDef.region });
        return CfnStack.getStackInfo(cfn, stackName);
    });

    return Promise.all(stackInfoPromises).then(values => {
        var invalidStacks = _.filter(values, function(stackInfo) {
            return !CfnStack.isStatusValidCompleteState(stackInfo.status);
        });
        if (invalidStacks.length !== 0) {
            throw new Error('One of the dependent stacks is not yet deployed!');
        }
        var outputs = _.map(values, function(stackInfo) {
            return stackInfo.outputs;
        });
        return utils.zipObject(dependantComponents, outputs);
    }, err => {
        if (err === CfnStack.Status.DOES_NOT_EXIST) {
            throw new Error('One of the dependent stacks is not yet deployed!');
        }
        throw e;
    }).then(dependencyObject => {
        if (program.options.verbose) {
            console.log('Building component ' + this.componentName);
        }

        return utils.pdone(this.componentDef.build, this.componentDef, dependencyObject);
    }).then(buildResult => {
        this.buildResult = buildResult;
        this.buildResult.novaId = moment().utc().format('YYYYMMDDTHHmmss');

        if (program.options.verbose) {
            console.log('Generating cloudformation template...');
        }

        if (buildResult.resources && !(buildResult.resources instanceof Array)) {
            throw new Error('component resources must be array');
        }

        if (buildResult.outputs && !(buildResult.outputs instanceof Array)) {
            throw new Error('component outputs must be array');
        }

        if (buildResult.parameters && !(buildResult.parameters instanceof Array)) {
            throw new Error('component parameters must be array');
        }

        var stack = novaform.Stack(this.stackName);

        // Allow nova definition file components to be stl templates, we can extract the
        // resources ourselves then
        var resources = _.reduce(buildResult.resources, (memo, resource) => {
            if (resource instanceof novastl.Template) {
                return memo.concat(resource.resources());
            }
            return memo.concat(resource);
        }, []);

        stack.add(resources);
        stack.add(_.map(buildResult.parameters, 'param'));
        stack.add(buildResult.outputs || []);

        if (stack.isEmpty()) {
            throw new NovaError('Stack empty. We can pretend it was a success though.');
        }

        stack.add(novaform.Output('novaId', this.buildResult.novaId));

        var templateBody = stack.toJson();

        // Output template if reuquested
        var templateOutput = this.commandOptions['template-output'];
        if (templateOutput === '-') {
            console.log(templateBody);
        } else if (templateOutput) {
            var fd = fs.openSync(templateOutput, 'w');
            fs.writeSync(fd, templateBody);
            fs.closeSync(fd);
        }

        return templateBody;
    }).then(templateBody => {
        if (program.options.verbose) {
            console.log('Validating cloudformation template ...');
        }

        var novaBucket = program.getNovaBucket();
        var keyPath = path.join(
            'meta',
            this.project.name,
            'tmp',
            'template-to-validate.json');

        var s3 = new AWS.S3({ region: novaBucket.region });
        var upload = utils.pbind(s3.upload, s3, {
            Bucket: novaBucket.name,
            Key: keyPath,
            Body: templateBody,
        });
        return upload().then(data => {
            var cfn = new AWS.CloudFormation({ region: this.componentDef.region });
            var validateTemplate = utils.pbind(cfn.validateTemplate, cfn, {
                TemplateURL: data.Location,
            });
            return validateTemplate();
        }).then(data => {
            return templateBody;
        }, err => {
            if (err.code === 'ValidationError') {
                var message = 'AWS says your template is silly - ' + err.message;
                throw new NovaError(message);
            }
            throw err;
        });
    }).then(templateBody => {
        if (program.options.verbose) {
            console.log('Uploading cloudformation template to S3...');
        }

        var novaBucket = program.getNovaBucket();
        var s3 = new AWS.S3({ region: novaBucket.region });

        var timestamp = moment().utc().format('YYYYMMDDTHHmmss');
        var keyPath = path.join(
            'data',
            this.project.name,
            'templates',
            this.componentName,
            timestamp + '.json'
            );

        var upload = utils.pbind(s3.upload, s3);
        return upload({
            Bucket: novaBucket.name,
            Key: keyPath,
            Body: templateBody,
        }).then(data => {
            this.templateMetaData = {
                timestamp: this.buildResult.novaId,
                region: this.componentDef.region,
                keyPath: keyPath,
                location: data.Location,
            };
        }).then(() => {
            if (program.options.verbose) {
                console.log('Checking cloudformation stack status...');
            }

            return ensureStackStateOk(this.stackName, this.componentDef.region, this.commandOptions.noop);
        }).then(status => {
            if (program.options.verbose) {
                console.log('Deploying cloudformation stack...');
            }

            var parameters = _.map(this.buildResult.parameters, function(paramObject){
                if (paramObject.value === null || typeof paramObject.value === 'undefined') {
                    throw new Error(`Parameter values for '${paramObject.param.name}' cannot be null`);
                }
                return {
                    ParameterKey: paramObject.param.name,
                    ParameterValue: paramObject.value
                };
            });

            if (this.commandOptions.noop) {
                return 'noop-stack-id';
            }

            var cfn = new AWS.CloudFormation({ region: this.componentDef.region });
            var promise;
            if (status === CfnStack.Status.DOES_NOT_EXIST) {
                promise = utils.pbind(cfn.createStack, cfn, {
                    Capabilities: [ 'CAPABILITY_IAM' ], // TODO: Only use this is template validations says to
                    StackName: this.stackName,
                    TemplateURL: this.templateMetaData.location,
                    Tags: [
                        { Key: 'nova-project-name', Value: this.project.name },
                        { Key: 'nova-component-name', Value: this.componentName },
                        { Key: 'nova-initial-id', Value: this.buildResult.novaId },
                    ],
                    Parameters: parameters,
                });
            } else {
                if (!CfnStack.isStatusComplete(status)) {
                    // already in progress?
                    throw new NovaError(util.format('Stack is not in a valid state for deployment: %s', status));
                }
                promise = utils.pbind(cfn.updateStack, cfn, {
                    Capabilities: [ 'CAPABILITY_IAM' ], // TODO: Only use this is template validations says to
                    StackName: this.stackName,
                    TemplateURL: this.templateMetaData.location,
                    Parameters: parameters,
                });
            }

            return promise().then(data => {
                return data.StackId;
            }, err => {
                if (err.code === 'ValidationError') {
                    var message = 'AWS says your template no good - ' + err.message;
                    throw new NovaError(message);
                }

                throw err;
            });
        }).then(stackId => {
            if (program.options.verbose) {
                console.log('Deployed stack id ' + stackId);
            }

            this.templateMetaData.stackId = stackId;

            if (program.options.verbose) {
                console.log('Updating meta data...');
            }

            if (this.commandOptions.noop) {
                return;
            }

            return updateMetaData(this.project.name, this.componentName, this.templateMetaData);
        }).then(() => {
            if (!this.commandOptions.wait) {
                return;
            }

            process.stdout.write('Waiting for stack ...');

            if (this.commandOptions.noop) {
                process.stdout.write(' not\n');
                return;
            }
            return waitForStack(this.stackName, this.componentDef.region, status => {
                if (CfnStack.isStatusFailed(status)
                    || CfnStack.isStatusRolledBack(status)
                    || CfnStack.isStatusRollingback(status)) {
                    // TODO: revert meta data update?
                    throw new NovaError(util.format('Stack deployment failed: %s', status));
                }
                if (CfnStack.isStatusComplete(status)) {
                    return true;
                }

                process.stdout.write('.');
            }).then(() => {
                process.stdout.write(' done! \n');
            }, err => {
                process.stdout.write('\n');
                throw err;
            }).then(() => {
                var cfn = new AWS.CloudFormation({ region: this.componentDef.region });
                return CfnStack.getStackInfo(cfn, this.stackName);
            }).then(stack => {
                if (!program.options.verbose) {
                    return;
                }

                if (stack.outputs) {
                    console.log('Outputs:');
                }
                _.forEach(stack.outputs, (value, key) => {
                    console.log(` * ${key}: ${value}`);
                });
            });
        });
    });
};

module.exports = Command;
<|endoftext|>


<commit_before>// Copyright & License details are available under JXCORE_LICENSE file

var fs = require('fs');
var path = require('path');
var jxtools = require('jxtools');
var fname = 'io.jxcore.node.jx';
var dname = 'io.jxcore.node';

exports.run = function () {

  if (process.argv[2] !== 'sample')
    return;

  process.argv[2] = '--sample';
  var parsedArv = jxcore.utils.argv.parse({force: true});

  exports.useSample(parsedArv.sample.value)
};

exports.useSample = function (sampleName) {

  var dir = path.resolve(sampleName);
  if (!fs.existsSync(dir))
    dir = path.join(process.cwd(), dname, 'sample', sampleName);

  if (!fs.existsSync(dir)) {
    jxcore.utils.console.error('Wrong sample name:', sampleName);
    return;
  }

  if (path.basename(dir) !== 'www')
    dir = path.join(dir, 'www');

  var www = path.join(process.cwd(), "www");
  var backup_www = path.join(process.cwd(), "www_backup");

  if (!fs.existsSync(backup_www)) {
    jxtools.fs.copySync(www, backup_www);
  }

  var commands = [];

  var package_json = path.join(dir, "jxcore/package.json");
  var node_modules = path.join(dir, "jxcore/node_modules");

  if (fs.existsSync(package_json) && !fs.existsSync(node_modules)) {
    commands.push({
      name: "install modules",
      command: '"' + process.execPath + '" install',
      cwd: path.join(dir, 'jxcore'),
      caption: 'Installing node modules for the sample...'
    });
  }

  commands.push({
    name: 'remove_dir',
    command: jxtools.fs.getRmdirCommand(www),
    caption: 'Removing previous www folder...'
  });

  commands.push({
    name: 'copy_sample',
    command: function () {
      jxtools.fs.copySync(dir, www);
    },
    caption: 'Copying sample folder...'
  });

  commands.push({
    name: 'cordova_prepare',
    command: 'cordova prepare',
    caption: 'Executing `cordova prepare` command...'
  });

  commands.push(function () {
    jxcore.utils.console.info('The project is ising `' + sampleName + '` sample now.');
  });

  jxtools.fs.execMultiple(commands, function (ret) {
    if (ret.errors)
      jxcore.utils.console.error(ret.errors);
  });

};<commit_msg>typo fix<commit_after>// Copyright & License details are available under JXCORE_LICENSE file

var fs = require('fs');
var path = require('path');
var jxtools = require('jxtools');
var fname = 'io.jxcore.node.jx';
var dname = 'io.jxcore.node';

exports.run = function () {

  if (process.argv[2] !== 'sample')
    return;

  process.argv[2] = '--sample';
  var parsedArv = jxcore.utils.argv.parse({force: true});

  exports.useSample(parsedArv.sample.value)
};

exports.useSample = function (sampleName) {

  var dir = path.resolve(sampleName);
  if (!fs.existsSync(dir))
    dir = path.join(process.cwd(), dname, 'sample', sampleName);

  if (!fs.existsSync(dir)) {
    jxcore.utils.console.error('Wrong sample name:', sampleName);
    return;
  }

  if (path.basename(dir) !== 'www')
    dir = path.join(dir, 'www');

  var www = path.join(process.cwd(), "www");
  var backup_www = path.join(process.cwd(), "www_backup");

  if (!fs.existsSync(backup_www)) {
    jxtools.fs.copySync(www, backup_www);
  }

  var commands = [];

  var package_json = path.join(dir, "jxcore/package.json");
  var node_modules = path.join(dir, "jxcore/node_modules");

  if (fs.existsSync(package_json) && !fs.existsSync(node_modules)) {
    commands.push({
      name: "install modules",
      command: '"' + process.execPath + '" install',
      cwd: path.join(dir, 'jxcore'),
      caption: 'Installing node modules for the sample...'
    });
  }

  commands.push({
    name: 'remove_dir',
    command: jxtools.fs.getRmdirCommand(www),
    caption: 'Removing previous www folder...'
  });

  commands.push({
    name: 'copy_sample',
    command: function () {
      jxtools.fs.copySync(dir, www);
    },
    caption: 'Copying sample folder...'
  });

  commands.push({
    name: 'cordova_prepare',
    command: 'cordova prepare',
    caption: 'Executing `cordova prepare` command...'
  });

  commands.push(function () {
    jxcore.utils.console.info('The project is using `' + sampleName + '` sample now.');
  });

  jxtools.fs.execMultiple(commands, function (ret) {
    if (ret.errors)
      jxcore.utils.console.error(ret.errors);
  });

};<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var fs = require('fs');
var path = require('path');

function arrayToQueryString(args) {
  var searchString = '?q=' + args._.join('+');
  if (args.user) {
    searchString = searchString.concat('+user:' + args.user);
  }
  if (args.language) {
    searchString = searchString.concat('+language:' + args.language);
  }
  return searchString;
}

function performQuery(config, request, args) {
  var url = config.API_URI + config.SEARCH_URI + arrayToQueryString(args);
  request.get(
    {
      url: url,
      headers: {
        'User-Agent': 'request',
      },
    }, function(error, response, body) {
      var result = JSON.parse(body);
      /* jshint camelcase: false */
      console.log('Found %s repositories that match your search query',
                  result.total_count || 0);
      _.forEach(result.items, function(repo) {
        console.log(repo.full_name);
      });
      /* jshint camelcase: true */
    });
}

function help() {
  console.log(fs.readFileSync(
    path.resolve(__dirname, '../templates/help-search.txt'), 'utf8'));
}

module.exports = function(config, request, args) {
  if (args.help) {
    help();
  }  else {
    performQuery(config, request, args);
  }
};
<commit_msg>Clarify result message to show that only 30 repos are showing.<commit_after>'use strict';

var _ = require('lodash');
var fs = require('fs');
var path = require('path');

function arrayToQueryString(args) {
  var searchString = '?q=' + args._.join('+');
  if (args.user) {
    searchString = searchString.concat('+user:' + args.user);
  }
  if (args.language) {
    searchString = searchString.concat('+language:' + args.language);
  }
  return searchString;
}

function performQuery(config, request, args) {
  var url = config.API_URI + config.SEARCH_URI + arrayToQueryString(args);
  request.get(
    {
      url: url,
      headers: {
        'User-Agent': 'request',
      },
    }, function(error, response, body) {
      var result = JSON.parse(body);
      /* jshint camelcase: false */
      var res = result.total_count || 0;
      console.log('Showing %d out of %d repositories ' +
                  'that match your search query',
                  Math.min(res, 30), res);
      _.forEach(result.items, function(repo) {
        console.log(repo.full_name);
      });
      /* jshint camelcase: true */
    });
}

function help() {
  console.log(fs.readFileSync(
    path.resolve(__dirname, '../templates/help-search.txt'), 'utf8'));
}

module.exports = function(config, request, args) {
  if (args.help) {
    help();
  }  else {
    performQuery(config, request, args);
  }
};
<|endoftext|>