<commit_before>'use strict';

angular
.module('app.controllers')
.controller('EventListCtrl', function($scope, $rootScope, $stateParams, $state, Restangular, apiDescriptor, dataTransformer) {
	var resourceName = $stateParams.resourceName;
	var resourceId = $stateParams.id;
	$scope.resourceName = resourceName;
	apiDescriptor.then(function(apiDescription) {
		$scope.rdesc = apiDescription.resource(resourceName);
	});

	$scope.displayDate = function(date) {
		if (date == undefined) { return; };
		var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
		var year = parseInt(date.substring(0,4));
		var month = parseInt(date.substring(5, 7));
		return monthNames[month - 1] + " " + year;
	}

	var teamsIdToName = {};
	var venuesIdToName = {};
	var organizationIdToName = {};
	var personIdToName = {};
	$scope.eventRSVPCount = {};

	$scope.eventDetails = {
		venue : {},
		team 	: {},
		survey: {},
		feedback: {},
		coorganizers: {},
		presenters: {},
		addedBy: {},
		attendees: {},
		attendeesCount: {},
		teaches: {},
		date: {}
	};

	//mapping teamID to teamName
	Restangular.all('teams')
		.getList()
		.then(function(teams) {
			_.each(teams, function(element) {
				teamsIdToName[element.id] = element.attributes.name;
			});
		});

	//mapping venueID to venueName
	Restangular.all('venues')
		.getList()
		.then(function(teams) {
			_.each(teams, function(element) {
				venuesIdToName[element.id] = element.attributes.name;
			});
		});

	//mapping organization to organizationName
	Restangular.all('organizations')
		.getList()
		.then(function(organization) {
			_.each(organization, function(element) {
				organizationIdToName[element.id] = element.attributes.name;
			});
		});

	//mapping personID to personName
	Restangular.all('people')
		.getList()
		.then(function(person) {
			_.each(person, function(element) {
				personIdToName[element.id] = element.attributes.name;
			});
		});

	Restangular.all(resourceName)
	.getList()
	.then(function(data) {
		$scope.data = data;
		console.log($scope.data[0]);
		if (resourceId) {
			var index = _.findIndex($scope.data, {id: resourceId});
			$scope.model = $scope.data[index];
		}

		_.each($scope.data, function(element) {
			//mapping eventID to venue names
			if (element.relationships.venue.data != null) {
				$scope.eventDetails.venue[element.id] = venuesIdToName[element.relationships.venue.data.id];
			};//end

			//mapping eventID to team names
			if (element.relationships.teams.data.length > 0) {
				element.relationships.teams.data.forEach( team => {
					if ($scope.eventDetails.team[element.id] == undefined) {
						$scope.eventDetails.team[element.id] = teamsIdToName[team.id];
					} else {
						var string = $scope.eventDetails.team[element.id];
						string = string + ", " + teamsIdToName[team.id];
						$scope.eventDetails.team[element.id] = string;
					}
				});
			};//end

			//mapping eventID to survey URI
			if (element.relationships.survey.data != null) {
				Restangular.one("surveys/" + element.relationships.survey.data.id)
				.get()
				.then(function(survey) {
					$scope.eventDetails.survey[element.id] = survey.attributes.URI;
				});
			};//end

			//mapping eventID to co-organizers
			if (element.relationships.coorganizers.data != null) {
				element.relationships.coorganizers.data.forEach( organization => {
					if ($scope.eventDetails.coorganizers[element.id] == undefined) {
						$scope.eventDetails.coorganizers[element.id] = organizationIdToName[organization.id];
					} else {
						var string = $scope.eventDetails.coorganizers[element.id];
						string = string + ", " + organizationIdToName[organization.id];
						$scope.eventDetails.coorganizers[element.id] = string;
					}
				})
			};//end

			//mapping eventID to attendees & number of attendees
			$scope.eventDetails.attendeesCount[element.id] = element.relationships.attendees.data.length;
			if (element.relationships.attendees.data.length > 0) {
				element.relationships.attendees.data.forEach(response => {
					if ($scope.eventDetails.attendees[element.id] === undefined) {
						$scope.eventDetails.attendees[element.id] = personIdToName[response.id];
					} else {
						var string = $scope.eventDetails.attendees[element.id];
						string = string + ", " + personIdToName[response.id];
						$scope.eventDetails.attendees[element.id] = string;
					}
				});
			}//end

			//mapping eventID to number of RSVPs
			$scope.eventRSVPCount[element.id] = element.relationships.rsvps.data.length;

			//mapping eventID to feedback
			if (element.relationships.feedback.data.length > 0) {
				element.relationships.feedback.data.forEach(response => {
					Restangular.one("survey-responses/" + response.id)
					.get()
					.then(function(data) {
						if ($scope.eventDetails.feedback[element.id] == undefined) {
							$scope.eventDetails.feedback[element.id] = data.id;
						} else {
							var string = $scope.eventDetails.feedback[element.id];
							string = string + ", " + data.id;
							$scope.eventDetails.feedback[element.id] = string;
						}
					});
				})
			}//end

			//mapping eventID to teaches
			if (element.relationships.teaches.data.length > 0) {
				element.relationships.teaches.data.forEach(response => {
					Restangular.one("skills/" + response.id)
					.get()
					.then(function(data) {
						if ($scope.eventDetails.teaches[element.id] == undefined) {
							$scope.eventDetails.teaches[element.id] = data.attributes.name;
						} else {
							var string = $scope.eventDetails.teaches[element.id];
							string = string + ", " + data.attributes.name;
							$scope.eventDetails.teaches[element.id] = string;
						}
					});
				})
			}//end

			//mapping eventID to addedBy
			if (element.relationships.addedBy != null && element.relationships.addedBy.data != null ) {
				Restangular.one("people/" + element.relationships.addedBy.data.id)
				.get()
				.then(function(data) {
						$scope.eventDetails.addedBy[element.id] = data.attributes.name;
				});
			}

			//mapping eventID to presenters
			if (element.relationships.presenters.data.length > 0 ) {
				element.relationships.presenters.data.forEach(presenter => {
					Restangular.one("presenters/" + presenter.id)
					.get()
					.then(function(data) {
						if ($scope.eventDetails.presenters[element.id] == undefined) {
							$scope.eventDetails.presenters[element.id] = data.attributes.name;
						} else {
							var string = $scope.eventDetails.presenters[element.id];
							string = string + ", " + data.attributes.name;
							$scope.eventDetails.presenters[element.id] = string;
						}
					});
				})
			}
		});//end _.each()
	});

	$scope.updateSelection = function(newModelId) {
		// $state.go("list", {id: newModelId});
		$state.transitionTo('list',
			{id: newModelId},
			{notify: false}
		);
	};

	$scope.deleteResource = function(id) {
		dataTransformer.deleteResource($scope.resourceName, id).then(function() {
			alert('Successfully deleted this entry');
			$scope.data = Restangular.all($scope.resourceName).getList().$object;
			$scope.model = {};
			$state.transitionTo('list',
				{resourceName: $scope.resourceName},
				{
					inherit: false,
					notify: false,
					reload: true
				}
			);
		});
	};
});
<commit_msg>updated event list routing<commit_after>'use strict';

