<commit_before>'use strict';

kiwiWeb.config(function ($stateProvider, $urlRouterProvider) {

  // Routing Configuration

  $urlRouterProvider.otherwise('/home');

  $stateProvider
  .state('home', {
    url: '/home',
    templateUrl: 'app/home/home.tpl.html',
    controller: 'HomeCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/home/home.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('products', {
    url: '/products',
    templateUrl: 'app/products/products.tpl.html',
    controller: 'ProductsCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/products.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('residential', {
    url: '/residential',
    templateUrl: 'app/products/residential/residential.tpl.html',
    controller: 'ResidentialCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/residential/residential.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('business', {
    url: '/business',
    templateUrl: 'app/products/business/business.tpl.html',
    controller: 'BusinessCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/business/business.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('dedicated', {
    url: '/dedicated',
    templateUrl: 'app/products/dedicated/dedicated.tpl.html',
    controller: 'DedicatedCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/dedicated/dedicated.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('metromesh', {
    url: '/metromesh',
    templateUrl: 'app/products/metromesh/metromesh.tpl.html',
    controller: 'MetroMeshCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/metromesh/metromesh.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('faq', {
    url: '/faq/:section',
    templateUrl: 'app/products/faq/faq.tpl.html',
    controller: 'FaqCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/faq/faq.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('sales', {
    url: '/sales/:product',
    templateUrl: 'app/products/sales/sales.tpl.html',
    controller: 'SalesCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/sales/sales.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      },
      states: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/sales/states.json'
        })
        .then(function(states) {
          return states;
        });
      }
    }
  })
  .state('about', {
    url: '/about',
    templateUrl: 'app/company/about/about.tpl.html',
    controller: 'AboutCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/about/about.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('concesion', {
    url: '/concesion',
    templateUrl: 'app/company/concesion/concesion.tpl.html',
    controller: 'ConcesionCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/concesion/concesion.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('careers', {
    url: '/careers',
    templateUrl: 'app/company/careers/careers.tpl.html',
    controller: 'CareersCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/careers/careers.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('apply', {
    url: '/apply',
    templateUrl: 'app/company/apply/apply.tpl.html',
    controller: 'ApplyCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/apply/apply.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('stories', {
    url: '/stories',
    templateUrl: 'app/company/stories/stories.tpl.html',
    controller: 'StoriesCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/stories/stories.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('privacy', {
    url: '/privacy',
    templateUrl: 'app/company/privacy/privacy.tpl.html',
    controller: 'PrivacyCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/privacy/privacy.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('contact', {
    url: '/contact',
    templateUrl: 'app/contact/contact.tpl.html',
    controller: 'ContactCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/contact/contact.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('dashboard', {
    abstract: true,
    url: '/dashboard',
    templateUrl: 'app/customer/dashboard/dashboard.tpl.html',
    controller: 'DashboardCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/customer/dashboard/dashboard.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('dashboard.anon', {
    url: '/anon',
    views: {
      'signUp' : {
        templateUrl: 'app/customer/signUp/signUp.tpl.html',
        controller: 'SignUpCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signUp/signUp.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      },
      'signIn' : {
        templateUrl: 'app/customer/signIn/signIn.tpl.html',
        controller: 'SignInCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signIn/signIn.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      }
    }
  })
  .state('pay', {
    url: '/pay',
    templateUrl: 'app/customer/pay/pay.tpl.html',
    controller: 'PayCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/customer/pay/pay.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('refer', {
    abstract: true,
    url: '/refer',
    templateUrl: 'app/customer/refer/refer.tpl.html',
    controller: 'ReferCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/customer/refer/refer.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('refer.anon', {
    url: '/anon',
    views: {
      'signUp' : {
        templateUrl: 'app/customer/signUp/signUp.tpl.html',
        controller: 'SignUpCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signUp/signUp.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      },
      'signIn' : {
        templateUrl: 'app/customer/signIn/signIn.tpl.html',
        controller: 'SignInCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signIn/signIn.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      }
    }
  })
  .state('support', {
    url: '/support',
    templateUrl: 'app/support/support.tpl.html',
    controller: 'SupportCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/support/support.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('status', {
    url: '/status',
    templateUrl: 'app/support/status/status.tpl.html',
    controller: 'StatusCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/support/status/status.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  });
});
<commit_msg>Fixes states.json route.<commit_after>'use strict';

kiwiWeb.config(function ($stateProvider, $urlRouterProvider) {

  // Routing Configuration

  $urlRouterProvider.otherwise('/home');

  $stateProvider
  .state('home', {
    url: '/home',
    templateUrl: 'app/home/home.tpl.html',
    controller: 'HomeCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/home/home.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('products', {
    url: '/products',
    templateUrl: 'app/products/products.tpl.html',
    controller: 'ProductsCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/products.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('residential', {
    url: '/residential',
    templateUrl: 'app/products/residential/residential.tpl.html',
    controller: 'ResidentialCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/residential/residential.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('business', {
    url: '/business',
    templateUrl: 'app/products/business/business.tpl.html',
    controller: 'BusinessCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/business/business.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('dedicated', {
    url: '/dedicated',
    templateUrl: 'app/products/dedicated/dedicated.tpl.html',
    controller: 'DedicatedCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/dedicated/dedicated.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('metromesh', {
    url: '/metromesh',
    templateUrl: 'app/products/metromesh/metromesh.tpl.html',
    controller: 'MetroMeshCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/metromesh/metromesh.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('faq', {
    url: '/faq/:section',
    templateUrl: 'app/products/faq/faq.tpl.html',
    controller: 'FaqCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/faq/faq.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('sales', {
    url: '/sales/:product',
    templateUrl: 'app/products/sales/sales.tpl.html',
    controller: 'SalesCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/products/sales/sales.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      },
      states: function($http) {
        return $http({
          method: 'GET',
          url: 'app/common/json/mx/states.json'
        })
        .then(function(states) {
          return states;
        });
      }
    }
  })
  .state('about', {
    url: '/about',
    templateUrl: 'app/company/about/about.tpl.html',
    controller: 'AboutCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/about/about.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('concesion', {
    url: '/concesion',
    templateUrl: 'app/company/concesion/concesion.tpl.html',
    controller: 'ConcesionCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/concesion/concesion.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('careers', {
    url: '/careers',
    templateUrl: 'app/company/careers/careers.tpl.html',
    controller: 'CareersCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/careers/careers.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('apply', {
    url: '/apply',
    templateUrl: 'app/company/apply/apply.tpl.html',
    controller: 'ApplyCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/apply/apply.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('stories', {
    url: '/stories',
    templateUrl: 'app/company/stories/stories.tpl.html',
    controller: 'StoriesCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/stories/stories.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('privacy', {
    url: '/privacy',
    templateUrl: 'app/company/privacy/privacy.tpl.html',
    controller: 'PrivacyCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/company/privacy/privacy.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('contact', {
    url: '/contact',
    templateUrl: 'app/contact/contact.tpl.html',
    controller: 'ContactCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/contact/contact.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('dashboard', {
    abstract: true,
    url: '/dashboard',
    templateUrl: 'app/customer/dashboard/dashboard.tpl.html',
    controller: 'DashboardCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/customer/dashboard/dashboard.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('dashboard.anon', {
    url: '/anon',
    views: {
      'signUp' : {
        templateUrl: 'app/customer/signUp/signUp.tpl.html',
        controller: 'SignUpCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signUp/signUp.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      },
      'signIn' : {
        templateUrl: 'app/customer/signIn/signIn.tpl.html',
        controller: 'SignInCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signIn/signIn.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      }
    }
  })
  .state('pay', {
    url: '/pay',
    templateUrl: 'app/customer/pay/pay.tpl.html',
    controller: 'PayCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/customer/pay/pay.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('refer', {
    abstract: true,
    url: '/refer',
    templateUrl: 'app/customer/refer/refer.tpl.html',
    controller: 'ReferCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/customer/refer/refer.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('refer.anon', {
    url: '/anon',
    views: {
      'signUp' : {
        templateUrl: 'app/customer/signUp/signUp.tpl.html',
        controller: 'SignUpCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signUp/signUp.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      },
      'signIn' : {
        templateUrl: 'app/customer/signIn/signIn.tpl.html',
        controller: 'SignInCtrl',
        resolve: {
          lang: function($http) {
            return $http({
              method: 'GET',
              url: 'app/customer/signIn/signIn.lang.es.json'
            })
            .then(function(data) {
              return data;
            });
          }
        }
      }
    }
  })
  .state('support', {
    url: '/support',
    templateUrl: 'app/support/support.tpl.html',
    controller: 'SupportCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/support/support.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  })
  .state('status', {
    url: '/status',
    templateUrl: 'app/support/status/status.tpl.html',
    controller: 'StatusCtrl',
    resolve: {
      lang: function($http) {
        return $http({
          method: 'GET',
          url: 'app/support/status/status.lang.es.json'
        })
        .then(function(data) {
          return data;
        });
      }
    }
  });
});
<|endoftext|>


<commit_before>var Application = function ()
{
	this.times = [];
	this.currentTimeIndex = -1;
	this.totalTimes = [];
	this.totalLast7Days = 0;
	this.workStoppedSymbol = "-";
	this.roundToMinutes = 30;
	this.is24HourClock = false;

	this.init = function ()
	{
		var self = this;

		self.loadData();
		self.setupEventHandling();
	};

	this.loadData = function ()
	{
		var self = this,
			time = null,
			previousTime = null,
			timesList = "",
			timeStampString = "";

		if("undefined" !== typeof localStorage.times && null !== localStorage.times)
		{
			self.times = JSON.parse(localStorage.times);
			console.log("Times:", self.times);
		}

		for(var i = 0, timesLength = self.times.length; i < timesLength; i++)
		{
			time = self.times[i];

			if(typeof time.id === "undefined")
			{
				time.id = i;
			}
			time.TimeStamp = new Date(time.TimeStamp);
			timeStampString = get12HourTime(time.TimeStamp);

			if(previousTime === null)
			{
				previousTime = time;
			}

			if(previousTime.TimeStamp.getDate() !== time.TimeStamp.getDate())
			{
				timesList += "
" + (time.TimeStamp.getMonth() + 1) + "/" + time.TimeStamp.getDate() + "/" + time.TimeStamp.getFullYear() + "
";
			}

			timesList += "
" + timeStampString + " " + time.Name + "
";

			previousTime = time;
		}

		$("div.left-pane").find("ul").append($(timesList));

		self.calculateTotals();
	};

	var get12HourTime = function (dateTime)
	{
		var hours = dateTime.getHours(),
			isAm = true;

		if (hours > 12) {
    		hours -= 12;
    		isAm = false;
		} else if (hours === 0) {
   			hours = 12;
   			isAm = false;
		}

		return (hours + ":" + ("0" + dateTime.getMinutes()).slice(-2) + " " + (isAm === true ? "AM" : "PM"));
	};

	this.setupEventHandling = function ()
	{
		var self = this;

		$("div.input").find("button").off("click");

		$("div.input").find("button").on("click", function ()
		{
			if($.trim($("div.input").find("div").eq(0).text()) !== "")
			{
				var newId = (self.times.length === 0 ? 0 : self.times[self.times.length - 1].id + 1),
					time = {
						"Name": $.trim($("div.input").find("div").eq(0).text()),
						"TimeStamp": new Date(),
						"id": newId
					};

				self.times.push(time);

				timeStampString = get12HourTime(time.TimeStamp);

				$("div.left-pane").find("ul").append($("
" + timeStampString + " " + time.Name + "
"));

				self.saveTimes();

				$("div.input").find("div").html("");

				self.calculateTotals();

				$(".overflow").animate({ scrollTop: $('.overflow')[0].scrollHeight}, 1000);

				self.setupEventHandling();
			}
		});

		$("div.input").find("div").off("keyup");

		$("div.input").find("div").on("keyup", function (event)
		{
			if(event.keyCode === 13)
			{
				$("div.input").find("button").trigger("click");
			}
			else if(event.keyCode === 38)
			{
				if(self.currentTimeIndex === -1)
				{
					self.currentTimeIndex = self.times.length;
				}

				if(self.currentTimeIndex !== 0)
				{
					self.currentTimeIndex--;
				}

				$(this).text(self.times[self.currentTimeIndex].Name);
			}
			else if(event.keyCode === 40)
			{
				if(self.currentTimeIndex === -1)
				{
					self.currentTimeIndex = self.times.length;
				}

				if(self.currentTimeIndex >= self.times.length - 1)
				{
					$(this).text("");
				}
				else
				{
					self.currentTimeIndex++;

					$(this).text(self.times[self.currentTimeIndex].Name);
				}
			}
		});

		$("li").find("span.timestamp").off("click");

		$("li").find("span.timestamp").on("click", function ()
		{
			$(this).hide();

			$(this).after($("<input type='text' class='timestamp' value='" + $(this).text() + "' />"));
			$(this).closest("li").find("input[type=text]").focus();

			self.setupEventHandling();
		});

		$("input[type=text].timestamp").off("blur");

		$("li").find("input[type=text].timestamp").on("blur", function ()
		{
			if($(this).val().indexOf(":") === -1 || (self.is24HourClock === false
				&& $(this).val().toLowerCase().indexOf(" am") === -1
				&& $(this).val().toLowerCase().indexOf(" pm") === -1))
			{
				console.log("nope, invalid date!");
			}
			else
			{
				self.updateTime(+($(this).closest("li").data("id")), $(this).val());

				$(this).closest("li").find("span.timestamp").text($(this).val());
				$(this).closest("li").find("span.timestamp").show();
				$(this).remove();
			}
		});

		$("a.export-times-to-csv").off("click");

		$("a.export-times-to-csv").on("click", function ()
			{
				console.log(self.times);
				exportToCsv("times.csv", self.times);
			});

		$(".overflow").animate({ scrollTop: $('.overflow')[0].scrollHeight}, 1000);
	};

	this.updateTime = function (id, newTime)
	{
		var self = this,
			time = self.times[self.times.indexOfPropertyValue([
			{
				"prop": "id",
				"value": id
			}
		])];

		var newDateTime = new Date(time.TimeStamp),
			hours = +(newTime.split(":")[0]),
			minutes = +(newTime.split(":")[1].toLowerCase().replace(" pm", "").replace(" am", ""));

		if(newTime.toLowerCase().indexOf("pm") !== -1 && hours !== 12 && self.is24HourClock === true)
		{
			hours += 12;
		}

		newDateTime = newDateTime.setHours(hours, minutes);

		time.TimeStamp = new Date(newDateTime);

		self.saveTimes();
	};

	this.saveTimes = function ()
	{
		var self = this;

		localStorage.times = JSON.stringify(self.times);

		self.calculateTotals();
	};

	this.calculateTotals = function ()
	{
		var self = this,
			thisTime = null,
			nextTime = null,
			timeSpan = 0;

		self.totalTimes = [];
		self.totalLast7Days = 0

		for(var i = 0, timesLength = self.times.length; i < timesLength; i++)
		{
			thisTime = self.times[i];
			timeSpan = 0;
			nextTime = null;

			if(i < timesLength - 1)
			{
				nextTime = self.times[i+1];
			}

			if(nextTime !== null)
			{
				timeSpan = (nextTime.TimeStamp - thisTime.TimeStamp) / 1000 / 60 / 60;

				//timeSpan = timeSpan.toFixed(1);

				timeSpan = +(timeSpan);
			}

			var thisIndex = self.totalTimes.indexOfPropertyValue([
				{
					"prop": "Name",
					"value": thisTime["Name"]
				},
				{
					"prop": "Date",
					"value": (thisTime.TimeStamp.getMonth() + 1) + "/" + thisTime.TimeStamp.getDate() + "/" + thisTime.TimeStamp.getFullYear()
				}
			]);

			if(thisIndex === -1)
			{
				self.totalTimes.push({
					"Name": thisTime.Name,
					"Date": (thisTime.TimeStamp.getMonth() + 1) + "/" + thisTime.TimeStamp.getDate() + "/" + thisTime.TimeStamp.getFullYear(),
					"TimeSpan": timeSpan
				});
			}
			else if(nextTime !== null)
			{
				var totalTime = self.totalTimes[thisIndex];

				totalTime.TimeSpan = +(totalTime.TimeSpan) + timeSpan;
			}

		}

		var totalTimesList = "",
			totalTime = null
			today = new Date(),
			sevenDaysAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7);

		for(var i = 0, totalTimesLength = self.totalTimes.length; i < totalTimesLength; i++)
		{
			totalTime = self.totalTimes[i];

			if(self.roundToMinutes === 30)
			{
				totalTime.TimeSpan = Math.round(totalTime.TimeSpan * 2) / 2;
			}

			totalTimesList += "
" + totalTime.Date + " " + totalTime.Name + " - " + (totalTime.TimeSpan === null ? "In Progress" : totalTime.TimeSpan + (totalTime.TimeSpan === 1 ? " hour" : " hours")) + "
";

			if(new Date(totalTime.Date) > sevenDaysAgo && totalTime.Name !== self.workStoppedSymbol && totalTime.Name !== "")
			{
				self.totalLast7Days += totalTime.TimeSpan;
			}
		}

		$(".last7Days").text(self.totalLast7Days);

		$("div.right-pane").find("ul").html("");
		$("div.right-pane").find("ul").append($(totalTimesList));
		console.log(self.totalTimes);
	};
}

var track = new Application();

track.init();<commit_msg>Fix issue where modifying PM times after noon does not input the proper time<commit_after>var Application = function ()
{
	this.times = [];
	this.currentTimeIndex = -1;
	this.totalTimes = [];
	this.totalLast7Days = 0;
	this.workStoppedSymbol = "-";
	this.roundToMinutes = 30;
	this.is24HourClock = false;

	this.init = function ()
	{
		var self = this;

		self.loadData();
		self.setupEventHandling();
	};

	this.loadData = function ()
	{
		var self = this,
			time = null,
			previousTime = null,
			timesList = "",
			timeStampString = "";

		if("undefined" !== typeof localStorage.times && null !== localStorage.times)
		{
			self.times = JSON.parse(localStorage.times);
			console.log("Times:", self.times);
		}

		for(var i = 0, timesLength = self.times.length; i < timesLength; i++)
		{
			time = self.times[i];

			if(typeof time.id === "undefined")
			{
				time.id = i;
			}
			time.TimeStamp = new Date(time.TimeStamp);
			timeStampString = get12HourTime(time.TimeStamp);

			if(previousTime === null)
			{
				previousTime = time;
			}

			if(previousTime.TimeStamp.getDate() !== time.TimeStamp.getDate())
			{
				timesList += "
" + (time.TimeStamp.getMonth() + 1) + "/" + time.TimeStamp.getDate() + "/" + time.TimeStamp.getFullYear() + "
";
			}

			timesList += "
" + timeStampString + " " + time.Name + "
";

			previousTime = time;
		}

		$("div.left-pane").find("ul").append($(timesList));

		self.calculateTotals();
	};

	var get12HourTime = function (dateTime)
	{
		var hours = dateTime.getHours(),
			isAm = true;

		if (hours > 12) {
    		hours -= 12;
    		isAm = false;
		} else if (hours === 0) {
   			hours = 12;
   			isAm = false;
		}

		return (hours + ":" + ("0" + dateTime.getMinutes()).slice(-2) + " " + (isAm === true ? "AM" : "PM"));
	};

	this.setupEventHandling = function ()
	{
		var self = this;

		$("div.input").find("button").off("click");

		$("div.input").find("button").on("click", function ()
		{
			if($.trim($("div.input").find("div").eq(0).text()) !== "")
			{
				var newId = (self.times.length === 0 ? 0 : self.times[self.times.length - 1].id + 1),
					time = {
						"Name": $.trim($("div.input").find("div").eq(0).text()),
						"TimeStamp": new Date(),
						"id": newId
					};

				self.times.push(time);

				timeStampString = get12HourTime(time.TimeStamp);

				$("div.left-pane").find("ul").append($("
" + timeStampString + " " + time.Name + "
"));

				self.saveTimes();

				$("div.input").find("div").html("");

				self.calculateTotals();

				$(".overflow").animate({ scrollTop: $('.overflow')[0].scrollHeight}, 1000);

				self.setupEventHandling();
			}
		});

		$("div.input").find("div").off("keyup");

		$("div.input").find("div").on("keyup", function (event)
		{
			if(event.keyCode === 13)
			{
				$("div.input").find("button").trigger("click");
			}
			else if(event.keyCode === 38)
			{
				if(self.currentTimeIndex === -1)
				{
					self.currentTimeIndex = self.times.length;
				}

				if(self.currentTimeIndex !== 0)
				{
					self.currentTimeIndex--;
				}

				$(this).text(self.times[self.currentTimeIndex].Name);
			}
			else if(event.keyCode === 40)
			{
				if(self.currentTimeIndex === -1)
				{
					self.currentTimeIndex = self.times.length;
				}

				if(self.currentTimeIndex >= self.times.length - 1)
				{
					$(this).text("");
				}
				else
				{
					self.currentTimeIndex++;

					$(this).text(self.times[self.currentTimeIndex].Name);
				}
			}
		});

		$("li").find("span.timestamp").off("click");

		$("li").find("span.timestamp").on("click", function ()
		{
			$(this).hide();

			$(this).after($("<input type='text' class='timestamp' value='" + $(this).text() + "' />"));
			$(this).closest("li").find("input[type=text]").focus();

			self.setupEventHandling();
		});

		$("input[type=text].timestamp").off("blur");

		$("li").find("input[type=text].timestamp").on("blur", function ()
		{
			if($(this).val().indexOf(":") === -1 || (self.is24HourClock === false
				&& $(this).val().toLowerCase().indexOf(" am") === -1
				&& $(this).val().toLowerCase().indexOf(" pm") === -1))
			{
				console.log("nope, invalid date!");
			}
			else
			{
				self.updateTime(+($(this).closest("li").data("id")), $(this).val());

				$(this).closest("li").find("span.timestamp").text($(this).val());
				$(this).closest("li").find("span.timestamp").show();
				$(this).remove();
			}
		});

		$("a.export-times-to-csv").off("click");

		$("a.export-times-to-csv").on("click", function ()
			{
				console.log(self.times);
				exportToCsv("times.csv", self.times);
			});

		$(".overflow").animate({ scrollTop: $('.overflow')[0].scrollHeight}, 1000);
	};

	this.updateTime = function (id, newTime)
	{
		var self = this,
			time = self.times[self.times.indexOfPropertyValue([
			{
				"prop": "id",
				"value": id
			}
		])];

		var newDateTime = new Date(time.TimeStamp),
			hours = +(newTime.split(":")[0]),
			minutes = +(newTime.split(":")[1].toLowerCase().replace(" pm", "").replace(" am", ""));

		if(newTime.toLowerCase().indexOf("pm") !== -1 && hours !== 12 && self.is24HourClock !== true)
		{
			hours += 12;
		}

		newDateTime = newDateTime.setHours(hours, minutes);

		time.TimeStamp = new Date(newDateTime);

		self.saveTimes();
	};

	this.saveTimes = function ()
	{
		var self = this;

		localStorage.times = JSON.stringify(self.times);

		self.calculateTotals();
	};

	this.calculateTotals = function ()
	{
		var self = this,
			thisTime = null,
			nextTime = null,
			timeSpan = 0;

		self.totalTimes = [];
		self.totalLast7Days = 0

		for(var i = 0, timesLength = self.times.length; i < timesLength; i++)
		{
			thisTime = self.times[i];
			timeSpan = 0;
			nextTime = null;

			if(i < timesLength - 1)
			{
				nextTime = self.times[i+1];
			}

			if(nextTime !== null)
			{
				timeSpan = (nextTime.TimeStamp - thisTime.TimeStamp) / 1000 / 60 / 60;

				//timeSpan = timeSpan.toFixed(1);

				timeSpan = +(timeSpan);
			}

			var thisIndex = self.totalTimes.indexOfPropertyValue([
				{
					"prop": "Name",
					"value": thisTime["Name"]
				},
				{
					"prop": "Date",
					"value": (thisTime.TimeStamp.getMonth() + 1) + "/" + thisTime.TimeStamp.getDate() + "/" + thisTime.TimeStamp.getFullYear()
				}
			]);

			if(thisIndex === -1)
			{
				self.totalTimes.push({
					"Name": thisTime.Name,
					"Date": (thisTime.TimeStamp.getMonth() + 1) + "/" + thisTime.TimeStamp.getDate() + "/" + thisTime.TimeStamp.getFullYear(),
					"TimeSpan": timeSpan
				});
			}
			else if(nextTime !== null)
			{
				var totalTime = self.totalTimes[thisIndex];

				totalTime.TimeSpan = +(totalTime.TimeSpan) + timeSpan;
			}

		}

		var totalTimesList = "",
			totalTime = null
			today = new Date(),
			sevenDaysAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7);

		for(var i = 0, totalTimesLength = self.totalTimes.length; i < totalTimesLength; i++)
		{
			totalTime = self.totalTimes[i];

			if(self.roundToMinutes === 30)
			{
				totalTime.TimeSpan = Math.round(totalTime.TimeSpan * 2) / 2;
			}

			totalTimesList += "
" + totalTime.Date + " " + totalTime.Name + " - " + (totalTime.TimeSpan === null ? "In Progress" : totalTime.TimeSpan + (totalTime.TimeSpan === 1 ? " hour" : " hours")) + "
";

			if(new Date(totalTime.Date) > sevenDaysAgo && totalTime.Name !== self.workStoppedSymbol && totalTime.Name !== "")
			{
				self.totalLast7Days += totalTime.TimeSpan;
			}
		}

		$(".last7Days").text(self.totalLast7Days);

		$("div.right-pane").find("ul").html("");
		$("div.right-pane").find("ul").append($(totalTimesList));
		console.log(self.totalTimes);
	};
}

var track = new Application();

track.init();<|endoftext|>


<commit_before>/**
 * RcmCallToActionBox
 *
 * JS for editing RcmCallToActionBox
 *
 * PHP version 5.3
 *
 * LICENSE: No License yet
 *
 * @category  Reliv
 * @author    Rod McNew <rmcnew@relivinc.com>
 * @copyright 2012 Reliv International
 * @license   License.txt New BSD License
 * @version   GIT: <git_id>
 */
var RcmCallToActionBoxEdit = function (instanceId, container) {

    /**
     * Always refers to this object unlike the 'this' JS variable;
     *
     * @type {RcmCallToActionBoxEdit}
     */
    var me = this;

    /**
     * jQuery object for the two links
     *
     * @type {Object}
     */
    var aTags = container.find('a');

    /**
     * Background image jQuery object
     *
     * @type {Object}
     */
    var imgTag = container.find('.rollImg');

    /**
     *  Gets background image url
     *
     * @returns {String}
     */
    var getBackgroundImageUrl = function () {
        return imgTag.css('background-image').replace('url(', '')
            .replace(')', '');
    };

    /**
     * Called by content management system to make this plugin user-editable
     */
    me.initEdit = function () {

        //Double clicking will show properties dialog
        container.dblclick(me.showEditDialog);

        //Add right click menu
        $.contextMenu({
            selector: rcm.getPluginContainerSelector(instanceId),
            //Here are the right click menu options
            items: {
                edit: {
                    name: 'Edit Properties',
                    icon: 'edit',
                    callback: function () {
                        me.showEditDialog();
                    }
                }

            }
        });
    };

    /**
     * Called by content management system to get this plugins data for saving
     * on the server
     *
     * @return {Object}
     */
    me.getSaveData = function () {
        return {
            'href': aTags.attr('href'),
            'imageSrc': getBackgroundImageUrl()
        }
    };

    /**
     * Displays a dialog box to edit href and image src
     */
    me.showEditDialog = function () {
        var srcInput = $.dialogIn('image', 'Image', getBackgroundImageUrl());
        var hrefInput = $.dialogIn('url', 'Link Url', aTags.attr('href'));

        var form = $('<form></form>')
            .addClass('simple')
            .append(srcInput, hrefInput)
            .dialog({
                title: 'Properties',
                modal: true,
                width: 620,
                buttons: {
                    Cancel: function () {
                        $(this).dialog("close");
                    },
                    Ok: function () {

                        //Get user-entered data from form
                        imgTag.css('background-image', 'url(' + srcInput.val() + ')');
                        aTags.attr('href', hrefInput.val());

                        $(this).dialog('close');
                    }
                }
            }
        );
    };
};<commit_msg>Fix Firefox issue with call to action image<commit_after>/**
 * RcmCallToActionBox
 *
 * JS for editing RcmCallToActionBox
 *
 * PHP version 5.3
 *
 * LICENSE: No License yet
 *
 * @category  Reliv
 * @author    Rod McNew <rmcnew@relivinc.com>
 * @copyright 2012 Reliv International
 * @license   License.txt New BSD License
 * @version   GIT: <git_id>
 */
var RcmCallToActionBoxEdit = function (instanceId, container) {

    /**
     * Always refers to this object unlike the 'this' JS variable;
     *
     * @type {RcmCallToActionBoxEdit}
     */
    var me = this;

    /**
     * jQuery object for the two links
     *
     * @type {Object}
     */
    var aTags = container.find('a');

    /**
     * Background image jQuery object
     *
     * @type {Object}
     */
    var imgTag = container.find('.rollImg');

    /**
     *  Gets background image url
     *
     * @returns {String}
     */
    var getBackgroundImageUrl = function () {
        return imgTag.css('background-image')
            .replace('url(', '')
            .replace(')', '')
            .replace('"','');
    };

    /**
     * Called by content management system to make this plugin user-editable
     */
    me.initEdit = function () {

        //Double clicking will show properties dialog
        container.dblclick(me.showEditDialog);

        //Add right click menu
        $.contextMenu({
            selector: rcm.getPluginContainerSelector(instanceId),
            //Here are the right click menu options
            items: {
                edit: {
                    name: 'Edit Properties',
                    icon: 'edit',
                    callback: function () {
                        me.showEditDialog();
                    }
                }

            }
        });
    };

    /**
     * Called by content management system to get this plugins data for saving
     * on the server
     *
     * @return {Object}
     */
    me.getSaveData = function () {
        return {
            'href': aTags.attr('href'),
            'imageSrc': getBackgroundImageUrl()
        }
    };

    /**
     * Displays a dialog box to edit href and image src
     */
    me.showEditDialog = function () {
        console.log(getBackgroundImageUrl());
        var srcInput = $.dialogIn('image', 'Image', getBackgroundImageUrl());
        var hrefInput = $.dialogIn('url', 'Link Url', aTags.attr('href'));

        var form = $('<form></form>')
            .addClass('simple')
            .append(srcInput, hrefInput)
            .dialog({
                title: 'Properties',
                modal: true,
                width: 620,
                buttons: {
                    Cancel: function () {
                        $(this).dialog("close");
                    },
                    Ok: function () {

                        //Get user-entered data from form
                        imgTag.css('background-image', 'url(' + srcInput.val() + ')');
                        aTags.attr('href', hrefInput.val());

                        $(this).dialog('close');
                    }
                }
            }
        );
    };
};<|endoftext|>


<commit_before>/**
* This widget displays the list of WMS layers
*/
minerva.views.WmsLayersListWidget = minerva.View.extend({

    events: {
        'submit #m-add-layers-form': function (e) {
            e.preventDefault();
            var wmsSource = this.source;

            this.$('form#m-add-layers-form :input.m-add-layers').each(_.bind(function (index, layer) {
                var typeName = $(layer).attr('typeName');
                var layerName = $(layer).attr('name');

                if (layer.checked && !_.contains(this.currentLayersInDatasets, this.generateUniqueLayerName(layerName))) {

                    this.currentLayersInDatasets.push(this.generateUniqueLayerName(layerName));

                    var params = {
                        typeName: typeName,
                        name: layerName,
                        wmsSourceId: wmsSource.get('_id')
                    };

                    var wmsDataset = new minerva.models.WmsDatasetModel({});

                    wmsDataset.once('m:wmsDatasetAdded', function () {
                        this.$el.modal('hide');
                        this.collection.add(wmsDataset);
                    }, this).createWmsDataset(params);
                }
            }, this));
        },

        'click .m-add-layers-checkbox label': function (e) {
            var checkbox = $(e.currentTarget).parent().find('input:checkbox').first();
            var checked = checkbox.prop('checked');
            var disabled = checkbox.prop('disabled');
            if (!disabled) {
                checkbox.prop('checked', !checked);
            }
        },

        'keyup #m-filter-layers': function (e) {
            var text = $(e.target).val();
            this.filterLayers(text);
        }
    },

    filterLayers: function (text) {
        var data = this.layers;
        var pattern = new RegExp(text, 'gi');
        var filteredData = _.filter(data, function (layer) {
            return pattern.test(layer.layer_title);
        });
        $('.m-layer-list').html('');
        filteredData.forEach(_.bind(function (layer) {
            var layerView = minerva.templates.layersListWidget({
                layer: layer,
                checked: _.contains(this.currentLayersInDatasets, this.generateUniqueLayerName(layer.layer_title))
            });
            $('.m-layer-list').append(layerView);
        }, this));
    },

    generateUniqueLayerName: function (layerName) {
        return layerName + '_' + this.sourceName;
    },

    layersInDatasets: function (collection) {
        return collection.map(function (model) {
            return this.generateUniqueLayerName(model.get('name'));
        }, this);
    },

    initialize: function (settings) {
        this.collection = settings.collection;
        this.setCurrentSource(settings.source);
    },

    render: function () {
        this.currentLayersInDatasets = this.layersInDatasets(this.collection);
        var modal = this.$el.html(minerva.templates.wmsLayersListWidget({
            layers: this.layers
        })).girderModal(this);
        modal.trigger($.Event('ready.girder.modal', {relatedTarget: modal}));

        this.layers.forEach(_.bind(function (layer) {
            var layerView = minerva.templates.layersListWidget({
                layer: layer,
                checked: _.contains(this.currentLayersInDatasets, this.generateUniqueLayerName(layer.layer_title))
            });
            $('.m-layer-list').append(layerView);
        }, this));

        return this;
    },

    /**
     * Change the current wmsSource whose layers will be displayed, and render.
     *
     * @param  wmsSource  The wmsSource to display.
     */
    setCurrentSource: function (wmsSource) {
        this.source = wmsSource;
        this.sourceName = this.source.get('name');
        this.layers = this.source.getMinervaMetadata().layers;
    }

});
<commit_msg>Add source_id to wms layer for dataset tracking<commit_after>/**
* This widget displays the list of WMS layers
*/
minerva.views.WmsLayersListWidget = minerva.View.extend({

    events: {
        'submit #m-add-layers-form': function (e) {
            e.preventDefault();
            var wmsSource = this.source;

            this.$('form#m-add-layers-form :input.m-add-layers').each(_.bind(function (index, layer) {
                var typeName = $(layer).attr('typeName');
                var layerName = $(layer).attr('name');

                if (layer.checked && !_.contains(this.currentLayersInDatasets, this.generateUniqueLayerName(layerName, wmsSource.get('_id')))) {
                    this.currentLayersInDatasets.push(this.generateUniqueLayerName(layerName, wmsSource.get('_id')));

                    var params = {
                        typeName: typeName,
                        name: layerName,
                        wmsSourceId: wmsSource.get('_id')
                    };

                    var wmsDataset = new minerva.models.WmsDatasetModel({});

                    wmsDataset.once('m:wmsDatasetAdded', function () {
                        this.$el.modal('hide');
                        this.collection.add(wmsDataset);
                    }, this).createWmsDataset(params);
                }
            }, this));
        },

        'click .m-add-layers-checkbox label': function (e) {
            var checkbox = $(e.currentTarget).parent().find('input:checkbox').first();
            var checked = checkbox.prop('checked');
            var disabled = checkbox.prop('disabled');
            if (!disabled) {
                checkbox.prop('checked', !checked);
            }
        },

        'keyup #m-filter-layers': function (e) {
            var text = $(e.target).val();
            this.filterLayers(text);
        }
    },

    filterLayers: function (text) {
        var data = this.layers;
        var pattern = new RegExp(text, 'gi');
        var filteredData = _.filter(data, function (layer) {
            return pattern.test(layer.layer_title);
        });
        $('.m-layer-list').html('');
        filteredData.forEach(_.bind(function (layer) {
            var layerView = minerva.templates.layersListWidget({
                layer: layer,
                checked: _.contains(this.currentLayersInDatasets, this.generateUniqueLayerName(layer.layer_title, this.source.get('_id')))
            });
            $('.m-layer-list').append(layerView);
        }, this));
    },

    generateUniqueLayerName: function (layerName, sourceId) {
        return layerName + '_' + sourceId;
    },

    layersInDatasets: function (collection) {
        var wmsLayers = collection.filter(function (model) {
            return model.getDatasetType() === 'wms';
        }, this);
        var layers = wmsLayers.map(function (model) {
            var sourceId = model.getMinervaMetadata().source_id;
            return this.generateUniqueLayerName(model.get('name'), sourceId);
        }, this);
        return layers;
    },

    initialize: function (settings) {
        this.collection = settings.collection;
        this.setCurrentSource(settings.source);
    },

    render: function () {
        this.currentLayersInDatasets = this.layersInDatasets(this.collection);
        var modal = this.$el.html(minerva.templates.wmsLayersListWidget({
            layers: this.layers
        })).girderModal(this);
        modal.trigger($.Event('ready.girder.modal', {relatedTarget: modal}));

        this.layers.forEach(_.bind(function (layer) {
            var layerView = minerva.templates.layersListWidget({
                layer: layer,
                checked: _.contains(this.currentLayersInDatasets, this.generateUniqueLayerName(layer.layer_title, this.source.get('_id')))
            });
            $('.m-layer-list').append(layerView);
        }, this));

        return this;
    },

    /**
     * Change the current wmsSource whose layers will be displayed, and render.
     *
     * @param  wmsSource  The wmsSource to display.
     */
    setCurrentSource: function (wmsSource) {
        this.source = wmsSource;
        this.sourceName = this.source.get('name');
        this.layers = this.source.getMinervaMetadata().layers;
    }

});
<|endoftext|>


<commit_before>import Mirage from 'ember-cli-mirage';

import {module, test} from 'qunit';

module('Unit | Factory');

test('it exists', function(assert) {
  assert.ok(Mirage.Factory);
});

test('the base class builds empty objects', function(assert) {
  var f = new Mirage.Factory();
  var data = f.build();

  assert.deepEqual(data, {});
});

test('a noop extension builds empty objects', function(assert) {
  var EmptyFactory = Mirage.Factory.extend();
  var f = new EmptyFactory();
  var data = f.build();

  assert.deepEqual(data, {});
});

test('it works with strings, numbers and booleans', function(assert) {
  var AFactory = Mirage.Factory.extend({
    name: 'Sam',
    age: 28,
    alive: true
  });

  var f = new AFactory();
  var data = f.build();

  assert.deepEqual(data, {name: 'Sam', age: 28, alive: true});
});

test('it supports inheritance', function(assert) {
  var PersonFactory = Mirage.Factory.extend({
    species: 'human'
  });
  var ManFactory = PersonFactory.extend({
    gender: 'male'
  });
  var SamFactory = ManFactory.extend({
    name: 'Sam'
  });

  var p = new PersonFactory();
  var m = new ManFactory();
  var s = new SamFactory();

  assert.deepEqual(p.build(), {species: 'human'});
  assert.deepEqual(m.build(), {species: 'human', gender: 'male'});
  assert.deepEqual(s.build(), {species: 'human', gender: 'male', name: 'Sam'});
});

test('it can use sequences', function(assert) {
  var PostFactory = Mirage.Factory.extend({
    likes: function(i) {
      return 5*i;
    }
  });

  var p = new PostFactory();
  var post1 = p.build(1);
  var post2 = p.build(2);

  assert.deepEqual(post1, {likes: 5});
  assert.deepEqual(post2, {likes: 10});
});

test('it can reuse static properties', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    foo: 5,
    bar: function(i) {
      return this.foo * i;
    }
  });

  var b = new BazFactory();
  var baz1 = b.build(1);
  var baz2 = b.build(2);

  assert.deepEqual(baz1, {foo: 5, bar: 5});
  assert.deepEqual(baz2, {foo: 5, bar: 10});
});

test('it can reuse dynamic properties', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    foo: function(i) {
      return 5*i;
    },
    bar: function() {
      return this.foo * 2;
    }
  });

  var b = new BazFactory();
  var baz1 = b.build(1);
  var baz2 = b.build(2);

  assert.deepEqual(baz1, {foo: 5, bar: 10});
  assert.deepEqual(baz2, {foo: 10, bar: 20});
});

test('it can reference properties out of order', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    bar: function() {
      return this.foo + 2;
    },

    baz: 6,

    foo: function(i) {
      return this.baz * i;
    }
  });

  var b = new BazFactory();
  var baz1 = b.build(1);
  var baz2 = b.build(2);

  assert.deepEqual(baz1, {baz: 6, foo: 6, bar: 8});
  assert.deepEqual(baz2, {baz: 6, foo: 12, bar: 14});
});

test('it can reference properties on complex object', function(assert) {
  var AbcFactory = Mirage.Factory.extend({
    a: function(i) {
      return this.b + i;
    },
    b: function() {
      return this.c + 1;
    },
    c: function() {
      return this.f + 1;
    },
    d: function(i) {
      return this.e + i;
    },
    e: function() {
      return this.c + 1;
    },
    f: 1,
    g: 2,
    h: 3,
  });

  var b = new AbcFactory();
  var abc1 = b.build(1);
  var abc2 = b.build(2);

  assert.deepEqual(abc1, {a: 4, b: 3, c: 2, d: 4, e: 3, f: 1, g: 2, h: 3});
  assert.deepEqual(abc2, {a: 5, b: 3, c: 2, d: 5, e: 3, f: 1, g: 2, h: 3});
});

test('throws meaningfull exception on circular reference', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    bar: function() {
      return this.foo;
    },

    foo: function(i) {
      return this.bar;
    }
  });

  var b = new BazFactory();
  assert.throws(function() {
    b.build(1);
  }, function(e) {
    return e.toString() === 'Error: Cyclic dependency in properties ["foo","bar"]';
  });
});
<commit_msg>dynamic prop should be able to reference multiple props<commit_after>import Mirage from 'ember-cli-mirage';

