<!DOCTYPE html>
<html ng-app="app">
<head>
<link data-require="font-awesome@*" data-semver="4.5.0" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.css" />
<link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<link data-require="animate.css@*" data-semver="3.2.0" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.0/animate.min.css" />
<link data-require="ngToast@*" data-semver="1.5.0" rel="stylesheet" href="//rawgit.com/tameraydin/ngToast/1.5.0/dist/ngToast.css" />
<link data-require="ngToast@*" data-semver="1.5.0" rel="stylesheet" href="//rawgit.com/tameraydin/ngToast/1.5.0/dist/ngToast-animations.css" />
<script data-require="jquery@*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script data-require="angular.js@1.4.9" data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular.js"></script>
<script data-require="ui-router@*" data-semver="0.2.18" src="//cdn.rawgit.com/angular-ui/ui-router/0.2.18/release/angular-ui-router.js"></script>
<script data-require="underscore.js@*" data-semver="1.8.3" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script data-require="ui-bootstrap@*" data-semver="1.3.2" src="https://cdn.rawgit.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-tpls-1.3.2.js"></script>
<script data-require="angular-sanitize@*" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-sanitize.js"></script>
<script data-require="angular-animate@*" data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular-animate.js"></script>
<script data-require="ngToast@*" data-semver="1.5.0" src="//rawgit.com/tameraydin/ngToast/1.5.0/dist/ngToast.js"></script>
<script src="angular-clipboard.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="app.js"></script>
<script src="KinobodyProgramDataService.js"></script>
<script src="MainController.js"></script>
</head>
<body ng-controller="mainController as vm">
<toast></toast>
<div ui-view=""></div>
<div class="container-fluid">
<form>
<div class="row">
<div class="col-md-12">
<h4>Kinobody Calories / Macros</h4>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="form-group has-warning">
<div class="input-group input-select">
<span class="input-group-addon input-label">Kinobody Program</span>
<select class="form-control" ng-options="(option.name + ' - ' + option.description) for option in vm.programOptionSet" ng-model="vm.selectedProgram" title="{{vm.selectedProgram.description}}" ng-change="vm.onProgramOptionChange()"></select>
</div>
</div>
</div>
</div>
<div class="row" ng-show="vm.activeProgramSubOptionSet.length > 1">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="form-group has-warning">
<div class="input-group input-select">
<span class="input-group-addon input-label">Program Options</span>
<select class="form-control" ng-options="(option.name) for option in vm.activeProgramSubOptionSet" ng-model="vm.selectedProgramSubOption" ng-change="vm.onProgramSubOptionChange()"></select>
</div>
</div>
</div>
</div>
<div class="row" ng-show="vm.activeMacroOptionSet.length > 1">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="form-group has-warning">
<div class="input-group input-select">
<span class="input-group-addon input-label">Macro Options</span>
<select class="form-control" ng-options="(option.name) for option in vm.activeMacroOptionSet" ng-model="vm.selectedMacroOption" ng-change="vm.onMacroOptionChange()"></select>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="form-group has-warning">
<div class="input-group">
<span class="input-group-addon input-label">{{vm.inputWeightLabel}}</span>
<input type="text" class="form-control" ng-model="vm.inputWeight" ng-model-options="{debounce: 500}" ng-change="vm.onWeightChange()" />
<span class="input-group-btn">
<button type="button" class="btn btn-toggle" ng-click="vm.toggleInputUnitsWeight()" tabindex="-1" title="Click to toggle kg/lbs">
{{vm.inputUnitsWeight}} <i class="fa fa-toggle-on" ng-class="{'fa-flip-horizontal': vm.inputUnitsWeight !== 'kg'}"></i>
</button>
</span>
</div>
</div>
<div ng-show="vm.hasGoalNotes">
<ul>
<li ng-repeat="note in vm.goalNotes">
{{note.text}}
</li>
</ul>
</div>
</div>
</div>
<div class="row" ng-show="vm.kcalOffsetActive">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="form-group has-warning">
<div class="input-group">
<span class="input-group-addon input-label">kcal Offset</span>
<input type="text" class="form-control" ng-model="vm.kcalOffset" ng-model-options="{debounce: 500}" ng-change="vm.onKcalOffsetChange()" />
<span class="input-group-addon">kcal</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<fieldset disabled="">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon input-label">Maintenance (lbs x 15)</span>
<input type="text" ng-model="vm.kinobodyEstimateMaintenanceCalories_display" class="form-control text-right" placeholder="Required: weight" readonly="" />
<span class="input-group-addon">kcal</span>
</div>
</div>
</fieldset>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-12">
<h4>{{vm.macroSectionLabel}}</h4>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<fieldset disabled="">
<div class="form-group" ng-class="{'has-success' : vm.activeMaintenanceFormula === 'KB'}">
<div class="input-group">
<span class="input-group-addon input-label">{{vm.dailyCaloriesLabel}}</span>
<input type="text" ng-model="vm.kinobodyEstimateDailyCalories_display" class="form-control text-right" placeholder="Required: weight" readonly="" />
<span class="input-group-addon">kcal</span>
</div>
</div>
</fieldset>
</div>
</div>
<fieldset disabled="">
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Protein</span>
<input type="text" ng-model="vm.macrosProtein" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageProtein" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Fats</span>
<input type="text" ng-model="vm.macrosFats" id="macrosFat" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageFats" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Carbs</span>
<input type="text" ng-model="vm.macrosCarbs" id="macrosCarb" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageCarbs" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
</fieldset>
<div ng-show="vm.hasTrainingRestDaysSplit">
<hr />
<div class="row">
<div class="col-md-12">
<h4>{{vm.macroSectionLabel_rest}}</h4>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<fieldset disabled="">
<div class="form-group" ng-class="{'has-success' : vm.activeMaintenanceFormula === 'KB'}">
<div class="input-group">
<span class="input-group-addon input-label">{{vm.dailyCaloriesLabel_rest}}</span>
<input type="text" ng-model="vm.kinobodyEstimateDailyCalories_rest_display" class="form-control text-right" placeholder="Required: weight" readonly="" />
<span class="input-group-addon">kcal</span>
</div>
</div>
</fieldset>
</div>
</div>
<fieldset disabled="">
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Protein</span>
<input type="text" ng-model="vm.macrosProtein_rest" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageProtein_rest" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Fats</span>
<input type="text" ng-model="vm.macrosFats_rest" id="macrosFat" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageFats_rest" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Carbs</span>
<input type="text" ng-model="vm.macrosCarbs_rest" id="macrosCarb" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageCarbs_rest" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
</fieldset>
</div>
<div ng-show="vm.hasRefeedDaySubOption">
<hr />
<div class="row">
<div class="col-md-12">
<h4>{{vm.macroSectionLabel_refeed}}</h4>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<fieldset disabled="">
<div class="form-group" ng-class="{'has-success' : vm.activeMaintenanceFormula === 'KB'}">
<div class="input-group">
<span class="input-group-addon input-label">{{vm.dailyCaloriesLabel_refeed}}</span>
<input type="text" ng-model="vm.kinobodyEstimateDailyCalories_refeed_display" class="form-control text-right" placeholder="Required: weight" readonly="" />
<span class="input-group-addon">kcal</span>
</div>
</div>
</fieldset>
<div ng-show="vm.hasRefeedDayNotes">
<ul>
<li ng-repeat="note in vm.refeedDayNotes">
{{note.text}}
</li>
</ul>
</div>
</div>
</div>
<fieldset disabled="">
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Protein</span>
<input type="text" ng-model="vm.macrosProtein_refeed" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageProtein_refeed" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Fats</span>
<input type="text" ng-model="vm.macrosFats_refeed" id="macrosFat" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageFats_refeed" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="row">
<div class="col-xs-8">
<div class="form-group has-success">
<div class="input-group">
<span class="input-group-addon input-macros">Carbs</span>
<input type="text" ng-model="vm.macrosCarbs_refeed" id="macrosCarb" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">g</span>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group has-success">
<div class="input-group">
<input type="text" ng-model="vm.percentageCarbs_refeed" id="macrosProtein" class="form-control text-right" placeholder="" readonly="" />
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>
</div>
</fieldset>
</div>
<hr />
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="form-group" ng-class="{'has-success' : vm.activeMaintenanceFormula === 'KB'}">
<div class="input-group">
<span class="input-group-addon">Link: </span>
<input type="text" ng-model="vm.shareLink" class="form-control" />
<span class="input-group-btn">
<button clipboard="" supported="vm.clipboardSupported" text="vm.shareLink" on-copied="vm.onClipboardSuccess()" on-error="onClipboardFail(err)" type="button" class="btn btn-toggle" tabindex="-1" title="Click to copy to clipboard">
<i class="fa fa-copy"></i>
</button>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-9 col-xs-12">
<div class="form-group">
<button type="button" class="btn btn-default" ng-click="vm.resetForm()" tabindex="-1">
<i class="fa fa-fw fa-remove"></i>
Clear my data
</button>
</div>
</div>
</div>
<div ng-show="vm.displayDebuggingArea">
<div class="row">
<div class="col-md-12">
<h4>Debugging: stuff below is not working yet!</h4>
</div>
</div>
<div>
<ul>
<li>Check kcal normal/training day: {{vm.crossCheckCalories}}</li>
<li ng-show="vm.hasTrainingRestDaysSplit">Check kcal rest day: {{vm.crossCheckCalories_rest}}</li>
<li ng-show="vm.hasRefeedDaySubOption">Check kcal refeed day: {{vm.crossCheckCalories_refeed}}</li>
</ul>
</div>
</div>
</form>
</div>
</body>
</html>
/* Styles go here */
body {
padding: 15px;
}
.input-label {
width: 150px;
text-align: left;
}
.input-macros {
width: 100px;
text-align: left;
}
.input-select {
width: 100%;
}
.btn-toggle {
color: #A66D3B;
background-color: #FCF8E3;
border-color: #8A6D3B;
}
(function() {
var app = angular.module('app', [
'ui.router',
'ui.bootstrap',
'angular-clipboard',
'ngAnimate',
'ngSanitize',
'ngToast'
]);
app.run(['$state', function($state) {
console.log("app run");
}]);
app.config(function() {
console.log("app config");
});
app.config(['ngToastProvider', function(ngToastProvider) {
ngToastProvider.configure({
animation: 'slide' // or 'fade'
});
}]);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', uiRouterConfigurator]);
function uiRouterConfigurator($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/');
// States
$stateProvider
.state('reset', {
url: '/?kcalOffset',
// params: {
// test: null,
// },
//url: '/afl/{weight}_{weightUnits}',
// templateUrl: 'kinobody_afl.html',
// controller: 'kinobody_afl_controller',
// controllerAs: 'vm',
})
.state('home', {
url: '/{programName}/{programSubOptionName}/{macrosOptionName}/{weight}_{weightUnits}?kcalOffset',
// params: {
// test: null,
// },
//url: '/afl/{weight}_{weightUnits}',
// templateUrl: 'kinobody_afl.html',
// controller: 'kinobody_afl_controller',
// controllerAs: 'vm',
})
// .state('status', {
// url: '/status/:statusName',
// templateUrl: 'hallo.html',
// })
;
}
})();
(function() {
'use strict';
angular.module('app')
.controller('mainController', MainController);
MainController.$inject = ['$scope', '$log', '$state', '$stateParams', '$location', '$timeout', 'ngToast', 'kinobodyProgramData'];
function MainController($scope, $log, $state, $stateParams, $location, $timeout, ngToast, kinobodyProgramData) {
var _kgToPoundRatio = 2.2046226218;
var _cmToInRatio = 0.39370;
var _inputWeight = '';
var _inputHeight = '';
var initialized = false;
var _initTimeout = 3000;
var _DefaultStartupProgramRoutingName = 'kinobody_afl';
// view model
var vm = this;
vm.title = 'Kinobody Calories/Macros!';
vm.clipboardSupported = false;
vm.weightKg = '';
vm.selectedProgramRoutingName = _DefaultStartupProgramRoutingName;
vm.displayDebuggingArea = false;
vm.activeProgramSubOptionSet = '';
vm.activeMacroOptionSet = '';
vm.selectedProgram = '';
vm.selectedProgramSubOption = '';
vm.selectedMacroOption = '';
vm.inputUnitsWeight = 'kg';
vm.macroSectionLabel = 'Daily calories / macros';
vm.macroSectionLabel_rest = 'Rest days calories / macros';
vm.macroSectionLabel_refeed = 'Refeed days calories / macros';
vm.kcalOffset = 0;
vm.kcalOffsetActive = false;
vm.programOptionSet = kinobodyProgramData.getKinobodyPrograms();
function init() {
// process state params here
processStateParams($stateParams);
updateRoute();
$timeout(function() {
initialized = true;
}, _initTimeout);
}
function processStateParams(stateParams) {
// $log.log('processStateParams $location', $location);
$log.log('processStateParams stateParams', stateParams);
// $log.log('processStateParams $state.params', $state.params);
var programName = '';
var programSubOptionName = '';
var macrosOptionName = '';
var kcalOffset = 0;
if(stateParams) {
// restore program by id:
if (stateParams.programName) {
programName = stateParams.programName;
vm.selectedProgramRoutingName = stateParams.programName;
}
if(stateParams.programSubOptionName) {
programSubOptionName = stateParams.programSubOptionName;
}
if(stateParams.macrosOptionName) {
macrosOptionName = stateParams.macrosOptionName;
}
if(stateParams.kcalOffset) {
kcalOffset = stateParams.kcalOffset;
vm.kcalOffset = Number(stateParams.kcalOffset);
vm.kcalOffsetActive = true;
}
// weight / weight units
if (stateParams.weight && stateParams.weightUnits) {
var weight = stateParams.weight;
var units = stateParams.weightUnits.toLowerCase();
vm.inputUnitsWeight = (units === 'lbs') ? 'lbs' : 'kg';
if (vm.inputUnitsWeight === 'kg') {
vm.weightKg = weight;
} else {
vm.weightKg = weight / _kgToPoundRatio;
}
vm.inputWeight = (vm.inputUnitsWeight === 'kg') ? vm.weightKg : (vm.weightKg * _kgToPoundRatio);
}
}
// initialize controls
var initializeFromRoute = (programName && programSubOptionName && macrosOptionName);
$log.log('initializeFromRoute', initializeFromRoute, stateParams, programName, programSubOptionName, macrosOptionName);
// INIT: vm.weightKg is always in kg!
vm.inputWeight = (vm.inputUnitsWeight === 'kg') ? vm.weightKg : (vm.weightKg * _kgToPoundRatio);
vm.inputHeight = (vm.inputUnitsHeight === 'cm') ? vm.heightCm : (vm.heightCm * _cmToInRatio);
//var hasRoutingError = true;
vm.selectedProgram = _.find(vm.programOptionSet, function(item) {
return item.routing_name.toUpperCase() === vm.selectedProgramRoutingName.toUpperCase();
});
if (!vm.selectedProgram) {
vm.selectedProgramRoutingName = _DefaultStartupProgramRoutingName;
vm.selectedProgram = _.find(vm.programOptionSet, function(item) {
return item.routing_name.toUpperCase() === vm.selectedProgramRoutingName.toUpperCase();
});
} else if (vm.selectedProgram && initializeFromRoute) {
$log.log('-- selectedProgram success!', programName);
$log.log('vm.selectedProgram && initializeFromRoute', initializeFromRoute, stateParams);
vm.activeProgramSubOptionSet = vm.selectedProgram.programSubOptionSet;
vm.selectedProgramSubOption = _.find(vm.activeProgramSubOptionSet, function(item) {
return item.routing_name === programSubOptionName;
});
if(vm.selectedProgramSubOption) {
$log.log('-- selectedProgramSubOption success!', programSubOptionName);
vm.selectedProgram.prevSelectedProgramSubOption = vm.selectedProgramSubOption;
vm.activeMacroOptionSet = vm.selectedProgramSubOption.macroOptionSet;
vm.selectedMacroOption = _.find(vm.activeMacroOptionSet, function(item) {
return item.routing_name === macrosOptionName;
});
if(vm.selectedMacroOption) {
$log.log('-- selectedMacroOption success!', macrosOptionName);
vm.selectedProgramSubOption.prevSelectedMacroOption = vm.selectedMacroOption;
}
}
}
// if(!vm.selectedProgram) {
// }
// if(hasRoutingError) {
// }
// _selectedProgram = _.find(vm.programOptionSet, function(item) { return item.routing_name.toUpperCase() === vm.selectedProgramId.toUpperCase(); });
// if(!_selectedProgram) {
// // $log.log('invalid program name');
// _selectedProgram = vm.programOptionSet[0];
// vm.selectedProgramId = _selectedProgram.programId;
// $timeout(function() {
// updateRoute();
// }, 10);
// }
//vm.selectedMacroOption = vm.selectedProgram.macroOptionSet[vm.selectedProgram.defaultMacroOptionIndex];
// if(initializeFromRoute) {
// vm.activeProgramSubOptionSet = vm.selectedProgram.programSubOptionSet;
// vm.selectedProgramSubOption = _.find(vm.activeProgramSubOptionSet, function(item) {
// return item.routing_name === programSubOptionName;
// });
// if(vm.selectedProgramSubOption) {
// vm.activeMacroOptionSet = vm.selectedProgramSubOption.macroOptionSet;
// vm.selectedMacroOption = _.find(vm.activeMacroOptionSet, function(item) {
// return item.routing_name === macrosOptionName;
// });
// }
// }
// if (hasRoutingError) {
// vm.selectedProgramRoutingName = _DefaultStartupProgramRoutingName;
// onProgramOptionChange();
// updateRoute();
// }
onProgramOptionChange();
updateRoute();
}
Object.defineProperty(vm, "shareLink", {
get: function() {
return $location.absUrl();
}
});
Object.defineProperty(vm, "hasTrainingRestDaysSplit", {
get: function() {
return vm.selectedProgramSubOption.hasTrainingRestDaysSplit;
}
});
Object.defineProperty(vm, "hasRefeedDaySubOption", {
get: function() {
return vm.selectedProgramSubOption.hasRefeedDaySubOption;
}
});
Object.defineProperty(vm, "refeedDaySubOption", {
get: function() {
return vm.selectedProgramSubOption.refeedDaySubOption;
}
});
Object.defineProperty(vm, "hasFixedCaloriesOffset", {
get: function() {
return vm.selectedProgramSubOption.hasFixedCaloriesOffset;
}
});
Object.defineProperty(vm, "isGoalBodyWeightRequired", {
get: function() {
return vm.selectedProgramSubOption.isGoalBodyWeightRequired;
}
});
Object.defineProperty(vm, "isBodyWeightOrGoalBodyWeightRequired", {
get: function() {
return vm.selectedProgramSubOption.isBodyWeightOrGoalBodyWeightRequired;
}
});
Object.defineProperty(vm, "hasGoalNotes", {
get: function() {
return vm.selectedProgramSubOption.goalNotes && vm.selectedProgramSubOption.goalNotes.length > 0;
}
});
Object.defineProperty(vm, "goalNotes", {
get: function() {
return vm.selectedProgramSubOption.goalNotes;
}
});
Object.defineProperty(vm, "hasRefeedDayNotes", {
get: function() {
return vm.selectedProgramSubOption.refeedDayNotes && vm.selectedProgramSubOption.refeedDayNotes.length > 0;
}
});
Object.defineProperty(vm, "refeedDayNotes", {
get: function() {
return vm.selectedProgramSubOption.refeedDayNotes;
}
});
// Object.defineProperty(vm, "selectedProgram", {
// get: function() {
// return _selectedProgram;
// },
// set: function(value) {
// _selectedProgram = value;
// vm.selectedProgramName = _selectedProgram.routing_name;
// }
// });
Object.defineProperty(vm, "inputWeight", {
get: function() {
return _inputWeight;
},
set: function(value) {
_inputWeight = value;
vm.weightKg = convertInputWeightToKg(_inputWeight);
}
});
Object.defineProperty(vm, "weightLbs", {
get: function() {
if(vm.weightKg) {
return vm.weightKg * _kgToPoundRatio;
}
return '';
}
});
Object.defineProperty(vm, "kcalOffset_number", {
get: function() {
if(vm.kcalOffset && canBeNumber(vm.kcalOffset)) {
return Number(vm.kcalOffset);
}
return 0;
}
});
Object.defineProperty(vm, "kinobodyEstimateMaintenanceCalories", {
get: function() {
if(vm.weightLbs) {
return (kinobodyProgramData.getKinobodyMaintenanceFactor() * vm.weightLbs) + vm.kcalOffset_number;
}
return '';
}
});
Object.defineProperty(vm, "kinobodyEstimateMaintenanceCalories_display", {
get: function() {
if(vm.kinobodyEstimateMaintenanceCalories) {
return formatCalNumber(vm.kinobodyEstimateMaintenanceCalories);
}
return '';
}
});
Object.defineProperty(vm, "activeMaintenanceFormula", {
get: function() {
// => only use KB for now!
if (vm.kinobodyEstimateMaintenanceCalories) {
return 'KB';
}
return '';
}
});
// Object.defineProperty(vm, "maintenanceCalories", {
// get: function() {
// if (vm.kinobodyEstimateMaintenanceCalories) {
// return formatCalNumber(vm.kinobodyEstimateMaintenanceCalories);
// }
// return '';
// }
// });
Object.defineProperty(vm, "inputUnitsWeight_display", {
get: function() {
if (vm.inputUnitsWeight === 'kg') {
return 'Kg';
} else if (vm.inputUnitsWeight === 'lbs') {
return 'Lbs';
}
return 'inputUnitsWeight_display error';
}
});
Object.defineProperty(vm, "inputWeightLabel", {
get: function() {
if(vm.isGoalBodyWeightRequired && vm.isGoalBodyWeightRequired === true) {
return 'Goal weight in ' + vm.inputUnitsWeight_display;
} else if (vm.isBodyWeightOrGoalBodyWeightRequired) {
return '(Goal/) Body weight in ' + vm.inputUnitsWeight_display;
} else {
return 'Weight in ' + vm.inputUnitsWeight_display;
}
}
});
//--------------------------------------------------------------------------
// default / training days
//--------------------------------------------------------------------------
Object.defineProperty(vm, "macroSectionLabel", {
get: function() {
var label = 'Daily calories / macros';
if(vm.hasTrainingRestDaysSplit) {
label = 'Training days calories / macros';
}
return label;
}
});
Object.defineProperty(vm, "dailyCaloriesLabel", {
get: function() {
var label = 'Calories '
+ '(lbs x ' + vm.selectedProgramSubOption.lbsFactor + ')'
+ vm.programOffsetLabel;
return label;
}
});
Object.defineProperty(vm, "programOffsetLabel", {
get: function() {
var offset = vm.programOffset;
if (offset !== 0) {
if(offset > 0) {
return ' + ' + offset;
} else {
return ' - ' + Math.abs(offset);
}
}
return '';
}
});
Object.defineProperty(vm, "programOffset", {
get: function() {
if (vm.hasTrainingRestDaysSplit) {
return vm.selectedProgramSubOption.trainingDaysCaloriesOffset;
} else if (vm.hasFixedCaloriesOffset) {
return vm.selectedProgramSubOption.fixedCaloriesOffset;
}
return 0;
}
});
Object.defineProperty(vm, "kinobodyEstimateDailyCalories", {
get: function() {
if(vm.weightLbs) {
return (vm.selectedProgramSubOption.lbsFactor * vm.weightLbs) + vm.programOffset + vm.kcalOffset_number;
}
return '';
}
});
Object.defineProperty(vm, "kinobodyEstimateDailyCalories_display", {
get: function() {
if(vm.kinobodyEstimateDailyCalories) {
return formatCalNumber(vm.kinobodyEstimateDailyCalories);
}
return '';
}
});
Object.defineProperty(vm, "deficitCalories", {
get: function() {
if(vm.kinobodyEstimateDailyCalories) {
return formatCalNumber(vm.kinobodyEstimateDailyCalories);
}
return '';
}
});
Object.defineProperty(vm, "macrosProtein", {
get: function() {
if(vm.selectedMacroOption && vm.deficitCalories) {
return formatCalNumber(vm.selectedMacroOption.getProteinMacros(vm.deficitCalories, vm.weightKg, vm.weightLbs));
}
return '';
}
});
Object.defineProperty(vm, "macrosFats", {
get: function() {
if(vm.selectedMacroOption && vm.deficitCalories) {
return formatCalNumber(vm.selectedMacroOption.getFatMacros(vm.deficitCalories));
}
return '';
}
});
Object.defineProperty(vm, "macrosCarbs", {
get: function() {
// the rest from carbs
if(vm.deficitCalories) {
return formatCalNumber(kinobodyProgramData.calculateCarbMacros_default(vm.macrosProtein, vm.macrosFats, vm.deficitCalories));
}
return '';
}
});
Object.defineProperty(vm, "percentageProtein", {
get: function() {
if(vm.macrosProtein) {
var calsFats = vm.macrosProtein * 4;
var p = calsFats / vm.deficitCalories * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "percentageFats", {
get: function() {
if(vm.macrosFats) {
var calsFats = vm.macrosFats * 9;
var p = calsFats / vm.deficitCalories * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "percentageCarbs", {
get: function() {
if(vm.macrosCarbs) {
var calsCarbs = vm.macrosCarbs * 4;
var p = calsCarbs / vm.deficitCalories * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "crossCheckCalories", {
get: function() {
if(vm.macrosProtein && vm.macrosFats && vm.macrosCarbs) {
var calsProtein = vm.macrosProtein * 4;
var calsFats = vm.macrosFats * 9;
var calsCarbs = vm.macrosCarbs * 4;
return formatCalNumber(calsProtein + calsFats + calsCarbs);
}
return '';
}
});
//--------------------------------------------------------------------------
// rest days
//--------------------------------------------------------------------------
Object.defineProperty(vm, "macroSectionLabel_rest", {
get: function() {
var label = 'Rest days calories / macros';
return label;
}
});
Object.defineProperty(vm, "dailyCaloriesLabel_rest", {
get: function() {
var label = 'Calories '
+ '(lbs x ' + vm.selectedProgramSubOption.lbsFactor + ')'
+ vm.programOffsetLabel_rest;
return label;
}
});
Object.defineProperty(vm, "programOffsetLabel_rest", {
get: function() {
if (vm.hasTrainingRestDaysSplit) {
if(vm.selectedProgramSubOption.restDaysCaloriesOffset > 0) {
return ' + ' + vm.selectedProgramSubOption.restDaysCaloriesOffset;
} else {
return ' - ' + Math.abs(vm.selectedProgramSubOption.restDaysCaloriesOffset);
}
}
return '';
}
});
Object.defineProperty(vm, "kinobodyEstimateDailyCalories_rest", {
get: function() {
if(vm.weightLbs) {
if(!vm.hasTrainingRestDaysSplit) {
return (vm.selectedProgramSubOption.lbsFactor * vm.weightLbs);
} else {
return (vm.selectedProgramSubOption.lbsFactor * vm.weightLbs) + vm.selectedProgramSubOption.restDaysCaloriesOffset + vm.kcalOffset_number;
}
}
return '';
}
});
Object.defineProperty(vm, "kinobodyEstimateDailyCalories_rest_display", {
get: function() {
if(vm.kinobodyEstimateDailyCalories_rest) {
return formatCalNumber(vm.kinobodyEstimateDailyCalories_rest);
}
return '';
}
});
Object.defineProperty(vm, "deficitCalories_rest", {
get: function() {
if(vm.kinobodyEstimateDailyCalories_rest) {
return formatCalNumber(vm.kinobodyEstimateDailyCalories_rest);
}
return '';
}
});
Object.defineProperty(vm, "macrosProtein_rest", {
get: function() {
if(vm.selectedMacroOption && vm.deficitCalories_rest) {
return formatCalNumber(vm.selectedMacroOption.getProteinMacros(vm.deficitCalories_rest, vm.weightKg, vm.weightLbs));
}
return '';
}
});
Object.defineProperty(vm, "macrosFats_rest", {
get: function() {
if(vm.selectedMacroOption && vm.deficitCalories_rest) {
return formatCalNumber(vm.selectedMacroOption.getFatMacros(vm.deficitCalories_rest));
}
return '';
}
});
Object.defineProperty(vm, "macrosCarbs_rest", {
get: function() {
// the rest from carbs
if(vm.deficitCalories_rest) {
return formatCalNumber(kinobodyProgramData.calculateCarbMacros_default(vm.macrosProtein_rest, vm.macrosFats_rest, vm.deficitCalories_rest));
}
return '';
}
});
Object.defineProperty(vm, "percentageProtein_rest", {
get: function() {
if(vm.macrosProtein) {
var calsFats = vm.macrosProtein_rest * 4;
var p = calsFats / vm.deficitCalories_rest * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "percentageFats_rest", {
get: function() {
if(vm.macrosFats) {
var calsFats = vm.macrosFats_rest * 9;
var p = calsFats / vm.deficitCalories_rest * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "percentageCarbs_rest", {
get: function() {
if(vm.macrosCarbs) {
var calsCarbs = vm.macrosCarbs_rest * 4;
var p = calsCarbs / vm.deficitCalories_rest * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "crossCheckCalories_rest", {
get: function() {
if(vm.macrosProtein_rest && vm.macrosFats_rest && vm.macrosCarbs_rest) {
var calsProtein = vm.macrosProtein_rest * 4;
var calsFats = vm.macrosFats_rest * 9;
var calsCarbs = vm.macrosCarbs_rest * 4;
return formatCalNumber(calsProtein + calsFats + calsCarbs);
}
return '';
}
});
//--------------------------------------------------------------------------
// refeed days
//--------------------------------------------------------------------------
Object.defineProperty(vm, "macroSectionLabel_refeed", {
get: function() {
var label = 'Refeed days calories / macros';
if (vm.selectedProgramSubOption.refeedDayTitle) {
label = vm.selectedProgramSubOption.refeedDayTitle;
}
return label;
}
});
Object.defineProperty(vm, "dailyCaloriesLabel_refeed", {
get: function() {
if (vm.hasRefeedDaySubOption) {
var label = 'Calories '
+ '(lbs x ' + vm.refeedDaySubOption.lbsFactor + ')';
if(vm.refeedDaySubOption.refeedDaysCaloriesOffset && vm.refeedDaySubOption.refeedDaysCaloriesOffset !== 0) {
label += ' ' + ((vm.refeedDaySubOption.refeedDaysCaloriesOffset > 0) ? '+' : '-')
+ ' ' + vm.refeedDaySubOption.refeedDaysCaloriesOffset;
}
return label;
}
return '';
}
});
Object.defineProperty(vm, "kinobodyEstimateDailyCalories_refeed", {
get: function() {
if (vm.hasRefeedDaySubOption) {
if(vm.weightLbs) {
var offset = (vm.refeedDaySubOption.refeedDaysCaloriesOffset && vm.refeedDaySubOption.refeedDaysCaloriesOffset !== 0)
? vm.refeedDaySubOption.refeedDaysCaloriesOffset
: 0;
return (vm.refeedDaySubOption.lbsFactor * vm.weightLbs) + offset + vm.kcalOffset_number;
}
}
return '';
}
});
Object.defineProperty(vm, "kinobodyEstimateDailyCalories_refeed_display", {
get: function() {
if (vm.hasRefeedDaySubOption) {
if(vm.kinobodyEstimateDailyCalories_refeed) {
return formatCalNumber(vm.kinobodyEstimateDailyCalories_refeed);
}
}
return '';
}
});
Object.defineProperty(vm, "deficitCalories_refeed", {
get: function() {
if(vm.kinobodyEstimateDailyCalories_refeed) {
return formatCalNumber(vm.kinobodyEstimateDailyCalories_refeed);
}
return '';
}
});
Object.defineProperty(vm, "selectedRefeedMacroOption", {
get: function() {
if (vm.hasRefeedDaySubOption) {
return vm.refeedDaySubOption.macroOptionSet[0]; // only one possible at the moment!
}
return '';
}
});
Object.defineProperty(vm, "macrosProtein_refeed", {
get: function() {
if(vm.selectedRefeedMacroOption && vm.deficitCalories_refeed) {
return formatCalNumber(vm.selectedRefeedMacroOption.getProteinMacros(vm.deficitCalories_refeed, vm.weightKg, vm.weightLbs));
}
return '';
}
});
Object.defineProperty(vm, "macrosFats_refeed", {
get: function() {
if(vm.selectedRefeedMacroOption && vm.deficitCalories_refeed) {
return formatCalNumber(vm.selectedRefeedMacroOption.getFatMacros(vm.deficitCalories_refeed));
}
return '';
}
});
Object.defineProperty(vm, "macrosCarbs_refeed", {
get: function() {
// the rest from carbs
if(vm.deficitCalories_refeed) {
return formatCalNumber(kinobodyProgramData.calculateCarbMacros_default(vm.macrosProtein_refeed, vm.macrosFats_refeed, vm.deficitCalories_refeed));
}
return '';
}
});
Object.defineProperty(vm, "percentageProtein_refeed", {
get: function() {
if(vm.macrosProtein_refeed) {
var calsFats = vm.macrosProtein_refeed * 4;
var p = calsFats / vm.deficitCalories_refeed * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "percentageFats_refeed", {
get: function() {
if(vm.macrosFats_refeed) {
var calsFats = vm.macrosFats_refeed * 9;
var p = calsFats / vm.deficitCalories_refeed * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "percentageCarbs_refeed", {
get: function() {
if(vm.macrosCarbs_refeed) {
var calsCarbs = vm.macrosCarbs_refeed * 4;
var p = calsCarbs / vm.deficitCalories_refeed * 100;
return formatCalNumber(p);
}
return '';
}
});
Object.defineProperty(vm, "crossCheckCalories_refeed", {
get: function() {
if(vm.macrosProtein_refeed && vm.macrosFats_refeed && vm.macrosCarbs_refeed) {
var calsProtein = vm.macrosProtein_refeed * 4;
var calsFats = vm.macrosFats_refeed * 9;
var calsCarbs = vm.macrosCarbs_refeed * 4;
return formatCalNumber(calsProtein + calsFats + calsCarbs);
}
return '';
}
});
//--------------------------------------------------------------------------
vm.formatCalNumber = formatCalNumber;
vm.toggleInputUnitsWeight = toggleInputUnitsWeight;
vm.onWeightChange = onWeightChange;
vm.onKcalOffsetChange = onKcalOffsetChange;
vm.onProgramOptionChange = onProgramOptionChange;
vm.onProgramSubOptionChange = onProgramSubOptionChange;
vm.onMacroOptionChange = onMacroOptionChange;
vm.resetForm = resetForm;
vm.onClipboardSuccess = onClipboardSuccess;
vm.onClipboardFail = onClipboardFail;
function onClipboardSuccess() {
ngToast.create("Address copied to clipboard");
// $log.log('onClipboardSuccess');
}
function onClipboardFail(err) {
$log.log('onClipboardFail', err);
}
function onWeightChange() {
updateRoute();
}
function onKcalOffsetChange() {
if(canBeNumber(vm.kcalOffset)) {
vm.kcalOffset = Number(vm.kcalOffset);
}
vm.kcalOffsetActive = true;
updateRoute();
}
function onProgramOptionChange() {
$log.log('onProgramOptionChange');
if(vm.activeProgramSubOptionSet !== vm.selectedProgram.programSubOptionSet) {
vm.activeProgramSubOptionSet = vm.selectedProgram.programSubOptionSet;
}
if(!!!vm.selectedProgram.prevSelectedProgramSubOption) {
//$log.log('onProgramOptionChange AAA');
vm.selectedProgramSubOption = vm.selectedProgram.programSubOptionSet[vm.selectedProgram.defaultProgramSubOptionIndex];
} else {
//$log.log('onProgramOptionChange BBB');
vm.selectedProgramSubOption = vm.selectedProgram.prevSelectedProgramSubOption;
}
onProgramSubOptionChange();
//updateRoute();
}
function onProgramSubOptionChange() {
$log.log('onProgramSubOptionChange');
vm.selectedProgram.prevSelectedProgramSubOption = vm.selectedProgramSubOption;
vm.activeMacroOptionSet = vm.selectedProgramSubOption.macroOptionSet;
//vm.selectedMacroOption = vm.activeMacroOptionSet[vm.selectedProgramSubOption.defaultMacroOptionIndex];
if(!!!vm.selectedProgramSubOption.prevSelectedMacroOption) {
//$log.log('onProgramSubOptionChange CCC');
vm.selectedMacroOption = vm.activeMacroOptionSet[vm.selectedProgramSubOption.defaultMacroOptionIndex];
} else {
//$log.log('onProgramSubOptionChange DDD');
vm.selectedMacroOption = vm.selectedProgramSubOption.prevSelectedMacroOption;
}
onMacroOptionChange();
//updateRoute();
}
function onMacroOptionChange() {
//$log.log('onMacroOptionChange EEE');
vm.selectedProgramSubOption.prevSelectedMacroOption = vm.selectedMacroOption;
updateRoute();
}
function resetForm() {
vm.inputWeight = '';
vm.kcalOffset = 0;
$state.go('reset', {}, { notify: true });
}
function updateRoute() {
if(!initialized || vm.inputWeight === '')
return;
$log.log('updateRoute XXX');
// $log.log('updateRoute', vm.storage, $location, $location.absUrl());
var stateOptions = {
programName: vm.selectedProgram.routing_name,
programSubOptionName: vm.selectedProgramSubOption.routing_name,
macrosOptionName: vm.selectedMacroOption.routing_name,
weight: vm.inputWeight,
weightUnits: vm.inputUnitsWeight,
};
if(vm.kcalOffset_number !== 0 || vm.kcalOffsetActive) {
stateOptions.kcalOffset = vm.kcalOffset_number;
}
$log.log('updateRoute', stateOptions);
$state.transitionTo('home', stateOptions, { notify: false });
}
function canBeNumber(i) {
if(_.isNumber(i)) {
return true;
}
if(Number.isNaN(Number(i))) {
return false;
}
return true;
}
function makeNumber(i) {
return Number(i);
}
function formatCalNumber(i) {
if(i === '' || !canBeNumber(i)) {
return '';
}
return Number(i).toFixed(0);
}
function toggleInputUnitsWeight() {
// $log.log('toggleInputUnitsWeight');
switch(vm.inputUnitsWeight){
case 'kg':
// LBS
vm.inputUnitsWeight = 'lbs';
vm.inputWeight = vm.inputWeight * _kgToPoundRatio;
break;
case 'lbs':
// KG
vm.inputUnitsWeight = 'kg';
vm.inputWeight = vm.inputWeight / _kgToPoundRatio;
break;
}
updateRoute();
}
function convertInputWeightToKg(inputWeight) {
if(vm.inputUnitsWeight === 'kg') {
return inputWeight;
} else {
return inputWeight / _kgToPoundRatio;
}
}
// state change event handler
$scope.$on("$stateChangeStart",
function (event, toState, toParams, fromState, fromParams) {
$log.log('$stateChangeStart', $location);
$log.log(' event', event);
$log.log(' toParams', toParams);
processStateParams(toParams);
}
);
init();
}
})();
Kinobody Calories / Macros
- Kinobody easy formulas for maintenance/deficit calculations
- Creates url that can be forum-posted:
http://run.plnkr.co/plunks/p1p1tI/#/kinobody_ggp/afl_nutrition/macros_35p_30f_35c/165_lbs
http://run.plnkr.co/plunks/p1p1tI/#/kinobody_ggp/lean_bulk/macros_1p_25f/73_kg?kcalOffset=200
Todo:
- verify everything is correct
- add routing again
- reorganize code (move "data" into own module)
Bugs:
-
Useful links for this plunk:
https://github.com/omichelsen/angular-clipboard
http://tamerayd.in/ngToast/
https://www.niclassahlin.com/2014/05/31/kickstarting-angular-ui-router/
http://www.metric-conversions.org/length/centimeters-to-inches.htm
http://www.metric-conversions.org/weight/kilograms-to-pounds.htm
https://github.com/gsklee/ngStorage
https://scotch.io/tutorials/the-many-ways-to-use-ngclass
// fix enter key strange behaviour:
http://stackoverflow.com/a/11591419/54159 : Just add the type="button" attribute to the button element, some browsers interpret the type as submit by default.
http://stackoverflow.com/questions/10400149/avoid-modal-dismiss-on-enter-keypress
https://gist.github.com/demisx/9605099
http://benfoster.io/blog/ui-router-optional-parameters
(function (root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define(['angular'], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require('angular'));
} else {
root.angularClipboard = factory(root.angular);
}
}(this, function (angular) {
return angular.module('angular-clipboard', [])
.factory('clipboard', ['$document', function ($document) {
function createNode(text) {
var node = $document[0].createElement('textarea');
node.style.position = 'absolute';
node.style.left = '-10000px';
node.textContent = text;
return node;
}
function copyNode(node) {
try {
// Set inline style to override css styles
$document[0].body.style.webkitUserSelect = 'initial';
var selection = $document[0].getSelection();
selection.removeAllRanges();
node.select();
if(!$document[0].execCommand('copy')) {
throw('failure copy');
}
selection.removeAllRanges();
} finally {
// Reset inline style
$document[0].body.style.webkitUserSelect = '';
}
}
function copyText(text) {
var node = createNode(text);
$document[0].body.appendChild(node);
copyNode(node);
$document[0].body.removeChild(node);
}
return {
copyText: copyText,
supported: 'queryCommandSupported' in document && document.queryCommandSupported('copy')
};
}])
.directive('clipboard', ['clipboard', function (clipboard) {
return {
restrict: 'A',
scope: {
onCopied: '&',
onError: '&',
text: '=',
supported: '='
},
link: function (scope, element) {
scope.supported = clipboard.supported;
element.on('click', function (event) {
try {
clipboard.copyText(scope.text);
if (angular.isFunction(scope.onCopied)) {
scope.$evalAsync(scope.onCopied());
}
} catch (err) {
if (angular.isFunction(scope.onError)) {
scope.$evalAsync(scope.onError({err: err}));
}
}
});
}
};
}]);
}));
(function kinobodyProgramDataServiceIIFE() {
'use strict';
var factoryId = 'kinobodyProgramData';
var app = angular.module('app');
app.factory(factoryId, ['$log', KinobodyProgramData]);
function KinobodyProgramData($log) {
var service = {};
service.getKinobodyPrograms = getKinobodyPrograms;
service.getKinobodyMaintenanceFactor = getKinobodyMaintenanceFactor;
service.calculateProteinMacros_default = calculateProteinMacros_default;
service.calculateFatMacros_default = calculateFatMacros_default;
service.calculateCarbMacros_default = calculateCarbMacros_default;
//-----------------------------------------------------------------
// program specific defaults
//-----------------------------------------------------------------
var _kinobodyMaintenanceFactor = 15;
var _AflDefaultLbsFactor = 11;
var _AflDefaultRefeedDayLbsFactor = _kinobodyMaintenanceFactor;
var _WspDefaultLbsFactor = 12;
var _WspDefaultRefeedDayLbsFactor = _kinobodyMaintenanceFactor;
var _GtpDefaultLbsFactor = 12;
var _GtpDefaultRefeedDayLbsFactor = _GtpDefaultLbsFactor;
var _SbpDefaultUnderfeedDayLbsFactor = _kinobodyMaintenanceFactor;
var _AflDefaultMacroOptionSet = [
{
routing_name: 'macros_35p_30f_35c',
name: '35% protein, 30% fat, 35% carbs (default)',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.35);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
},
{
routing_name: 'macros_35p_25f_40c',
name: '35% protein, 25% fat, 40% carbs',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.35);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
},
{
routing_name: 'macros_30p_30f_40c',
name: '30% protein, 30% fat, 40% carbs',
getProteinMacros: function(calories, weightKg, weightLbs) {
return calculateProteinMacros_default(calories, 0.30);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
},
];
var _WspDefaultMacroOptionSet = [
{
routing_name: 'macros_30p_30f_40c',
name: '30% protein, 30% fat, 40% carbs (default)',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.30);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
},
];
var _GgpDefaultMacroOptionSet = [
{
routing_name: 'macros_09p_25f',
name: 'Default protein (0.9 g/lbs, 2 g/kg)',
getProteinMacros: function(calories, weightKg, weightLbs) {
return 2 * weightKg;
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
},
{
routing_name: 'macros_08p_25f',
name: 'Less protein (0.8 g/lb)',
getProteinMacros: function(calories, weightKg, weightLbs) {
return 0.8 * weightLbs;
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
},
{
routing_name: 'macros_1p_25f',
name: 'More protein (1 g/lb)',
getProteinMacros: function(calories, weightKg, weightLbs) {
return 1 * weightLbs;
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
},
{
routing_name: 'macros_30p_30f_40c',
name: '30% protein, 30% fat, 40% carbs',
getProteinMacros: function(calories, weightKg, weightLbs) {
return calculateProteinMacros_default(calories, 0.30);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
},
];
var _SbpDefaultMacroOptionSet = [
{
routing_name: 'macros_25p_30f_45c',
name: '25% protein, 30% fat, 45% carbs (default)',
getProteinMacros: function(calories, weightKg, weightLbs) {
return calculateProteinMacros_default(calories, 0.25);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
},
{
routing_name: 'macros_30p_30f_40c',
name: '30% protein, 30% fat, 40% carbs',
getProteinMacros: function(calories, weightKg, weightLbs) {
return calculateProteinMacros_default(calories, 0.30);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
}
];
var _GtpDefaultMacroOptionSet = [
{
routing_name: 'macros_35p_25f_40c',
name: '35% protein, 25% fat, 40% carbs',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.35);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
},
{
routing_name: 'macros_35p_27f_38c',
name: '35% protein, 27.5% fat, 37.5% carbs (default)',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.35);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.275);
},
},
{
routing_name: 'macros_35p_30f_35c',
name: '35% protein, 30% fat, 35% carbs',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.35);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
},
{
routing_name: 'macros_30p_30f_40c',
name: '30% protein, 30% fat, 40% carbs',
getProteinMacros: function(calories, weightKg, weightLbs) {
return calculateProteinMacros_default(calories, 0.30);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.30);
},
},
];
var _AflDefaultRefeedDaySubOption = {
routing_name: 'refeed_sub_option',
name: 'refeed_sub_option',
lbsFactor: _AflDefaultRefeedDayLbsFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: [
{
routing_name: 'refeed_default_macros',
name: 'refeed_default_macros',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.25);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
}
],
};
var _WspDefaultRefeedDaySubOption = {
routing_name: 'refeed_sub_option',
name: 'refeed_sub_option',
lbsFactor: _WspDefaultRefeedDayLbsFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: [
{
routing_name: 'refeed_default_macros',
name: 'refeed_default_macros',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.25);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
}
],
};
var _SbpDefaultUnderfeedDaySubOption = {
routing_name: 'underfeed_sub_option',
name: 'underfeed_sub_option',
lbsFactor: _SbpDefaultUnderfeedDayLbsFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: [
{
routing_name: 'underfeed_default_macros',
name: 'underfeed_default_macros',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.25);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
}
],
};
var _GtpDefaultRefeedDaySubOption = {
routing_name: 'refeed_sub_option',
name: 'refeed_sub_option',
lbsFactor: _GtpDefaultRefeedDayLbsFactor,
defaultMacroOptionIndex: 0,
refeedDaysCaloriesOffset: 600,
macroOptionSet: [
{
routing_name: 'refeed_default_macros',
name: 'refeed_default_macros',
getProteinMacros: function(calories) {
return calculateProteinMacros_default(calories, 0.25);
},
getFatMacros: function(calories) {
return calculateFatMacros_default(calories, 0.25);
},
}
],
};
//-----------------------------------------------------------------
// Kinobody Program Configs
//-----------------------------------------------------------------
var kinobodyPrograms = [
{
routing_name: 'kinobody_afl',
name: 'Kinobody AFL',
description: 'Aggressive Fat Loss',
programSubOptionSet: [
{
routing_name: 'default',
name: 'Default',
lbsFactor: _AflDefaultLbsFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: _AflDefaultMacroOptionSet,
isGoalBodyWeightRequired: true,
goalNotes: [
{ text: 'Adjust goal weight in 20 lbs decrements' },
{ text: 'For example, if current body weight is 200 lbs, use goal weight 180 lbs; when reaching that, use 160 lbs, etc.' },
],
hasRefeedDaySubOption: true,
refeedDaySubOption: _AflDefaultRefeedDaySubOption,
refeedDayNotes: [
{ text: 'One refeed day per week' },
],
},
],
defaultProgramSubOptionIndex: 0,
},
{
routing_name: 'kinobody_wsp',
name: 'Kinobody WSP',
description: 'Warrior Shredding Program',
programSubOptionSet: [
{
routing_name: 'default',
name: 'Default',
lbsFactor: _WspDefaultLbsFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: _WspDefaultMacroOptionSet,
isBodyWeightOrGoalBodyWeightRequired: true,
goalNotes: [
{ text: 'If you have 15 lbs / 7 kg or less to lose, use body weight' },
{ text: 'If you have more than 15 lbs / 7 kg to lose, use GOAL body weight' },
],
hasRefeedDaySubOption: true,
refeedDaySubOption: _WspDefaultRefeedDaySubOption,
refeedDayNotes: [
{ text: 'Recommendation: 2 refeed days per week,' },
{ text: 'Separated by at least 2 days' },
],
},
],
defaultProgramSubOptionIndex: 0,
},
{
routing_name: 'kinobody_ggp',
name: 'Kinobody GGP',
description: 'Greek God Program',
programSubOptionSet: [
{
routing_name: 'lean_bulk',
name: 'Lean Bulk',
lbsFactor: _kinobodyMaintenanceFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: _GgpDefaultMacroOptionSet,
hasTrainingRestDaysSplit: true,
trainingDaysCaloriesOffset: 500,
restDaysCaloriesOffset: 100,
},
{
routing_name: 'recomp',
name: 'Recomp',
lbsFactor: _kinobodyMaintenanceFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: _GgpDefaultMacroOptionSet,
hasTrainingRestDaysSplit: true,
trainingDaysCaloriesOffset: 400,
restDaysCaloriesOffset: -300,
},
{
routing_name: 'afl_nutrition',
name: 'AFL Nutrition',
lbsFactor: _AflDefaultLbsFactor,
macroOptionSet: _AflDefaultMacroOptionSet,
defaultMacroOptionIndex: 0,
isGoalBodyWeightRequired: true,
goalNotes: [
{ text: 'Adjust goal weight in 20 lbs decrements' },
{ text: 'For example, if current body weight is 200 lbs, use goal weight 180 lbs; when reaching that, use 160 lbs, etc.' },
],
hasRefeedDaySubOption: true,
refeedDaySubOption: _AflDefaultRefeedDaySubOption,
refeedDayNotes: [
{ text: 'One refeed day per week' },
],
},
],
defaultProgramSubOptionIndex: 0,
},
{
routing_name: 'kinobody_sbp',
name: 'Kinobody SPB',
description: 'Superhero Bulking Program',
programSubOptionSet: [
{
routing_name: 'default',
name: 'default',
lbsFactor: _kinobodyMaintenanceFactor,
defaultMacroOptionIndex: 0,
macroOptionSet: _SbpDefaultMacroOptionSet,
hasFixedCaloriesOffset: true,
fixedCaloriesOffset: 300,
hasRefeedDaySubOption: true,
refeedDayTitle: 'Underfeed days calories / macros',
refeedDaySubOption: _SbpDefaultUnderfeedDaySubOption,
refeedDayNotes: [
{ text: 'Recommendation: 1 or 2 underfeed days per week' },
//{ text: 'Separated by at least 2 days' },
],
},
],
defaultProgramSubOptionIndex: 0,
},
{
routing_name: 'kinobody_gtp',
name: 'Kinobody GTP',
description: 'Goddess Toning Program',
programSubOptionSet: [
{
routing_name: 'default',
name: 'GTP Nutrition (default)',
lbsFactor: _GtpDefaultLbsFactor,
defaultMacroOptionIndex: 1,
macroOptionSet: _GtpDefaultMacroOptionSet,
hasRefeedDaySubOption: true,
refeedDaySubOption: _GtpDefaultRefeedDaySubOption,
refeedDayNotes: [
{ text: 'Recommendation: One refeed day per week' },
],
},
{
routing_name: 'afl_nutrition_10',
name: 'AFL Nutrition (11 calories / lb)',
lbsFactor: 11,
defaultMacroOptionIndex: 0,
macroOptionSet: _AflDefaultMacroOptionSet,
isGoalBodyWeightRequired: true,
hasRefeedDaySubOption: true,
refeedDaySubOption: _GtpDefaultRefeedDaySubOption,
refeedDayNotes: [
{ text: 'Recommendation: One refeed day per week' },
],
},
{
routing_name: 'afl_nutrition_10',
name: 'AFL Nutrition (10 calories / lb)',
lbsFactor: 10,
defaultMacroOptionIndex: 0,
macroOptionSet: _AflDefaultMacroOptionSet,
isGoalBodyWeightRequired: true,
hasRefeedDaySubOption: true,
refeedDaySubOption: _GtpDefaultRefeedDaySubOption,
refeedDayNotes: [
{ text: 'Recommendation: One refeed day per week' },
],
},
],
defaultProgramSubOptionIndex: 0,
},
];
//-----------------------------------------------------------------
// public
//-----------------------------------------------------------------
function getKinobodyPrograms() {
return kinobodyPrograms;
}
function getKinobodyMaintenanceFactor() {
return _kinobodyMaintenanceFactor;
}
function calculateProteinMacros_default(calories, percentageValue) {
//return roundToNearestX(percentageValue * calories / 4, 5);
return percentageValue * calories / 4;
}
function calculateFatMacros_default(calories, percentageValue) {
return percentageValue * calories / 9;
}
function calculateCarbMacros_default(macrosProtein, macrosFats, deficitCalories) {
// rest carbs
var carbGrams = 0;
var calsProtein = macrosProtein * 4;
var calsFats = macrosFats * 9;
var calsPF = calsProtein + calsFats;
var calsCarbs = deficitCalories - calsPF;
carbGrams = calsCarbs / 4;
// $log.log('carbGrams', carbGrams);
return carbGrams;
}
//-----------------------------------------------------------------
// private
//-----------------------------------------------------------------
function roundToNearestX(val, x) {
return Math.ceil(val/x)*x;
}
return service;
}
})();