angular
.module('app.controllers')
.controller('EventListCtrl', function($scope, $rootScope, $stateParams, $state, Restangular, apiDescriptor, dataTransformer) {
	var resourceName = $stateParams.resourceName;
	var resourceId = $stateParams.id;
	$scope.resourceName = resourceName;
	apiDescriptor.then(function(apiDescription) {
		$scope.rdesc = apiDescription.resource(resourceName);
	});

	$scope.displayDate = function(date) {
		if (date == undefined) { return; };
		var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
		var year = parseInt(date.substring(0,4));
		var month = parseInt(date.substring(5, 7));
		return monthNames[month - 1] + " " + year;
	}

	var teamsIdToName = {};
	var venuesIdToName = {};
	var organizationIdToName = {};
	var personIdToName = {};
	$scope.eventRSVPCount = {};

	$scope.eventDetails = {
		venue : {},
		team 	: {},
		survey: {},
		feedback: {},
		coorganizers: {},
		presenters: {},
		addedBy: {},
		attendees: {},
		attendeesCount: {},
		teaches: {},
		date: {}
	};

	//mapping teamID to teamName
	Restangular.all('teams')
		.getList()
		.then(function(teams) {
			_.each(teams, function(element) {
				teamsIdToName[element.id] = element.attributes.name;
			});
		});

	//mapping venueID to venueName
	Restangular.all('venues')
		.getList()
		.then(function(teams) {
			_.each(teams, function(element) {
				venuesIdToName[element.id] = element.attributes.name;
			});
		});

	//mapping organization to organizationName
	Restangular.all('organizations')
		.getList()
		.then(function(organization) {
			_.each(organization, function(element) {
				organizationIdToName[element.id] = element.attributes.name;
			});
		});

	//mapping personID to personName
	Restangular.all('people')
		.getList()
		.then(function(person) {
			_.each(person, function(element) {
				personIdToName[element.id] = element.attributes.name;
			});
		});

	Restangular.all(resourceName)
	.getList()
	.then(function(data) {
		$scope.data = data;
		console.log($scope.data[0]);
		if (resourceId) {
			var index = _.findIndex($scope.data, {id: resourceId});
			$scope.model = $scope.data[index];
		}

		_.each($scope.data, function(element) {
			//mapping eventID to venue names
			if (element.relationships.venue.data != null) {
				$scope.eventDetails.venue[element.id] = venuesIdToName[element.relationships.venue.data.id];
			};//end

			//mapping eventID to team names
			if (element.relationships.teams.data.length > 0) {
				element.relationships.teams.data.forEach( team => {
					if ($scope.eventDetails.team[element.id] == undefined) {
						$scope.eventDetails.team[element.id] = teamsIdToName[team.id];
					} else {
						var string = $scope.eventDetails.team[element.id];
						string = string + ", " + teamsIdToName[team.id];
						$scope.eventDetails.team[element.id] = string;
					}
				});
			};//end

			//mapping eventID to survey URI
			if (element.relationships.survey.data != null) {
				Restangular.one("surveys/" + element.relationships.survey.data.id)
				.get()
				.then(function(survey) {
					$scope.eventDetails.survey[element.id] = survey.attributes.URI;
				});
			};//end

			//mapping eventID to co-organizers
			if (element.relationships.coorganizers.data != null) {
				element.relationships.coorganizers.data.forEach( organization => {
					if ($scope.eventDetails.coorganizers[element.id] == undefined) {
						$scope.eventDetails.coorganizers[element.id] = organizationIdToName[organization.id];
					} else {
						var string = $scope.eventDetails.coorganizers[element.id];
						string = string + ", " + organizationIdToName[organization.id];
						$scope.eventDetails.coorganizers[element.id] = string;
					}
				})
			};//end

			//mapping eventID to attendees & number of attendees
			$scope.eventDetails.attendeesCount[element.id] = element.relationships.attendees.data.length;
			if (element.relationships.attendees.data.length > 0) {
				element.relationships.attendees.data.forEach(response => {
					if ($scope.eventDetails.attendees[element.id] === undefined) {
						$scope.eventDetails.attendees[element.id] = personIdToName[response.id];
					} else {
						var string = $scope.eventDetails.attendees[element.id];
						string = string + ", " + personIdToName[response.id];
						$scope.eventDetails.attendees[element.id] = string;
					}
				});
			}//end

			//mapping eventID to number of RSVPs
			$scope.eventRSVPCount[element.id] = element.relationships.rsvps.data.length;

			//mapping eventID to feedback
			if (element.relationships.feedback.data.length > 0) {
				element.relationships.feedback.data.forEach(response => {
					Restangular.one("survey-responses/" + response.id)
					.get()
					.then(function(data) {
						if ($scope.eventDetails.feedback[element.id] == undefined) {
							$scope.eventDetails.feedback[element.id] = data.id;
						} else {
							var string = $scope.eventDetails.feedback[element.id];
							string = string + ", " + data.id;
							$scope.eventDetails.feedback[element.id] = string;
						}
					});
				})
			}//end

			//mapping eventID to teaches
			if (element.relationships.teaches.data.length > 0) {
				element.relationships.teaches.data.forEach(response => {
					Restangular.one("skills/" + response.id)
					.get()
					.then(function(data) {
						if ($scope.eventDetails.teaches[element.id] == undefined) {
							$scope.eventDetails.teaches[element.id] = data.attributes.name;
						} else {
							var string = $scope.eventDetails.teaches[element.id];
							string = string + ", " + data.attributes.name;
							$scope.eventDetails.teaches[element.id] = string;
						}
					});
				})
			}//end

			//mapping eventID to addedBy
			if (element.relationships.addedBy != null && element.relationships.addedBy.data != null ) {
				Restangular.one("people/" + element.relationships.addedBy.data.id)
				.get()
				.then(function(data) {
						$scope.eventDetails.addedBy[element.id] = data.attributes.name;
				});
			}

			//mapping eventID to presenters
			if (element.relationships.presenters.data.length > 0 ) {
				element.relationships.presenters.data.forEach(presenter => {
					Restangular.one("presenters/" + presenter.id)
					.get()
					.then(function(data) {
						if ($scope.eventDetails.presenters[element.id] == undefined) {
							$scope.eventDetails.presenters[element.id] = data.attributes.name;
						} else {
							var string = $scope.eventDetails.presenters[element.id];
							string = string + ", " + data.attributes.name;
							$scope.eventDetails.presenters[element.id] = string;
						}
					});
				})
			}
		});//end _.each()
	});

	$scope.updateSelection = function(newModelId) {
		var index =	_.findIndex($scope.data, {'id': newModelId});
		$scope.model = $scope.data[index];
		$state.transitionTo('list',
			{id: newModelId, resourceName: resourceName},
			{notify: false}
		);
	};

	$scope.deleteResource = function(id) {
		dataTransformer.deleteResource($scope.resourceName, id).then(function() {
			alert('Successfully deleted this entry');
			$scope.data = Restangular.all($scope.resourceName).getList().$object;
			$scope.model = {};
			$state.transitionTo('list',
				{resourceName: $scope.resourceName},
				{
					inherit: false,
					notify: false,
					reload: true
				}
			);
		});
	};
});
<|endoftext|>


<commit_before>import React from 'react';
import LineChart from './LineChart';

import eastData from './east.json';
import northData from './north.json';
import allData from './all.json';

const colors = [undefined, '#a7a7a7', '#99b2ce', '#3b5d85', '#ab070a', '#e3070a'];

const stackUnitGrowth = json => json.map((year) => {
  // eslint-disable-next-line no-param-reassign
  year['Multifamily Unit Growth (Stacked)'] += year['Single Family Unit Growth (Stacked)'];
  return year;
});

const headingStyle = {
  textAlign: 'center',
  padding: '0 1em',
};

const pStyle = {
  maxWidth: '800px',
  marginLeft: 'auto',
  marginRight: 'auto',
  padding: '0 1em',
};

const TempProdVsCost = () =>

Housing Production and Cost

      Over the last ten years, the Portland region has
      gained
       over
      250,000 new residents.
      But it takes time to finance, design, and build new buildings. During this same period, the
      Portland metro area built

         27,000 fewer homes

       than expected given its rising population. Even with all the new high rises in inner
      Portland, new units will take years to catch up with demand. This series of line graphs
      invites you to explore the relationship of population and housing production to housing
      costs. Check back next month for an interactive version of these graphs that will allow you
      to explore your neighborhood and compare it to other neighborhoods around the city.

      In order to better compare values, these graphs compare annual percentage growth rather than
      absolute values. In the charts that follow, a line that holds steady at 2%, for example,
      represents steady growth. A line that increases represents an acceleration (in costs, in
      production of housing units, etc.). And a decreasing line that remains above zero represents
      a slowing in the rate of growth.

      There are some commonalities between all Portland neighborhoods: Homeownership prices were
      still decreasing in 2011 following the housing crash of 2008, but began a rapid acceleration
      in 2012, followed by a brief slowing in the rate of growth in 2014. Rental prices grew every
      year from 2011 through 2015, although again, there was a brief slowing of the rate of growth
      in 2014.

Portland Housing Production and Costs

    <LineChart data={stackUnitGrowth(allData)} colors={colors} />

      This pattern of increasing and moderating growth holds true across all neighborhoods.
      However, we see a slower rate of growth in housing costs in inner Portland neighborhoods that
      experienced significant new construction, like the Interstate corridor and NE Alberta:

Inner N and NE Portland Housing Production and Costs

    <LineChart data={stackUnitGrowth(northData)} colors={colors} />

      In contrast, areas that saw little new construction, like outer East Portland, saw steeper
      increases in both home prices and rental costs.

Outer East Portland Housing Production and Costs

    <LineChart data={stackUnitGrowth(eastData)} colors={colors} />

      These charts suggest that greater amounts of new housing built in specific neighborhoods has
      been correlated with a slowing of the rate at which the cost of housing increases in those
      same neighborhoods. What does this mean for Portland going forward? Explore the underlying
      data, and consider its implications for our city
      here.

;

export default TempProdVsCost;
<commit_msg>Make Production and Cost a StoryCard<commit_after>import React from 'react';
import StoryCard from '@hackoregon/component-library/lib/StoryCard/StoryCard';

import LineChart from './LineChart';

import eastData from './east.json';
import northData from './north.json';
import allData from './all.json';

const colors = [undefined, '#a7a7a7', '#99b2ce', '#3b5d85', '#ab070a', '#e3070a'];

const stackUnitGrowth = json => json.map((year) => {
  // eslint-disable-next-line no-param-reassign
  year['Multifamily Unit Growth (Stacked)'] += year['Single Family Unit Growth (Stacked)'];
  return year;
});

const headingStyle = {
  textAlign: 'center',
  padding: '0 1em',
};

const pStyle = {
  maxWidth: '800px',
  marginLeft: 'auto',
  marginRight: 'auto',
  padding: '0 1em',
  textAlign: 'left',
};