import {module, test} from 'qunit';

module('Unit | Factory');

test('it exists', function(assert) {
  assert.ok(Mirage.Factory);
});

test('the base class builds empty objects', function(assert) {
  var f = new Mirage.Factory();
  var data = f.build();

  assert.deepEqual(data, {});
});

test('a noop extension builds empty objects', function(assert) {
  var EmptyFactory = Mirage.Factory.extend();
  var f = new EmptyFactory();
  var data = f.build();

  assert.deepEqual(data, {});
});

test('it works with strings, numbers and booleans', function(assert) {
  var AFactory = Mirage.Factory.extend({
    name: 'Sam',
    age: 28,
    alive: true
  });

  var f = new AFactory();
  var data = f.build();

  assert.deepEqual(data, {name: 'Sam', age: 28, alive: true});
});

test('it supports inheritance', function(assert) {
  var PersonFactory = Mirage.Factory.extend({
    species: 'human'
  });
  var ManFactory = PersonFactory.extend({
    gender: 'male'
  });
  var SamFactory = ManFactory.extend({
    name: 'Sam'
  });

  var p = new PersonFactory();
  var m = new ManFactory();
  var s = new SamFactory();

  assert.deepEqual(p.build(), {species: 'human'});
  assert.deepEqual(m.build(), {species: 'human', gender: 'male'});
  assert.deepEqual(s.build(), {species: 'human', gender: 'male', name: 'Sam'});
});