const TempProdVsCost = () =>
  <StoryCard title="Housing Production and Cost" collectionId="housing" cardId="production-and-cost">

      Over the last ten years, the Portland region has
      gained
       over
      250,000 new residents.
      But it takes time to finance, design, and build new buildings. During this same period, the
      Portland metro area built

         27,000 fewer homes

       than expected given its rising population. Even with all the new high rises in inner
      Portland, new units will take years to catch up with demand. This series of line graphs
      invites you to explore the relationship of population and housing production to housing
      costs. Check back next month for an interactive version of these graphs that will allow you
      to explore your neighborhood and compare it to other neighborhoods around the city.

      In order to better compare values, these graphs compare annual percentage growth rather than
      absolute values. In the charts that follow, a line that holds steady at 2%, for example,
      represents steady growth. A line that increases represents an acceleration (in costs, in
      production of housing units, etc.). And a decreasing line that remains above zero represents
      a slowing in the rate of growth.

      There are some commonalities between all Portland neighborhoods: Homeownership prices were
      still decreasing in 2011 following the housing crash of 2008, but began a rapid acceleration
      in 2012, followed by a brief slowing in the rate of growth in 2014. Rental prices grew every
      year from 2011 through 2015, although again, there was a brief slowing of the rate of growth
      in 2014.

Portland Housing Production and Costs

    <LineChart data={stackUnitGrowth(allData)} colors={colors} />

      This pattern of increasing and moderating growth holds true across all neighborhoods.
      However, we see a slower rate of growth in housing costs in inner Portland neighborhoods that
      experienced significant new construction, like the Interstate corridor and NE Alberta:

Inner N and NE Portland Housing Production and Costs

    <LineChart data={stackUnitGrowth(northData)} colors={colors} />

      In contrast, areas that saw little new construction, like outer East Portland, saw steeper
      increases in both home prices and rental costs.

Outer East Portland Housing Production and Costs

    <LineChart data={stackUnitGrowth(eastData)} colors={colors} />

      These charts suggest that greater amounts of new housing built in specific neighborhoods has
      been correlated with a slowing of the rate at which the cost of housing increases in those
      same neighborhoods. What does this mean for Portland going forward? Explore the underlying
      data, and consider its implications for our city
      here.

  </StoryCard>;

export default TempProdVsCost;
<|endoftext|>


<commit_before>angular.module('feedbackcontrol', [])
.directive('transform', function(FeedbackSignal) {
    return {
        restrict: 'A'
      , link: function($scope, element, attrs) {

            var currentUrl = window.location.pathname;

            $(element).bind('click', function(e) {
                var me = $(element);
                $scope.$watch('checkFeedbackStatus', function() {
                    $scope.mystatus = FeedbackSignal.data;
                    console.log($scope.mystatus);
                    /*
                    if(currentUrl.match(/inbox\/all|deleted/g)) {
                        if(data.id.length > 0) {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }
                    }

                    if(currentUrl.match(/published/g)) {

                        if(me.attr('return-policy') == 1) {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }

                        if(data.status == "feature") {
                            var state = {
                                activate: {'background-position': '-64px -31px'}
                              , deactivate_sibling: {'background-position': '-32px 0px'}
                              , activation_color: 'featured'
                              , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                              , state_change: '{"status": "publish", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                              , present_status: "feature"
                            }
                            published_state(me, '.publish', 'publish feedback', state);
                        }

                        if(data.status == "publish") {
                            var state = {
                                activate: {'background-position': '-32px -31px'}
                              , deactivate_sibling: {'background-position': '-64px 0px'}
                              , activation_color: 'published'
                              , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                              , state_change: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                              , present_status: "publish"
                            }
                            published_state(me, '.feature', 'feature feedback', state);
                        }

                        if(data.status == "delete" || data.status == "fileas") {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }

                    }

                    if(currentUrl.match(/filed/g)) {

                        var data_status = data.status;

                        if(data_status == "publish" || data_status == "feature" || data_status == "delete") {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }

                        if(data_status == "fileas") {
                            $(me).parents(".dashboard-feedback")
                                   .children("div.feedback-contents")
                                   .children(".responsive-padding")
                                   .children(".feedback-details")
                                   .children(".filed")
                                   .html($(me).text())
                        }

                    }
                    */
                })

                e.preventDefault();
            });
        }
    }
})
.directive('undo', function(FeedbackSignal, FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {

                var currentUrl = window.location.pathname;
                $(".checky-box-container").hide();

                if (FeedbackSignal.data.id instanceof Array) {
                    for(var i=0; i < FeedbackSignal.data.id.length ; i++) {
                        var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id[i] + "]");

                        feedback.show();
                        $(feedback).parents('.feedback-group').show();

                        if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                            var catpicks = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id[i] + "] li .cat-picks");
                            catpicks.css({'background': '#598499'});
                        }
                    }
                } else {
                    var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id + "]");

                    feedback.show();
                    $(feedback).parents('.feedback-group').show();

                    if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                        var catpicks = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id + "] li .cat-picks");
                        catpicks.css({'background': '#598499'});
                    }

                    var checkbox = $(".feed-checkbox[value=" + FeedbackSignal.data.id + "]");

                    if(checkbox.is(":checked")) {
                        checkbox.click();
                    }
                }

                if($(".sorter-checkbox").is(":checked")) {
                    $(".sorter-checkbox").click();
                }

                if($('.feed-checkbox').is(":checked")) {
                    $('.feed-checkbox').prop("checked", false);
                }

                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('close', function(FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('feedcheckbox', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            var checkbox = $(element);

            checkbox.bind('change', function() {
                if(checkbox.is(":checked")) {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#F7F7F7'});
                } else {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#FFF'});
                }
            });

        }
    }
})
.directive('statuschange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "@feedid"
          , statustype: "@statustype"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                var status_class, value;
                var myvalue = $(this).val();
                if(scope.statustype == "status") {
                   status_class = ".status-line";
                   console.log(myvalue);
                   if(myvalue == "new") { value = "New"; }
                   if(myvalue == "inprogress") { value = "In Progress"; }
                   if(myvalue == "closed") { value = "Closed"; }
                } else {
                   status_class = ".priority-line";
                   console.log(myvalue);
                   if(myvalue == 0) { value = "Low"; }
                   if(myvalue == 60) { value = "Medium"; }
                   if(myvalue == 100) { value = "High"; }
                }

                $(this).parents(".dashboard-feedback")
                       .children("div.feedback-contents")
                       .children(".responsive-padding")
                       .children(".feedback-details")
                       .children(".feedback-details-status")
                       .children(status_class)
                       .html(value)

                FeedbackService.inline_change($(this).val(), scope.feedid, scope.statustype);
            })
        }
    }
})
.directive('deleteBlock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $(this).parents('.custom-att').fadeOut(400, function() {
                     var new_uploaded_images = new Array;
                     var new_attached_link;

                     var div = $(this).parents('.uploaded-images-and-links');
                     var images = div.find('.uploaded_image');
                     var media_attachment = div.find('.attached_link');

                     var remove_image = {
                        'small_url'    :$(this).find('.small-image-url').val(),
                        'medium_url'   :$(this).find('.medium-image-url').val(),
                        'large_url'    :$(this).find('.large-image-url').val()
                     }

                    if(images.length > 0){
                        var us = images.not(":hidden");
                        for(var i=0; i < us.length; i++) {
                            new_uploaded_images.push({
                                'name': $(us[i]).find('.image-name').val()
                            });
                        }
                    }

                    if(!media_attachment.is(":hidden")) {
                        new_attached_link = {
                            title           : media_attachment.find('.link-title').val(),
                            description     : media_attachment.find('.link-description').val(),
                            image           : media_attachment.find('.link-image').val(),
                            url             : media_attachment.find('.link-url').val(),
                            video           : media_attachment.find('.link-video').val(),
                        }
                    }

                    var remaining = {
                        uploaded_images : new_uploaded_images
                      , attached_link   : new_attached_link
                    }

                    var attachment_data = {
                        feedbackId      : div.find('.attachment_feedback_id').val()
                      , attachments     : remaining
                      , remove_image    : remove_image
                    }

                    //place this in service you lazy bastard!
                    $.ajax({
                        type: "POST"
                      , url: "/inbox/update_feedback_attachment"
                      , dataType: "json"
                      , data: attachment_data
                    });
                });
                e.preventDefault();
            })
        }
    }
})
.directive('flag', function(FeedbackControlService, Template) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {

            var current_url = window.location.pathname;

            $(element).bind('click', function(e) {
                var policy = $(this).attr("return-policy");
                if(policy == 1) {
                    $(this).removeAttr("style");
                    $(this).attr("return-policy", 0);
                } else {
                    $(this).attr("style", "background-position: -194px -31px");
                    $(this).attr("return-policy", 1);
                }

                var feed = $.parseJSON($(this).attr('data-feed'));
                var return_policy = $(this).attr('return-policy') == true;

                var modfeed = {
                    id: feed.id
                  , catid: (current_url.match(/filed/g)) ? feed.catid : Template.default_category_id
                  , status: (return_policy) ? feed.status : 'unflag'
                  , origin: Template.current_inbox_state
                }

                FeedbackControlService.flag_feedback(modfeed);
                e.preventDefault();
            });
        }
    }
})

function published_state(obj, sibling_id, msg, state) {
    //kill me....
    if(state.activation_color == 'featured') {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('published');
    } else {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('featured');
    }

    obj.css(state.activate);
    obj.children('.action-tooltip').children('span').html("Return to Inbox");
    obj.siblings(sibling_id).css(state.deactivate_sibling);
    obj.siblings(sibling_id).children('.action-tooltip').children('span').html(msg);
    obj.siblings(sibling_id).attr('return-policy', 0);
    obj.siblings(sibling_id).attr('data-feed', state.state_change);
    obj.attr('return-policy', 1);
    obj.attr('data-feed', state.state_change_inbox);

    var origin_cat_data = obj.siblings('.save')
                             .children('div.the-categories-menu')
                             .children('.the-categories-menu-content')
                             .children(".the-categories")
                             .children(".grids")
                             .children('li')
                             .children('a');

    for(var i=0;i<origin_cat_data.length;i++) {
        var cat = $(origin_cat_data[i]);

        var feed = $.parseJSON(cat.attr('data-feed'));
        feed.status = "fileas";
        feed.origin = state.present_status

        var repackaged_json = JSON.stringify(feed);
        cat.attr('data-feed', repackaged_json);
    }

    var action_delete = obj.parents('.grids').siblings('.grids').children('.action-delete');
    var delete_button = obj.siblings('.save')
                           .children('div.the-categories-menu')
                           .children('.the-categories-menu-content')
                           .children(".the-categories-delete")
                           .children('a');

    var delete_feed_attr = $.parseJSON(action_delete.attr('data-feed'));
    delete_feed_attr.origin = state.present_status;
    var repackaged_feed_attr = JSON.stringify(delete_feed_attr);

    action_delete.attr('data-feed', repackaged_feed_attr);
    delete_button.attr('data-feed', repackaged_feed_attr);
}

function hide_the_children(obj) {
    obj.parents('.dashboard-feedback').hide();
    var child_count = obj.parents('.feedback-group').children('.dashboard-feedback:visible');
    if(child_count.length == 0) {
        obj.parents('.feedback-group').hide();
    }
}
<commit_msg>represent most of the power in this town<commit_after>angular.module('feedbackcontrol', [])
.directive('transform', function(FeedbackSignal) {
    return {
        restrict: 'A'
      , link: function($scope, element, attrs) {

            var currentUrl = window.location.pathname;

            $(element).bind('click', function(e) {
                $scope.$watch('checkFeedbackStatus', function() {
                    var me = $(element);
                    $scope.mystatus = FeedbackSignal.data;
                    console.log($scope.mystatus);
                    console.log(me);
                    /*
                    if(currentUrl.match(/inbox\/all|deleted/g)) {
                        if(data.id.length > 0) {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }
                    }

                    if(currentUrl.match(/published/g)) {

                        if(me.attr('return-policy') == 1) {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }

                        if(data.status == "feature") {
                            var state = {
                                activate: {'background-position': '-64px -31px'}
                              , deactivate_sibling: {'background-position': '-32px 0px'}
                              , activation_color: 'featured'
                              , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                              , state_change: '{"status": "publish", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                              , present_status: "feature"
                            }
                            published_state(me, '.publish', 'publish feedback', state);
                        }

                        if(data.status == "publish") {
                            var state = {
                                activate: {'background-position': '-32px -31px'}
                              , deactivate_sibling: {'background-position': '-64px 0px'}
                              , activation_color: 'published'
                              , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                              , state_change: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "feature"}'
                              , present_status: "publish"
                            }
                            published_state(me, '.feature', 'feature feedback', state);
                        }

                        if(data.status == "delete" || data.status == "fileas") {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }

                    }

                    if(currentUrl.match(/filed/g)) {

                        var data_status = data.status;

                        if(data_status == "publish" || data_status == "feature" || data_status == "delete") {
                            hide_the_children(me);
                            $(".checky-box-container").show();
                        }

                        if(data_status == "fileas") {
                            $(me).parents(".dashboard-feedback")
                                   .children("div.feedback-contents")
                                   .children(".responsive-padding")
                                   .children(".feedback-details")
                                   .children(".filed")
                                   .html($(me).text())
                        }

                    }
                    */
                })

                e.preventDefault();
            });
        }
    }
})
.directive('undo', function(FeedbackSignal, FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {

                var currentUrl = window.location.pathname;
                $(".checky-box-container").hide();

                if (FeedbackSignal.data.id instanceof Array) {
                    for(var i=0; i < FeedbackSignal.data.id.length ; i++) {
                        var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id[i] + "]");

                        feedback.show();
                        $(feedback).parents('.feedback-group').show();

                        if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                            var catpicks = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id[i] + "] li .cat-picks");
                            catpicks.css({'background': '#598499'});
                        }
                    }
                } else {
                    var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id + "]");

                    feedback.show();
                    $(feedback).parents('.feedback-group').show();

                    if(currentUrl.match(/inbox\/all|deleted|published/g)) {
                        var catpicks = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id + "] li .cat-picks");
                        catpicks.css({'background': '#598499'});
                    }

                    var checkbox = $(".feed-checkbox[value=" + FeedbackSignal.data.id + "]");

                    if(checkbox.is(":checked")) {
                        checkbox.click();
                    }
                }

                if($(".sorter-checkbox").is(":checked")) {
                    $(".sorter-checkbox").click();
                }

                if($('.feed-checkbox').is(":checked")) {
                    $('.feed-checkbox').prop("checked", false);
                }

                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('close', function(FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('feedcheckbox', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            var checkbox = $(element);

            checkbox.bind('change', function() {
                if(checkbox.is(":checked")) {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#F7F7F7'});
                } else {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#FFF'});
                }
            });

        }
    }
})
.directive('statuschange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "@feedid"
          , statustype: "@statustype"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                var status_class, value;
                var myvalue = $(this).val();
                if(scope.statustype == "status") {
                   status_class = ".status-line";
                   console.log(myvalue);
                   if(myvalue == "new") { value = "New"; }
                   if(myvalue == "inprogress") { value = "In Progress"; }
                   if(myvalue == "closed") { value = "Closed"; }
                } else {
                   status_class = ".priority-line";
                   console.log(myvalue);
                   if(myvalue == 0) { value = "Low"; }
                   if(myvalue == 60) { value = "Medium"; }
                   if(myvalue == 100) { value = "High"; }
                }

                $(this).parents(".dashboard-feedback")
                       .children("div.feedback-contents")
                       .children(".responsive-padding")
                       .children(".feedback-details")
                       .children(".feedback-details-status")
                       .children(status_class)
                       .html(value)

                FeedbackService.inline_change($(this).val(), scope.feedid, scope.statustype);
            })
        }
    }
})
.directive('deleteBlock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $(this).parents('.custom-att').fadeOut(400, function() {
                     var new_uploaded_images = new Array;
                     var new_attached_link;

                     var div = $(this).parents('.uploaded-images-and-links');
                     var images = div.find('.uploaded_image');
                     var media_attachment = div.find('.attached_link');

                     var remove_image = {
                        'small_url'    :$(this).find('.small-image-url').val(),
                        'medium_url'   :$(this).find('.medium-image-url').val(),
                        'large_url'    :$(this).find('.large-image-url').val()
                     }

                    if(images.length > 0){
                        var us = images.not(":hidden");
                        for(var i=0; i < us.length; i++) {
                            new_uploaded_images.push({
                                'name': $(us[i]).find('.image-name').val()
                            });
                        }
                    }

                    if(!media_attachment.is(":hidden")) {
                        new_attached_link = {
                            title           : media_attachment.find('.link-title').val(),
                            description     : media_attachment.find('.link-description').val(),
                            image           : media_attachment.find('.link-image').val(),
                            url             : media_attachment.find('.link-url').val(),
                            video           : media_attachment.find('.link-video').val(),
                        }
                    }

                    var remaining = {
                        uploaded_images : new_uploaded_images
                      , attached_link   : new_attached_link
                    }

                    var attachment_data = {
                        feedbackId      : div.find('.attachment_feedback_id').val()
                      , attachments     : remaining
                      , remove_image    : remove_image
                    }

                    //place this in service you lazy bastard!
                    $.ajax({
                        type: "POST"
                      , url: "/inbox/update_feedback_attachment"
                      , dataType: "json"
                      , data: attachment_data
                    });
                });
                e.preventDefault();
            })
        }
    }
})
.directive('flag', function(FeedbackControlService, Template) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {

            var current_url = window.location.pathname;

            $(element).bind('click', function(e) {
                var policy = $(this).attr("return-policy");
                if(policy == 1) {
                    $(this).removeAttr("style");
                    $(this).attr("return-policy", 0);
                } else {
                    $(this).attr("style", "background-position: -194px -31px");
                    $(this).attr("return-policy", 1);
                }

                var feed = $.parseJSON($(this).attr('data-feed'));
                var return_policy = $(this).attr('return-policy') == true;

                var modfeed = {
                    id: feed.id
                  , catid: (current_url.match(/filed/g)) ? feed.catid : Template.default_category_id
                  , status: (return_policy) ? feed.status : 'unflag'
                  , origin: Template.current_inbox_state
                }

                FeedbackControlService.flag_feedback(modfeed);
                e.preventDefault();
            });
        }
    }
})