test('it can use sequences', function(assert) {
  var PostFactory = Mirage.Factory.extend({
    likes: function(i) {
      return 5*i;
    }
  });

  var p = new PostFactory();
  var post1 = p.build(1);
  var post2 = p.build(2);

  assert.deepEqual(post1, {likes: 5});
  assert.deepEqual(post2, {likes: 10});
});

test('it can reuse static properties', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    foo: 5,
    bar: function(i) {
      return this.foo * i;
    }
  });

  var b = new BazFactory();
  var baz1 = b.build(1);
  var baz2 = b.build(2);

  assert.deepEqual(baz1, {foo: 5, bar: 5});
  assert.deepEqual(baz2, {foo: 5, bar: 10});
});

test('it can reuse dynamic properties', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    foo: function(i) {
      return 5*i;
    },
    bar: function() {
      return this.foo * 2;
    }
  });

  var b = new BazFactory();
  var baz1 = b.build(1);
  var baz2 = b.build(2);

  assert.deepEqual(baz1, {foo: 5, bar: 10});
  assert.deepEqual(baz2, {foo: 10, bar: 20});
});

test('it can reference properties out of order', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    bar: function() {
      return this.foo + 2;
    },

    baz: 6,

    foo: function(i) {
      return this.baz * i;
    }
  });

  var b = new BazFactory();
  var baz1 = b.build(1);
  var baz2 = b.build(2);

  assert.deepEqual(baz1, {baz: 6, foo: 6, bar: 8});
  assert.deepEqual(baz2, {baz: 6, foo: 12, bar: 14});
});