function published_state(obj, sibling_id, msg, state) {
    //kill me....
    if(state.activation_color == 'featured') {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('published');
    } else {
        obj.parents('.dashboard-feedback').addClass(state.activation_color);
        obj.parents('.dashboard-feedback').removeClass('featured');
    }

    obj.css(state.activate);
    obj.children('.action-tooltip').children('span').html("Return to Inbox");
    obj.siblings(sibling_id).css(state.deactivate_sibling);
    obj.siblings(sibling_id).children('.action-tooltip').children('span').html(msg);
    obj.siblings(sibling_id).attr('return-policy', 0);
    obj.siblings(sibling_id).attr('data-feed', state.state_change);
    obj.attr('return-policy', 1);
    obj.attr('data-feed', state.state_change_inbox);

    var origin_cat_data = obj.siblings('.save')
                             .children('div.the-categories-menu')
                             .children('.the-categories-menu-content')
                             .children(".the-categories")
                             .children(".grids")
                             .children('li')
                             .children('a');

    for(var i=0;i<origin_cat_data.length;i++) {
        var cat = $(origin_cat_data[i]);

        var feed = $.parseJSON(cat.attr('data-feed'));
        feed.status = "fileas";
        feed.origin = state.present_status

        var repackaged_json = JSON.stringify(feed);
        cat.attr('data-feed', repackaged_json);
    }

    var action_delete = obj.parents('.grids').siblings('.grids').children('.action-delete');
    var delete_button = obj.siblings('.save')
                           .children('div.the-categories-menu')
                           .children('.the-categories-menu-content')
                           .children(".the-categories-delete")
                           .children('a');

    var delete_feed_attr = $.parseJSON(action_delete.attr('data-feed'));
    delete_feed_attr.origin = state.present_status;
    var repackaged_feed_attr = JSON.stringify(delete_feed_attr);

    action_delete.attr('data-feed', repackaged_feed_attr);
    delete_button.attr('data-feed', repackaged_feed_attr);
}

function hide_the_children(obj) {
    obj.parents('.dashboard-feedback').hide();
    var child_count = obj.parents('.feedback-group').children('.dashboard-feedback:visible');
    if(child_count.length == 0) {
        obj.parents('.feedback-group').hide();
    }
}
<|endoftext|>


<commit_before>/*
 * Nutz.Dao 的默认支持数据库的种类
 */
var ioc = {

	/*
	 * Experts 的映射列表
	 */
	experts : {
		"h2.*" : "org.nutz.dao.impl.jdbc.h2.H2JdbcExpert",
		"mysql.*" : "org.nutz.dao.impl.jdbc.mysql.MysqlJdbcExpert",
		"postgresql.*" : "org.nutz.dao.impl.jdbc.psql.PsqlJdbcExpert",
		"db2.*" : "org.nutz.dao.impl.jdbc.db2.Db2JdbcExpert",
		"oracle.*" : "org.nutz.dao.impl.jdbc.oracle.OracleJdbcExpert",
		// SqlServer2005 --> 9.0 , SqlServer2008 --> 10.0
		"microsoft sql server.*(9|10)[.].+" : "org.nutz.dao.impl.jdbc.sqlserver2005.Sqlserver2005JdbcExpert",
		"microsoft sql server.*(8)[.].+" : "org.nutz.dao.impl.jdbc.sqlserver2000.Sqlserver2000JdbcExpert",
		"microsoft sql server.*(11|12|13|14|15)[.].+" : "org.nutz.dao.impl.jdbc.sqlserver2005.Sqlserver2005JdbcExpert",
		"hsql.*" : "org.nutz.dao.impl.jdbc.hsqldb.HsqldbJdbcExpert",
		"sqlite" : "org.nutz.dao.impl.jdbc.sqlite.SQLiteJdbcExpert",
		".+derby.+" : "org.nutz.dao.impl.jdbc.derby.DerbyJdbcExpert",
		"gbase.*" : "org.nutz.dao.impl.jdbc.gbase.GBaseJdbcExpert",
		"sybase.*" : "org.nutz.dao.impl.jdbc.sybase.SybaseIQJdbcExpert",
		"dm dbms.*" : "org.nutz.dao.impl.jdbc.dm.DmJdbcExpert",
		"tdengine.*" : "org.nutz.dao.impl.jdbc.tdengine.TDengineJdbcExpert",
		"clickhouse.*" : "org.nutz.dao.impl.jdbc.clickhouse.ClickhouseJdbcExpert"
	// ~ 映射结束
	},

	/*
	 * 所有 Expert 都能读到这个配置文件
	 */
	config : {
	// 默认的 Clob 以及 Blog 临时目录
	"pool-home" : "~/.nutz/tmp/dao/",
	// 临时目录大小，0 为不限大小
	"pool-max" : 200000,
	// Mysql 特殊配置
	"mysql-engine" : "InnoDB",
	// GBase 特殊配置
	"gbase-engine" : "GsDB"
	// ～ 配置信息结束
	} };<commit_msg>Update nutz_jdbc_experts.js<commit_after>/*
 * Nutz.Dao 的默认支持数据库的种类
 */
var ioc = {

	/*
	 * Experts 的映射列表
	 */
	experts : {
		"h2.*" : "org.nutz.dao.impl.jdbc.h2.H2JdbcExpert",
		"mysql.*" : "org.nutz.dao.impl.jdbc.mysql.MysqlJdbcExpert",
		"postgresql.*" : "org.nutz.dao.impl.jdbc.psql.PsqlJdbcExpert",
		"db2.*" : "org.nutz.dao.impl.jdbc.db2.Db2JdbcExpert",
		"oracle.*" : "org.nutz.dao.impl.jdbc.oracle.OracleJdbcExpert",
		// SqlServer2005 --> 9.0 , SqlServer2008 --> 10.0
		"microsoft sql server.*(9|10)[.].+" : "org.nutz.dao.impl.jdbc.sqlserver2005.Sqlserver2005JdbcExpert",
		"microsoft sql server.*(8)[.].+" : "org.nutz.dao.impl.jdbc.sqlserver2000.Sqlserver2000JdbcExpert",
		"microsoft sql server.*(11|12|13|14|15)[.].+" : "org.nutz.dao.impl.jdbc.sqlserver2005.Sqlserver2005JdbcExpert",
		"hsql.*" : "org.nutz.dao.impl.jdbc.hsqldb.HsqldbJdbcExpert",
		"sqlite" : "org.nutz.dao.impl.jdbc.sqlite.SQLiteJdbcExpert",
		".+derby.+" : "org.nutz.dao.impl.jdbc.derby.DerbyJdbcExpert",
		"gbase.*" : "org.nutz.dao.impl.jdbc.gbase.GBaseJdbcExpert",
		"sybase.*" : "org.nutz.dao.impl.jdbc.sybase.SybaseIQJdbcExpert",
		"dm dbms.*" : "org.nutz.dao.impl.jdbc.dm.DmJdbcExpert",
		"tdengine.*" : "org.nutz.dao.impl.jdbc.tdengine.TDengineJdbcExpert",
		"clickhouse.*" : "org.nutz.dao.impl.jdbc.clickhouse.ClickhouseJdbcExpert"
	// ~ 映射结束
	},

	/*
	 * 所有 Expert 都能读到这个配置文件
	 */
	config : {
	// 默认的 Clob/Blob 临时目录
	"pool-home" : "~/.nutz/tmp/dao/",
	// 临时目录大小，0 为不限大小
	"pool-max" : 200000,
	// Mysql 特殊配置
	"mysql-engine" : "InnoDB",
	// GBase 特殊配置
	"gbase-engine" : "GsDB"
	// ～ 配置信息结束
	} };
<|endoftext|>


<commit_before>import React from 'react';

export default class ImagePreview extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { value } = this.props;
    return value ?  : null;
  }
}
<commit_msg>Back to original file formatting<commit_after>import React from 'react';

export default class ImagePreview extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { value } = this.props;
    return value ?  : null;
  }
}
<|endoftext|>


<commit_before>jQuery(function($) {
  var FlockState = window.FlockState || {};

  var size = {
    width: window.innerWidth,
    height: window.innerHeight
  };

  // Initialize some variables
  var boids = [];
  var groupTogether = false;
  var opticalFlowVector = new PIXI.Vector(0, 0);
  var path = [];
  var speedFactor = 1;

  // create an new instance of a pixi _stage - and set it to be interactive
  var _stage = new PIXI.Stage(0xffffff);
  _stage.setInteractive(true);

  // create a _renderer instance
  var _renderer = PIXI.autoDetectRenderer(size.width, size.height);

  _renderer.view.style.width = size.width + "px";
  _renderer.view.style.height = size.height + "px";

  _renderer.view.style.display = "block";

  requestAnimFrame(animate);
  var renderTexture = new PIXI.RenderTexture(size.width, size.height);

  var _target = new PIXI.DisplayObjectContainer();
  _stage.addChild(_target);

  // add render view to DOM
  document.body.appendChild(_renderer.view);

  var count = 0;

  // Create a path. This is for testing. Ideally we should detect an outline with an IR camera and using that data for the path.
  var steps = 90;
  for (var i = 0; i < steps; i++) {
    path.push(new PIXI.Vector(
      (size.width / 2) + 300 * Math.cos(2 * Math.PI * i / steps),
      (size.height / 2) + 300 * Math.sin(2 * Math.PI * i / steps)
     ));
  }

  var Boid = function(position, maxSpeed, maxForce) {
    var strength = Math.random() + 1.5;
    this.acceleration = new PIXI.Vector();
    this.vector = new PIXI.Vector(Math.random(), Math.random()).multiplyScalar(50).add(new PIXI.Vector(10,10));
    this.position = position.clone();
    this.radius = 30;
    this.maxSpeed = maxSpeed + strength;
    this.maxForce = maxForce + strength;
    this.amount = strength * 10 + 10;
    this.count = 0;
    this.flap = Math.random() * 0.5 + 0.5;
  };

  Boid.prototype.run = function(boids) {
    if (!groupTogether) {
      this.flock(boids);
    } else {
      this.align(boids);
    }
    this.update();
  };

  // We accumulate a new acceleration each time based on several rules
  Boid.prototype.flock = function(boids) {
    var separation = this.separate(boids).multiplyScalar(1);
    var alignment = this.align(boids).multiplyScalar(8);
    var cohesion = this.cohesion(boids).multiplyScalar(2);
    this.acceleration.add(separation).add(alignment).add(cohesion);
  };

  Boid.prototype.opticalFlow = function() {
    if (FlockState.boidData && FlockState.boidData.u) {
      var u = FlockState.boidData.u;
      var v = FlockState.boidData.v;
      opticalFlowVector.x -= u;
      opticalFlowVector.y += v;
    }
    return vector;
  };

  Boid.prototype.update = function() {
    // Update velocity
    this.vector.add(this.acceleration);
    // Limit speed
    if (FlockState.speedFactor) {
      speedFactor = FlockState.speedFactor / 1000;
    }
    this.vector.setLength(Math.min(this.maxSpeed, this.vector.length()));
    this.vector.multiplyScalar(speedFactor);

    //Move position based on vector of the boid
    this.position.add(this.vector);
    this.borders();

    // Limit the acceleration each cycle.
    // The closer to 0 this is, the more insect like the behavior
    // with sudden changes in direction
    this.acceleration.multiplyScalar(0.6);
  };

  Boid.prototype.seek = function(target) {
    this.acceleration.add(this.steer(target, false));
  };

  Boid.prototype.arrive = function(target) {
    this.acceleration.add(this.steer(target, true));
  };

  Boid.prototype.borders = function() {

    var vector = new PIXI.Vector(0, 0);
    var position = this.position;
    var radius = this.radius;

    if (position.x < -radius) {
      // vector.x = borderFactor * (-radius - position.x);
      vector.x = size.width + this.radius;
    }
    if (position.y < -radius){
      // vector.y = borderFactor * (-radius - position.y);
      vector.y = size.height + this.radius;
    }
    if (position.x > size.width + radius){
      // vector.x = -borderFactor * (position.x - size.width - radius);
      vector.x = -size.width - this.radius;
    }
    if (position.y > size.height + radius) {
      // vector.y = -borderFactor * (position.y - size.height - radius);
      vector.y = -size.height - this.radius;
    }
    this.position.add(vector);
    // return vector;
  };

  // A method that calculates a steering vector towards a target
  // Takes a second argument, if true, it slows down as it approaches
  // the target
  Boid.prototype.steer = function(target, slowdown) {
    var steer;
    var desired = target.clone().sub(this.position);
    var distance = desired.length();
    // Two options for desired vector magnitude
    // (1 -- based on distance, 2 -- maxSpeed)
    if (slowdown && distance < 20) {
      // This damping is somewhat arbitrary:
      desired.setLength(this.maxSpeed * (1 / distance));
    } else {
      // desired.setLength(this.maxSpeed);
    }
    steer = desired.clone().sub(this.vector);
    steer.setLength(Math.min(this.maxForce, steer.length()));

    return steer;
  };

  Boid.prototype.separate = function(boids) {
    var desiredSeperation = Math.pow(100, 2);
    var steer = new PIXI.Vector(0, 0);
    var count = 0;
    // For every boid in the system, check if it's too close
    for (var i = 0, l = boids.length; i < l; i++) {
      var other = boids[i];
      // since this. and other. poisition are PIXI.Points, need to create a new Vector out of that point
      var vector = new PIXI.Vector(this.position.clone().sub(other.position));
      var distanceSq = vector.lengthSq();
      if (distanceSq > 0 && distanceSq < desiredSeperation) {
        // Calculate vector pointing away from neighbor
        steer.add(vector.multiplyScalar(1 / (distanceSq * distanceSq)));
        count++;
      }
    }
    // Average -- divide by how many
    if (count > 0)
      steer.divideScalar(count);
    if (steer.length() !== 0) {
      // Implement Reynolds: Steering = Desired - Velocity
      steer.setLength(this.maxSpeed);
      steer.sub(this.vector);
      steer.setLength(Math.min(steer.length(), this.maxForce));
    }
    return steer;
  };

  // Alignment
  // For every nearby boid in the system, calculate the average velocity
  Boid.prototype.align = function(boids) {
    // Using square of distance to ease calculations
    var neighborDist = Math.pow(250, 2);
    var steer = new PIXI.Vector(0, 0);
    var count = 0;
    for (var i = 0, l = boids.length; i < l; i++) {
      var other = boids[i];
      // We just need to find the square of the distance — less calculation
      var distanceSq = this.position.distanceToSq(other.position);
      // debugger;
      if (distanceSq > 0 && distanceSq < neighborDist) {
        steer.add(other.vector);
        count++;
      }
    }

    if (count > 0)
      steer.divideScalar(count);
    if (! (steer.length() === 0)) {
      // Implement Reynolds: Steering = Desired - Velocity
      steer.setLength(this.maxSpeed);
      steer.sub(this.vector);
      steer.setLength(Math.min(steer.length(), this.maxForce));
    }
    return steer;
  };

  // Cohesion
  // For the average location (i.e. center) of all nearby boids,
  // calculate steering vector towards that location
  Boid.prototype.cohesion = function(boids) {
    // Using square of distance to ease calculations
    var neighborDist = Math.pow(600, 2);
    var sum = new PIXI.Vector(0, 0);
    var count = 0;
    for (var i = 0, l = boids.length; i < l; i++) {
      var other = boids[i];
      var distanceSq = this.position.distanceToSq(other.position);
      if (distanceSq > 0 && distanceSq < neighborDist) {
        sum.add(other.position); // Add location
        count++;
      }
    }
    if (count > 0) {
      sum.divideScalar(count);
      // Steer towards the location
      return this.steer(sum, false);
    }
    return sum;
  };

  //Main loop -
  init();

  function init() {
    var boidContainers = [];

    // Add the boids:
    for (var i = 0; i < 200; i++) {
      var position = new PIXI.Point(Math.random() * size.width, Math.random() * size.height);
      var boid = new Boid(position, 2, 1);
      var boidContainer = new PIXI.DisplayObjectContainer();
      var boidGraphic = new PIXI.Graphics();
      boidGraphic.beginFill(0x000000);
      boidGraphic.drawCircle(0, 0, 5);
      boidGraphic.lineTo(3.5,0);
      boidGraphic.endFill();

      boidContainer.addChild(boidGraphic);
      // boidContainer.alpha = 0.75 + boid.vector.length() / boid.maxSpeed;

      boid.container = boidContainer;
      boidContainers.push(boidContainer);

      boids.push(boid);

      _target.addChild(boidContainer);
      _stage.addChild(boidContainer);
    }
  _stage.setInteractive(true);
  _stage.mousedown = _stage.touchstart = onMouseDown;
  }

  function onMouseDown() {
    groupTogether = !groupTogether;
    console.log('mousedown!');
  }

  function animate() {
    if (FlockState = {} && window.FlockState !== undefined) {
      FlockState = window.FlockState;
    }

    requestAnimFrame(animate);

    count += 1;
    _renderer.render(_stage);

    for (var i = 0, l = boids.length; i < l; i++) {
      var boid = boids[i];

      if (groupTogether) {
        var index = parseInt( ((i + boid.count / 3) % l) / l * path.length);
        var point = path[index];
        boid.seek(point);
      }
      boid.container.position = boid.position;
      boid.vector.normalize();

      boid.count += (1 + boid.flap);
      // boid.container.alpha = 1.1 - (1 / (boid.vector.lengthSq() + .5)) ;
      boid.container.rotation = -boid.vector.rad();

      var flapFactor = boid.count * boid.vector.lengthSq() * 0.2;
      boid.container.scale = new PIXI.Point(Math.sin(flapFactor)*.25 + 0.85, 0.4);

      boid.run(boids);
    }
  }
});
<commit_msg>Edited some parameters in flock-animation.<commit_after>jQuery(function($) {
    var init = function() {
      var boidContainers = [];

      // Add the boids:
      for (var i = 0; i < 150; i++) {
        var position = new PIXI.Point(Math.random() * size.width, Math.random() * size.height);
        var boid = new Boid(position, 2, 1);
        var boidContainer = new PIXI.DisplayObjectContainer();
        var boidGraphic = new PIXI.Graphics();
        boidGraphic.beginFill(0x000000);
        boidGraphic.drawCircle(0, 0, 5);
        boidGraphic.lineTo(3.5,0);
        boidGraphic.endFill();

        boidContainer.addChild(boidGraphic);
        // boidContainer.alpha = 0.75 + boid.vector.length() / boid.maxSpeed;

        boid.container = boidContainer;
        boidContainers.push(boidContainer);

        boids.push(boid);

        _target.addChild(boidContainer);
        _stage.addChild(boidContainer);
      }
    _stage.setInteractive(true);
    _stage.mousedown = _stage.touchstart = onMouseDown;

    window.onresize = onResize;
  }

  var onMouseDown = function() {
    groupTogether = !groupTogether;
    console.log('mousedown!');
  }

  var onResize = function(event) {
    size = {
      width: window.innerWidth,
      height: window.innerHeight
    };
    _renderer.view.style.width = window.innerWidth + 'px';
    _renderer.view.style.height = window.innerHeight + 'px';
    _renderer.resize(window.innerWidth, window.innerHeight);
  }

  var animate = function() {
    if (FlockState = {} && window.FlockState !== undefined) {
      FlockState = window.FlockState;
    }

    requestAnimFrame(animate);

    count += 1;
    _renderer.render(_stage);

    for (var i = 0, l = boids.length; i < l; i++) {
      var boid = boids[i];

      if (groupTogether) {
        var index = parseInt( ((i + boid.count / 4.5) % l) / l * path.length);
        var point = path[index];
        boid.seek(point);
      }
      boid.container.position = boid.position;
      boid.vector.normalize();

      boid.count += (1 + boid.flap);
      // boid.container.alpha = 1.1 - (1 / (boid.vector.lengthSq() + .5)) ;
      boid.container.rotation = -boid.vector.rad();

      var flapFactor = boid.count * boid.vector.lengthSq() * 0.2;
      boid.container.scale = new PIXI.Point(Math.sin(flapFactor)*.25 + 0.95, 0.35);

      boid.run(boids);
    }
  }

  var FlockState = window.FlockState || {};

  var size = {
    width: window.innerWidth,
    height: window.innerHeight
  };

  // Initialize some variables
  var boids = [];
  var groupTogether = false;
  var opticalFlowVector = new PIXI.Vector(0, 0);
  var path = [];
  var speedFactor = 1;

  // create an new instance of a pixi _stage - and set it to be interactive
  var _stage = new PIXI.Stage(0xffffff);
  _stage.setInteractive(true);

  // create a _renderer instance
  var _renderer = PIXI.autoDetectRenderer(size.width, size.height);

  _renderer.view.style.width = size.width + "px";
  _renderer.view.style.height = size.height + "px";

  _renderer.view.style.display = "block";

  var renderTexture = new PIXI.RenderTexture(size.width, size.height);

  var _target = new PIXI.DisplayObjectContainer();
  _stage.addChild(_target);

  // add render view to DOM
  document.body.appendChild(_renderer.view);

  var count = 0;

  // Create a path. This is for testing. Ideally we should detect an outline with an IR camera and using that data for the path.
  var steps = 90;
  for (var i = 0; i < steps; i++) {
    path.push(new PIXI.Vector(
      (size.width / 2) + 300 * Math.cos(2 * Math.PI * i / steps),
      (size.height / 2) + 300 * Math.sin(2 * Math.PI * i / steps)
     ));
  }

  var Boid = function(position, maxSpeed, maxForce) {
    var strength = Math.random() + 1.5;
    this.acceleration = new PIXI.Vector();
    this.vector = new PIXI.Vector(Math.random(), Math.random()).multiplyScalar(50).add(new PIXI.Vector(10,10));
    this.position = position.clone();
    this.radius = 30;
    this.maxSpeed = maxSpeed + strength;
    this.maxForce = maxForce + strength;
    this.amount = strength * 10 + 10;
    this.count = 0;
    this.flap = Math.random() * 0.5 + 0.5;
  };

  Boid.prototype.run = function(boids) {
    if (!groupTogether) {
      this.flock(boids);
    } else {
      this.align(boids);
    }
    this.update();
  };

  // We accumulate a new acceleration each time based on several rules
  Boid.prototype.flock = function(boids) {
    var separation = this.separate(boids).multiplyScalar(1);
    var alignment = this.align(boids).multiplyScalar(8);
    var cohesion = this.cohesion(boids).multiplyScalar(1);
    this.acceleration.add(separation).add(alignment).add(cohesion);
  };

  Boid.prototype.opticalFlow = function() {
    if (FlockState.boidData && FlockState.boidData.u) {
      var u = FlockState.boidData.u;
      var v = FlockState.boidData.v;
      opticalFlowVector.x -= u;
      opticalFlowVector.y += v;
    }
    return vector;
  };

  Boid.prototype.update = function() {
    // Update velocity
    this.vector.add(this.acceleration);
    // Limit speed
    if (FlockState.speedFactor) {
      speedFactor = FlockState.speedFactor / 1000;
    }
    this.vector.setLength(Math.min(this.maxSpeed, this.vector.length()));
    this.vector.multiplyScalar(speedFactor);

    //Move position based on vector of the boid
    this.position.add(this.vector);
    this.borders();

    // Limit the acceleration each cycle.
    // The closer to 0 this is, the more insect like the behavior
    // with sudden changes in direction
    this.acceleration.multiplyScalar(0.6);
  };

  Boid.prototype.seek = function(target) {
    this.acceleration.add(this.steer(target, false));
  };

  Boid.prototype.arrive = function(target) {
    this.acceleration.add(this.steer(target, true));
  };

  Boid.prototype.borders = function() {

    var vector = new PIXI.Vector(0, 0);
    var position = this.position;
    var radius = this.radius;

    if (position.x < -radius) {
      // vector.x = borderFactor * (-radius - position.x);
      vector.x = size.width + this.radius;
    }
    if (position.y < -radius){
      // vector.y = borderFactor * (-radius - position.y);
      vector.y = size.height + this.radius;
    }
    if (position.x > size.width + radius){
      // vector.x = -borderFactor * (position.x - size.width - radius);
      vector.x = -size.width - this.radius;
    }
    if (position.y > size.height + radius) {
      // vector.y = -borderFactor * (position.y - size.height - radius);
      vector.y = -size.height - this.radius;
    }
    this.position.add(vector);
    // return vector;
  };

  // A method that calculates a steering vector towards a target
  // Takes a second argument, if true, it slows down as it approaches
  // the target
  Boid.prototype.steer = function(target, slowdown) {
    var steer;
    var desired = target.clone().sub(this.position);
    var distance = desired.length();
    // Two options for desired vector magnitude
    // (1 -- based on distance, 2 -- maxSpeed)
    if (slowdown && distance < 20) {
      // This damping is somewhat arbitrary:
      desired.setLength(this.maxSpeed * (1 / distance));
    } else {
      // desired.setLength(this.maxSpeed);
    }
    steer = desired.clone().sub(this.vector);
    steer.setLength(Math.min(this.maxForce, steer.length()));

    return steer;
  };

  Boid.prototype.separate = function(boids) {
    var desiredSeperation = Math.pow(100, 2);
    var steer = new PIXI.Vector(0, 0);
    var count = 0;
    // For every boid in the system, check if it's too close
    for (var i = 0, l = boids.length; i < l; i++) {
      var other = boids[i];
      // since this. and other. poisition are PIXI.Points, need to create a new Vector out of that point
      var vector = new PIXI.Vector(this.position.clone().sub(other.position));
      var distanceSq = vector.lengthSq();
      if (distanceSq > 0 && distanceSq < desiredSeperation) {
        // Calculate vector pointing away from neighbor
        steer.add(vector.multiplyScalar(1 / (distanceSq * distanceSq)));
        count++;
      }
    }
    // Average -- divide by how many
    if (count > 0)
      steer.divideScalar(count);
    if (steer.length() !== 0) {
      // Implement Reynolds: Steering = Desired - Velocity
      steer.setLength(this.maxSpeed);
      steer.sub(this.vector);
      steer.setLength(Math.min(steer.length(), this.maxForce));
    }
    return steer;
  };

  // Alignment
  // For every nearby boid in the system, calculate the average velocity
  Boid.prototype.align = function(boids) {
    // Using square of distance to ease calculations
    var neighborDist = Math.pow(250, 2);
    var steer = new PIXI.Vector(0, 0);
    var count = 0;
    for (var i = 0, l = boids.length; i < l; i++) {
      var other = boids[i];
      // We just need to find the square of the distance — less calculation
      var distanceSq = this.position.distanceToSq(other.position);
      // debugger;
      if (distanceSq > 0 && distanceSq < neighborDist) {
        steer.add(other.vector);
        count++;
      }
    }

    if (count > 0)
      steer.divideScalar(count);
    if (! (steer.length() === 0)) {
      // Implement Reynolds: Steering = Desired - Velocity
      steer.setLength(this.maxSpeed);
      steer.sub(this.vector);
      steer.setLength(Math.min(steer.length(), this.maxForce));
    }
    return steer;
  };

  // Cohesion
  // For the average location (i.e. center) of all nearby boids,
  // calculate steering vector towards that location
  Boid.prototype.cohesion = function(boids) {
    // Using square of distance to ease calculations
    var neighborDist = Math.pow(600, 2);
    var sum = new PIXI.Vector(0, 0);
    var count = 0;
    for (var i = 0, l = boids.length; i < l; i++) {
      var other = boids[i];
      var distanceSq = this.position.distanceToSq(other.position);
      if (distanceSq > 0 && distanceSq < neighborDist) {
        sum.add(other.position); // Add location
        count++;
      }
    }
    if (count > 0) {
      sum.divideScalar(count);
      // Steer towards the location
      return this.steer(sum, false);
    }
    return sum;
  };

  //Main loop -
  init();
  requestAnimFrame(animate);

});
<|endoftext|>