test('it can reference multiple properties in any order', function(assert) {
  var FooFactory = Mirage.Factory.extend({
    foo: function() {
      return this.bar + this.baz;
    },

    bar: 6,

    baz: 10
  });

  var BarFactory = Mirage.Factory.extend({
    bar: 6,

    foo: function() {
      return this.bar + this.baz;
    },

    baz: 10
  });

  var BazFactory = Mirage.Factory.extend({
    bar: 6,

    baz: 10,

    foo: function() {
      return this.bar + this.baz;
    }
  });

  var Foo = new FooFactory();
  var Bar = new BarFactory();
  var Baz = new BazFactory();

  var foo = Foo.build(1);
  var bar = Bar.build(1);
  var baz = Baz.build(1);

  assert.deepEqual(foo, {foo: 16, bar: 6, baz: 10});
  assert.deepEqual(bar, {foo: 16, bar: 6, baz: 10});
  assert.deepEqual(baz, {foo: 16, bar: 6, baz: 10});
});

test('it can reference properties on complex object', function(assert) {
  var AbcFactory = Mirage.Factory.extend({
    a: function(i) {
      return this.b + i;
    },
    b: function() {
      return this.c + 1;
    },
    c: function() {
      return this.f + 1;
    },
    d: function(i) {
      return this.e + i;
    },
    e: function() {
      return this.c + 1;
    },
    f: 1,
    g: 2,
    h: 3,
  });

  var b = new AbcFactory();
  var abc1 = b.build(1);
  var abc2 = b.build(2);

  assert.deepEqual(abc1, {a: 4, b: 3, c: 2, d: 4, e: 3, f: 1, g: 2, h: 3});
  assert.deepEqual(abc2, {a: 5, b: 3, c: 2, d: 5, e: 3, f: 1, g: 2, h: 3});
});

test('throws meaningfull exception on circular reference', function(assert) {
  var BazFactory = Mirage.Factory.extend({
    bar: function() {
      return this.foo;
    },

    foo: function(i) {
      return this.bar;
    }
  });

  var b = new BazFactory();
  assert.throws(function() {
    b.build(1);
  }, function(e) {
    return e.toString() === 'Error: Cyclic dependency in properties ["foo","bar"]';
  });
});
<|endoftext|>


<commit_before>module.exports = {
  env: {
    browser: true,
    es6: true,
    'jest/globals': true,
  },
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: "module",
    ecmaFeatures: {
      jsx: true,
    }
  },
  settings: {
    react: {
      version: "detect"
    }
  },
  extends: [
    "plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
    "plugin:@typescript-eslint/recommended", // Uses the recommended rules from @typescript-eslint/eslint-plugin
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended",
    "plugin:jsx-a11y/recommended",
    'plugin:jest/recommended',
  ],
  plugins: ['@typescript-eslint', 'react', 'jest', 'enzyme'],
  rules: {
    // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
    // e.g. "@typescript-eslint/explicit-function-return-type": "off",
    "prettier/prettier": 0,
    "@typescript-eslint/no-empty-function": 0,
    "@typescript-eslint/no-inferrable-types": 0,
    "@typescript-eslint/ban-types": 0,
    "@typescript-eslint/ban-ts-comment": 0,
    "@typescript-eslint/no-var-requires":0,
    "react/no-children-prop": 0,
    "react/jsx-key": 0,
    "react/prop-types": 0,
    "prefer-const": 0,
    "no-var": 0,
    'jest/no-disabled-tests': 'warn',
    'jest/no-focused-tests': 'error',
    'jest/no-identical-title': 'error',
    'jest/prefer-to-have-length': 'warn',
    'jest/valid-expect': 'error',
  },
};
<commit_msg>ignore some linting rules<commit_after>module.exports = {
  env: {
    browser: true,
    es6: true,
    'jest/globals': true,
  },
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: "module",
    ecmaFeatures: {
      jsx: true,
    }
  },
  settings: {
    react: {
      version: "detect"
    }
  },
  extends: [
    "plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
    "plugin:@typescript-eslint/recommended", // Uses the recommended rules from @typescript-eslint/eslint-plugin
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended",
    "plugin:jsx-a11y/recommended",
    'plugin:jest/recommended',
  ],
  plugins: ['@typescript-eslint', 'react', 'jest', 'enzyme'],
  rules: {
    // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
    // e.g. "@typescript-eslint/explicit-function-return-type": "off",
    "prettier/prettier": 0,
    "@typescript-eslint/no-empty-function": 0,
    "@typescript-eslint/no-inferrable-types": 0,
    "@typescript-eslint/no-namespace": 0,
    "@typescript-eslint/ban-types": 0,
    "@typescript-eslint/ban-ts-comment": 0,
    "@typescript-eslint/no-var-requires":0,
    "react/display-name": 1,
    "react/no-children-prop": 0,
    "react/jsx-key": 0,
    "react/prop-types": 0,
    "prefer-const": 0,
    "no-var": 0,
    'jest/no-disabled-tests': 'warn',
    'jest/no-focused-tests': 'error',
    'jest/no-identical-title': 'warn',
    'jest/no-mocks-import': 'warn',
    'jest/no-standalone-expect': 'warn',
    'jest/no-test-callback': 'warn',
    'jest/prefer-to-have-length': 'warn',
    'jest/valid-expect': 'warn',
    'jest/valid-expect-in-promise': 'warn',
    'jsx-a11y/aria-role': 'warn',
    'jsx-a11y/click-events-have-key-events': 'warn',
    'jsx-a11y/interactive-supports-focus': 'warn',
    'jsx-a11y/no-autofocus': 'warn',
    'jsx-a11y/no-redundant-roles': 'warn',
    'jsx-a11y/no-noninteractive-element-interactions': 'warn',
  },
};
<|endoftext|>