<commit_before>
// limbus-buildgen - A "build anywhere" C/C++ makefile/project generator.
// Written in 2014-2016 by Jesper Oskarsson jesosk@gmail.com
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain worldwide.
// This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

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

describe('Linking', function () {
    beforeEach(function () {
        return util.beforeEach().then(function () {
            return shell.mkdir('temp/include');
        }).then(function () {
            return shell.copyFiles([
                'linked.c',
                'linked_dynamic.c',
                'source/mylibrary.c',
                'include/mylibrary.h',
                'source/mydynamiclibrary.c',
                'include/mydynamiclibrary.h',
                'math.c',
            ], 'features/linking/', 'temp/');
        });
    });

    afterEach(function () {
        return util.afterEach();
    });

    it('should compile and link correctly given several source files and includes', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: util.host,
                files: [
                    'linked.c',
                    'source/mylibrary.c'
                ],
                includePaths: [
                    'include'
                ],
                outputName: 'linked'
            },
            command: 'linked',
            expectOutputToMatch: /42/
        });
    });

    it('should pass linker flags as is', function () {
        var failFlags = {
            'application': {
                'cl': '/link /NODEFAULTLIB',
                'clang': '-nostdlib',
                'gcc': '-nostdlib'
            },
            'static-library': {
                'cl': '/SUBSYSTEM:BOOT_APPLICATIO',
                'clang': 'q',
                'gcc': 'q'
            },
            'dynamic-library': {
                'cl': '/NODEFAULTLIB',
                'clang': '-nostdlib',
                'gcc': '-nostdlib'
            }
        };
        var succeedFlags = {
            'application': {
                'cl': '/link /VERSION:1.0',
                'clang': '-s',
                'gcc': '-s'
            },
            'static-library': {
                'cl': '/WX:NO',
                'clang': 'v',
                'gcc': 'v'
            },
            'dynamic-library': {
                'cl': '/VERSION:1.0',
                'clang': '-s',
                'gcc': '-s'
            }
        };

        var linkerFlagsShouldFailForType = function(type, flags) {
            return util.buildSimple({
                type: type,
                host: util.host,
                files: ['simple.c'],
                outputName: 'app',
                linkerFlags: failFlags[type][util.hostCompiler]
            }).then(function () {
                return Promise.reject(new Error(type + ' did not fail'));
            }, function () {
                return Promise.resolve();
            });
        };
        var linkerFlagsShouldSucceedForType = function(type, flags) {
            return util.buildSimple({
                type: type,
                host: util.host,
                files: ['simple.c'],
                outputName: 'app',
                linkerFlags: succeedFlags[type][util.hostCompiler]
            });
        };

        return Promise.resolve().then(function () {
            return linkerFlagsShouldSucceedForType('application');
        }).then(function () {
            return linkerFlagsShouldSucceedForType('static-library');
        }).then(function () {
            return linkerFlagsShouldSucceedForType('dynamic-library');
        }).then(function () {
            return linkerFlagsShouldFailForType('application');
        }).then(function () {
            return linkerFlagsShouldFailForType('static-library');
        }).then(function () {
            return linkerFlagsShouldFailForType('dynamic-library');
        });
    });

    it('should link with libm by default', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: util.host,
                files: [
                    'math.c'
                ],
                outputName: 'math'
            },
            command: 'math',
            expectOutputToMatch: /42/
        });
    });

    it('should compile to an executable with outputName', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: util.host,
                files: [
                    'simple.c'
                ],
                outputName: 'my_executable'
            },
            command: 'my_executable',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a static library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: util.host,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'application',
                    host: util.host,
                    files: [
                        'linked.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a dynamic library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: util.host,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'dynamic-library',
                    host: util.host,
                    files: [
                        'source/mydynamiclibrary.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    outputName: 'my_dyn_lib_name'
                },
                {
                    type: 'application',
                    host: util.host,
                    files: [
                        'linked_dynamic.c'
                    ],
                    libraries: [
                        'my_dyn_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    // On linux systems the shared object won't be looked for in
                    // the current working directory by default. We just add a
                    // flag so that it is.
                    linkerFlags: (process.platform === 'linux') ? '-Wl,-rpath=.' : '',
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });
});
<commit_msg>Another attempt at fixing linking<commit_after>
// limbus-buildgen - A "build anywhere" C/C++ makefile/project generator.
// Written in 2014-2016 by Jesper Oskarsson jesosk@gmail.com
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain worldwide.
// This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

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