<commit_before>/*#ifndef(UMD)*/
"use strict";
/*global _gpfEmptyFunc*/ // An empty function
/*global _gpfExtend*/ // gpf.extend
/*exported _gpfInstallCompatibility*/ // Define and install compatible methods
/*#endif*/

/*#ifndef(UMD)*/

/**
 * Polyfills for missing 'standard' methods
 *
 * @type {Object}
 */
var _gpfCompatibility = {};

/*#endif*/

function _gpfInstallCompatibleMethods (on, methods) {
    _gpfExtend(on.prototype, methods || {}, _gpfEmptyFunc);
}

function _gpfInstallCompatibleStatics (on, statics) {
    _gpfExtend(on, statics || {}, _gpfEmptyFunc);
}

/**
 * Define and install compatible methods
 *
 * @param {String} typeName
 * @param {Object} overrides Dictionary containing:
 * - {Function} on constructor to consider
 * - {Object} [methods=undefined] methods Dictionary of name to methods
 * - {Object} [statics=undefined] statics Dictionary of name to static functions
 * @private
 */
function _gpfInstallCompatibility (typeName, overrides) {
    var on = overrides.on;
/*#ifndef(UMD)*/
    _gpfCompatibility[typeName] = overrides;
/*#endif*/
    _gpfInstallCompatibleMethods(on, overrides.methods);
    _gpfInstallCompatibleStatics(on, overrides.statics);
}

/*#ifndef(UMD)*/

gpf.internals._gpfCompatibility = _gpfCompatibility;

/*#endif*/
<commit_msg>documentation<commit_after>/**
 * @file Polyfills installer
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfEmptyFunc*/ // An empty function
/*global _gpfExtend*/ // gpf.extend
/*exported _gpfInstallCompatibility*/ // Define and install compatible methods
/*#endif*/

/*#ifndef(UMD)*/

/**
 * Polyfills for missing 'standard' methods
 *
 * @type {Object}
 */
var _gpfCompatibility = {};

/*#endif*/

function _gpfInstallCompatibleMethods (on, methods) {
    _gpfExtend(on.prototype, methods || {}, _gpfEmptyFunc);
}

function _gpfInstallCompatibleStatics (on, statics) {
    _gpfExtend(on, statics || {}, _gpfEmptyFunc);
}

/**
 * Define and install compatible methods
 *
 * @param {String} typeName
 * @param {Object} overrides Dictionary containing:
 * - {Function} on constructor to consider
 * - {Object} [methods=undefined] methods Dictionary of name to methods
 * - {Object} [statics=undefined] statics Dictionary of name to static functions
 * @private
 */
function _gpfInstallCompatibility (typeName, overrides) {
    var on = overrides.on;
/*#ifndef(UMD)*/
    _gpfCompatibility[typeName] = overrides;
/*#endif*/
    _gpfInstallCompatibleMethods(on, overrides.methods);
    _gpfInstallCompatibleStatics(on, overrides.statics);
}

/*#ifndef(UMD)*/

gpf.internals._gpfCompatibility = _gpfCompatibility;

/*#endif*/
<|endoftext|>


<commit_before>function startTutor(id) {
    var allDialogs; // List of all dialog objects, populated from html automagically
    var nextDialogIndex;

    function closeDialog() {
        $(this).dialog("close");
    }

    function nextDialog() {
        if (nextDialogIndex < allDialogs.size()) {
            if (nextDialogIndex == allDialogs.size() - 1) {
                saveSetting("tutor-finished", true);
            }

            allDialogs.eq(nextDialogIndex).dialog("open");
            nextDialogIndex++;
        }
    }

    var commonOptions = {
        autoOpen: false,
        resizable: false,
        draggable: false,
        minHeight: 0,
        modal: false,
        width: "auto",
        show: "fade",
        hide: "fade",
        dialogClass: "tutor",
        buttons: [ {
            text: localize("Got it!"),
            click: closeDialog
        }, {
            text: localize("Skip tutor"),
            click: function() {
                nextDialogIndex = allDialogs.size() - 1;
                $(this).dialog("close");
            }
        }
        ],
        close: nextDialog
    };

    var specificOptions = {
        "welcome": {
            modal: true,
            position: {
                of: "#map-canvas-container"
            }
        },
        "dz-selection": {
            position: {
                of: "#dz-finder",
                my: "center top",
                at: "center bottom+10"
            }
        },
        "target": {
            position: {
                of: "#map-canvas-container",
                my: "left top",
                at: "center+10 center+10"
            }
        },
        "wind": {
            position: {
                of: $("#wind-direction-slider").parent().parent(),
                my: "right top",
                at: "left top"
            }
        },
        "reachset": {
            position: {
                of: "#display-ui-element-buttons",
                my: "right top",
                at: "left bottom"
            }
        },
        "pattern": {
            position: {
                of: $("#opening-altitude-slider").parent().parent(),
                my: "right top",
                at: "left top"
            }
        },
        "restart": {
            position: {
                of: ".tutor-button:visible",
                my: "right top",
                at: "left bottom"
            },
            open: function() {
                location.href = "#tutor-button";
            }
        },
        "rightclick": {
            modal: false,
            buttons: [],
            position: {
                of: "#map-canvas-container",
                my: "center bottom",
                at: "center bottom-10"
            }
        }
    };

    var allDialogs = $(id).children("div");

    allDialogs.each(function(){
        var specific = specificOptions[$(this).attr("id").replace("tutor-","")];
        $(this).dialog(commonOptions).dialog("option", specific);
    });

    var finished = readSetting("tutor-finished", false);
    nextDialogIndex = finished ? allDialogs.size() - 1 : 0;
    nextDialog();
    if (finished) {
        setTimeout(function() {
            $("#tutor-rightclick").dialog("close");
        }, 3000);
    }

    $(".tutor-button").click(function() {
        nextDialogIndex = 0;
        var visible = allDialogs.filter(function() { return $(this).dialog("isOpen") }).dialog("close");
        if (visible.size() == 0) {
            nextDialog();
        }
    });
}
<commit_msg>Just move the rightclick tutor up the page a bit.<commit_after>function startTutor(id) {
    var allDialogs; // List of all dialog objects, populated from html automagically
    var nextDialogIndex;

    function closeDialog() {
        $(this).dialog("close");
    }

    function nextDialog() {
        if (nextDialogIndex < allDialogs.size()) {
            if (nextDialogIndex == allDialogs.size() - 1) {
                saveSetting("tutor-finished", true);
            }

            allDialogs.eq(nextDialogIndex).dialog("open");
            nextDialogIndex++;
        }
    }

    var commonOptions = {
        autoOpen: false,
        resizable: false,
        draggable: false,
        minHeight: 0,
        modal: false,
        width: "auto",
        show: "fade",
        hide: "fade",
        dialogClass: "tutor",
        buttons: [ {
            text: localize("Got it!"),
            click: closeDialog
        }, {
            text: localize("Skip tutor"),
            click: function() {
                nextDialogIndex = allDialogs.size() - 1;
                $(this).dialog("close");
            }
        }
        ],
        close: nextDialog
    };

    var specificOptions = {
        "welcome": {
            modal: true,
            position: {
                of: "#map-canvas-container"
            }
        },
        "dz-selection": {
            position: {
                of: "#dz-finder",
                my: "center top",
                at: "center bottom+10"
            }
        },
        "target": {
            position: {
                of: "#map-canvas-container",
                my: "left top",
                at: "center+10 center+10"
            }
        },
        "wind": {
            position: {
                of: $("#wind-direction-slider").parent().parent(),
                my: "right top",
                at: "left top"
            }
        },
        "reachset": {
            position: {
                of: "#display-ui-element-buttons",
                my: "right top",
                at: "left bottom"
            }
        },
        "pattern": {
            position: {
                of: $("#opening-altitude-slider").parent().parent(),
                my: "right top",
                at: "left top"
            }
        },
        "restart": {
            position: {
                of: ".tutor-button:visible",
                my: "right top",
                at: "left bottom"
            },
            open: function() {
                location.href = "#tutor-button";
            }
        },
        "rightclick": {
            modal: false,
            buttons: [],
            position: {
                of: "#map-canvas-container",
                my: "center bottom",
                at: "center bottom-50"
            }
        }
    };

    var allDialogs = $(id).children("div");

    allDialogs.each(function(){
        var specific = specificOptions[$(this).attr("id").replace("tutor-","")];
        $(this).dialog(commonOptions).dialog("option", specific);
    });

    var finished = readSetting("tutor-finished", false);
    nextDialogIndex = finished ? allDialogs.size() - 1 : 0;
    nextDialog();
    if (finished) {
        setTimeout(function() {
            $("#tutor-rightclick").dialog("close");
        }, 3000);
    }

    $(".tutor-button").click(function() {
        nextDialogIndex = 0;
        var visible = allDialogs.filter(function() { return $(this).dialog("isOpen") }).dialog("close");
        if (visible.size() == 0) {
            nextDialog();
        }
    });
}
<|endoftext|>