describe('Linking', function () {
    beforeEach(function () {
        return util.beforeEach().then(function () {
            return shell.mkdir('temp/include');
        }).then(function () {
            return shell.copyFiles([
                'linked.c',
                'linked_dynamic.c',
                'source/mylibrary.c',
                'include/mylibrary.h',
                'source/mydynamiclibrary.c',
                'include/mydynamiclibrary.h',
                'math.c',
            ], 'features/linking/', 'temp/');
        });
    });

    afterEach(function () {
        return util.afterEach();
    });

    it('should compile and link correctly given several source files and includes', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: util.host,
                files: [
                    'linked.c',
                    'source/mylibrary.c'
                ],
                includePaths: [
                    'include'
                ],
                outputName: 'linked'
            },
            command: 'linked',
            expectOutputToMatch: /42/
        });
    });

    it('should pass linker flags as is', function () {
        var failFlags = {
            'application': {
                'cl': '/link /NODEFAULTLIB',
                'clang': '-nostdlib',
                'gcc': '-nostdlib'
            },
            'static-library': {
                'cl': '/SUBSYSTEM:BOOT_APPLICATIO',
                'clang': 'q',
                'gcc': 'q'
            },
            'dynamic-library': {
                'cl': '/NODEFAULTLIB',
                'clang': '-nostdlib',
                'gcc': '-o'
            }
        };
        var succeedFlags = {
            'application': {
                'cl': '/link /VERSION:1.0',
                'clang': '-s',
                'gcc': '-s'
            },
            'static-library': {
                'cl': '/WX:NO',
                'clang': 'v',
                'gcc': 'v'
            },
            'dynamic-library': {
                'cl': '/VERSION:1.0',
                'clang': '-s',
                'gcc': '-s'
            }
        };

        var linkerFlagsShouldFailForType = function(type, flags) {
            return util.buildSimple({
                type: type,
                host: util.host,
                files: ['simple.c'],
                outputName: 'app',
                linkerFlags: failFlags[type][util.hostCompiler]
            }).then(function () {
                return Promise.reject(new Error(type + ' did not fail'));
            }, function () {
                return Promise.resolve();
            });
        };
        var linkerFlagsShouldSucceedForType = function(type, flags) {
            return util.buildSimple({
                type: type,
                host: util.host,
                files: ['simple.c'],
                outputName: 'app',
                linkerFlags: succeedFlags[type][util.hostCompiler]
            });
        };

        return Promise.resolve().then(function () {
            return linkerFlagsShouldSucceedForType('application');
        }).then(function () {
            return linkerFlagsShouldSucceedForType('static-library');
        }).then(function () {
            return linkerFlagsShouldSucceedForType('dynamic-library');
        }).then(function () {
            return linkerFlagsShouldFailForType('application');
        }).then(function () {
            return linkerFlagsShouldFailForType('static-library');
        }).then(function () {
            return linkerFlagsShouldFailForType('dynamic-library');
        });
    });

    it('should link with libm by default', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: util.host,
                files: [
                    'math.c'
                ],
                outputName: 'math'
            },
            command: 'math',
            expectOutputToMatch: /42/
        });
    });

    it('should compile to an executable with outputName', function () {
        return util.generateCompileAndRun({
            config: {
                type: 'application',
                host: util.host,
                files: [
                    'simple.c'
                ],
                outputName: 'my_executable'
            },
            command: 'my_executable',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a static library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: util.host,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'application',
                    host: util.host,
                    files: [
                        'linked.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });

    it('should compile a dynamic library and then be able to link to it', function () {
        return util.generateCompileAndRun({
            config: [
                {
                    type: 'static-library',
                    host: util.host,
                    files: [
                        'source/mylibrary.c'
                    ],
                    outputName: 'my_lib_name'
                },
                {
                    type: 'dynamic-library',
                    host: util.host,
                    files: [
                        'source/mydynamiclibrary.c'
                    ],
                    libraries: [
                        'my_lib_name'
                    ],
                    outputName: 'my_dyn_lib_name'
                },
                {
                    type: 'application',
                    host: util.host,
                    files: [
                        'linked_dynamic.c'
                    ],
                    libraries: [
                        'my_dyn_lib_name'
                    ],
                    includePaths: [
                        'include'
                    ],
                    // On linux systems the shared object won't be looked for in
                    // the current working directory by default. We just add a
                    // flag so that it is.
                    linkerFlags: (process.platform === 'linux') ? '-Wl,-rpath=.' : '',
                    outputName: 'linked_with_library'
                }
            ],
            command: 'linked_with_library',
            expectOutputToMatch: /42/
        });
    });
});
<|endoftext|>