<commit_before>module.exports = {
    env: {
        jest: true,
        browser: true,
        es6: true,
        node: true
    },
    extends: 'airbnb',
    parser: 'babel-eslint',
    parserOptions: {
      ecmaVersion: 2017,
      sourceType: 'module',
      ecmaFeatures: {
        experimentalObjectRestSpread: true,
        impliedStrict: true,
        globalReturn: false
        jsx: true,
      }
    },
    rules: {
      'no-param-reassign': 'off', /* sadly, we have to reassign params to deal with props */
      'import/prefer-default-export': 'off', /* named exports allow for treeshaking */
      'no-restricted-syntax': [ /* we're omitting for of loops for this. they're pretty neat! */
        'error',
        {
          selector: 'ForInStatement',
          message: 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
        },
        {
          selector: 'LabeledStatement',
          message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
        },
        {
          selector: 'WithStatement',
          message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
        },
      ],
      'no-loop-func': 'off', /* we create functions within a loop to close over our actions. this is intentional! */
      'linebreak-style': 'off', /* we accept those of all line endings */
    }
};
<commit_msg>fixed issue with incorrect comma<commit_after>module.exports = {
    env: {
        jest: true,
        browser: true,
        es6: true,
        node: true
    },
    extends: 'airbnb',
    parser: 'babel-eslint',
    parserOptions: {
      ecmaVersion: 2017,
      sourceType: 'module',
      ecmaFeatures: {
        experimentalObjectRestSpread: true,
        impliedStrict: true,
        globalReturn: false,
        jsx: true,
      }
    },
    rules: {
      'no-param-reassign': 'off', /* sadly, we have to reassign params to deal with props */
      'import/prefer-default-export': 'off', /* named exports allow for treeshaking */
      'no-restricted-syntax': [ /* we're omitting for of loops for this. they're pretty neat! */
        'error',
        {
          selector: 'ForInStatement',
          message: 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
        },
        {
          selector: 'LabeledStatement',
          message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
        },
        {
          selector: 'WithStatement',
          message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
        },
      ],
      'no-loop-func': 'off', /* we create functions within a loop to close over our actions. this is intentional! */
      'linebreak-style': 'off', /* we accept those of all line endings */
    }
};
<|endoftext|>


<commit_before>var _calculateBarBlocks = function(sum, value) {
    var count = Math.floor(value/sum*20);   // 100% is 20 blocks
    return voteBar(count);
};

var _formatMessage = function(fields) {
    var message = bold('🏆 Top Result 🏆: ' + fields[0].title.titleize()) + '\n\n\n';
    var sum = fields.reduce(function(pv, cv) { return parseInt(pv) + parseInt(cv.value); }, 0);

    for (var i = 0; i < fields.length; i++) {
        var option  = fields[i];
        message += bold(option.title.titleize()) + ':\n' + bold(Math.floor(option.value/sum*100)) + '% - ';

        if (option.value == 0) {
            message += inlineBlock('😭') + '\n\n';
        } else {
            message += _calculateBarBlocks(sum, option.value) + '\n\n';
        }
    }

    return message;
};

var resultResponse = function (info, options) {
    var fields = options.map(function (opts, index) {
        return {
            "title" : opts.option,
            "value" : opts.count,
            "short" : false
        };
    });

    fields.sort(function (a, b) {
        return a.value > b.value ? 1 : -1;
    });

    var title = "Poll Results for " + info.title.titleize();

    var attachment = [{
            "fallback": title.titleize(),
            "color": "#44cfaa",    // good, warning, danger, or HEX value
            "title": title,
            "text": _formatMessage(fields),
			"mrkdwn_in": ["title", "text"]
    }];
    var message = {
        "response_type": "in_channel",
        "attachments": attachment
    };
    return message;
};

var openResponse = function (params) {
    var fields = params.opts.map(function (opts, index) {
        return {
            "title" : ((index+1).toString() + ". " + opts)).titleize(),
            "short" : false
        };
    });

    var attachment = [{
            "fallback": params.title.titleize(),
            "color": "#d4484d",    // good, warning, danger, or HEX value
            "title": params.title.titleize(),
            "fields": fields
    }];
    var message = {
        "response_type": "in_channel",
        "attachments": attachment
    };
    return message;
};

var bold = function(text) {
    return '*' + text + '*';
};

var italics = function(text) {
    return '_' + text + '_';
};

var strike = function(text) {
    return '~' + text + '~';
};

var inlineBlock = function(text) {
    return '`' + text + '`';
};

var blockQuote = function(text) {
    return '```' + text + '```';
};

var voteBar = function(count) {
    var voteBar = '`';
    for (var i = 0; i < count; i++) {
        voteBar += '█';
    }
    voteBar += '`';

    return voteBar;
};

var validToken = function(token) {
    var validToken = process.env.SLACK_TOKEN;
    return validToken ? token === validToken : true;
};

module.exports = {
    openResponse : openResponse,
    resultResponse : resultResponse,
    validToken: validToken
};
<commit_msg>✏  add footer to opening message<commit_after>var _calculateBarBlocks = function(sum, value) {
    var count = Math.floor(value/sum*20);   // 100% is 20 blocks
    return voteBar(count);
};

var _formatMessage = function(fields) {
    var message = bold('🏆 Top Result 🏆: ' + fields[0].title.titleize()) + '\n\n\n';
    var sum = fields.reduce(function(pv, cv) { return parseInt(pv) + parseInt(cv.value); }, 0);

    for (var i = 0; i < fields.length; i++) {
        var option  = fields[i];
        message += bold(option.title.titleize()) + ':\n' + bold(Math.floor(option.value/sum*100)) + '% - ';

        if (option.value == 0) {
            message += inlineBlock('😭') + '\n\n';
        } else {
            message += _calculateBarBlocks(sum, option.value) + '\n\n';
        }
    }

    return message;
};

var resultResponse = function (info, options) {
    var fields = options.map(function (opts, index) {
        return {
            "title" : opts.option,
            "value" : opts.count,
            "short" : false
        };
    });

    fields.sort(function (a, b) {
        return a.value > b.value ? 1 : -1;
    });

    var title = "Poll Results for " + info.title.titleize();

    var attachment = [{
            "fallback": title.titleize(),
            "color": "#44cfaa",    // good, warning, danger, or HEX value
            "title": title,
            "text": _formatMessage(fields),
			"mrkdwn_in": ["title", "text"]
    }];
    var message = {
        "response_type": "in_channel",
        "attachments": attachment
    };
    return message;
};

var openResponse = function (params) {
    var fields = params.opts.map(function (opts, index) {
        return {
            "title" : ((index+1).toString() + ". " + opts)).titleize(),
            "short" : false
        };
    });

    var attachment = [{
            "fallback": params.title.titleize(),
            "color": "#d4484d",    // good, warning, danger, or HEX value
            "title": params.title.titleize(),
            "fields": fields,
            "footer": "Cast your vote using the slash command /poll vote [option]."
    }];
    var message = {
        "response_type": "in_channel",
        "attachments": attachment
    };
    return message;
};

var bold = function(text) {
    return '*' + text + '*';
};

var italics = function(text) {
    return '_' + text + '_';
};

var strike = function(text) {
    return '~' + text + '~';
};

var inlineBlock = function(text) {
    return '`' + text + '`';
};

var blockQuote = function(text) {
    return '```' + text + '```';
};

var voteBar = function(count) {
    var voteBar = '`';
    for (var i = 0; i < count; i++) {
        voteBar += '█';
    }
    voteBar += '`';

    return voteBar;
};

var validToken = function(token) {
    var validToken = process.env.SLACK_TOKEN;
    return validToken ? token === validToken : true;
};

module.exports = {
    openResponse : openResponse,
    resultResponse : resultResponse,
    validToken: validToken
};
<|endoftext|>


<commit_before>App.module("Root", function(Root, App, Backbone, Marionette, $, _){

  Root.Controller = {
    "editNote": function(key){
      App.rootLayout.showChildView("container", new App.EditNote.Views.Main({key: key}));
    }
  };

  Root.Router = Marionette.AppRouter.extend({
    controller: Root.Controller,
    appRoutes: {
      "note/:key": "editNote"
    }
  });

});<commit_msg>ability to route to note by object and not just by key<commit_after>App.module("Root", function(Root, App, Backbone, Marionette, $, _){

  Root.Controller = {
    "editNote": function(options){
      App.rootLayout.showChildView("container", new App.EditNote.Views.Main(options));
      // update URL
      var key = options.key || options.model.get("key");
      Backbone.history.navigate("note/" + key, {trigger: false});
    },
    "editNoteByKey": function(key){
      this.editNote({key: key});
    },
    }
  };

  Root.Router = Marionette.AppRouter.extend({
    controller: Root.Controller,
    appRoutes: {
      "note/:key": "editNoteByKey",
    }
  });

  App.channel.on("router:navigate", function(name /*...*/){
    Root.Controller[name].apply(Root, _.toArray(arguments).slice(1));
  });
});<|endoftext|>