<commit_before>/**
 * This plugin overrides jQuery's height() and width() functions and
 * adds more handy stuff for cross-browser compatibility.
 */

/**
 * Returns the css height value for the first matched element.
 * If used on document, returns the document's height (innerHeight)
 * If used on window, returns the viewport's (window) height
 *
 * @example $("#testdiv").height()
 * @result "200px"
 *
 * @example $(document).height();
 * @result 800
 *
 * @example $(window).height();
 * @result 400
 *
 * @name height
 * @type Object
 * @cat Dimensions
 */
$.fn.height = function() {
	if ( this.get(0) == window )
		return self.innerHeight ||
			jQuery.boxModel && document.documentElement.clientHeight ||
			document.body.clientHeight;

	if ( this.get(0) == document )
		return Math.max( document.body.scrollHeight, document.body.offsetHeight );

	return this.css("height");
};

/**
 * Returns the css width value for the first matched element.
 * If used on document, returns the document's width (innerWidth)
 * If used on window, returns the viewport's (window) width
 *
 * @example $("#testdiv").width()
 * @result "200px"
 *
 * @example $(document).width();
 * @result 800
 *
 * @example $(window).width();
 * @result 400
 *
 * @name width
 * @type Object
 * @cat Dimensions
 */
$.fn.width = function() {
	if ( this.get(0) == window )
		return self.innerWidth ||
			jQuery.boxModel && document.documentElement.clientWidth ||
			document.body.clientWidth;

	if ( this.get(0) == document )
		return Math.max( document.body.scrollWidth, document.body.offsetWidth );

	return this.css("width");
};

/**
 * Returns the inner height value (without border) for the first matched element.
 * If used on document, returns the document's height (innerHeight)
 * If used on window, returns the viewport's (window) height
 *
 * @example $("#testdiv").innerHeight()
 * @result 800
 *
 * @name innerHeight
 * @type Number
 * @cat Dimensions
 */
$.fn.innerHeight = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.height() :
		this.get(0).offsetHeight - parseInt(this.css("borderTop") || 0) - parseInt(this.css("borderBottom") || 0);
};

/**
 * Returns the inner width value (without border) for the first matched element.
 * If used on document, returns the document's Width (innerWidth)
 * If used on window, returns the viewport's (window) width
 *
 * @example $("#testdiv").innerWidth()
 * @result 1000
 *
 * @name innerWidth
 * @type Number
 * @cat Dimensions
 */
$.fn.innerWidth = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.width() :
		this.get(0).offsetWidth - parseInt(this.css("borderLeft") || 0) - parseInt(this.css("borderRight") || 0);
};

/**
 * Returns the outer height value (including border) for the first matched element.
 * Cannot be used on document or window.
 *
 * @example $("#testdiv").outerHeight()
 * @result 1000
 *
 * @name outerHeight
 * @type Number
 * @cat Dimensions
 */
$.fn.outerHeight = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.height() :
		this.get(0).offsetHeight;
};

/**
 * Returns the outer width value (including border) for the first matched element.
 * Cannot be used on document or window.
 *
 * @example $("#testdiv").outerWidth()
 * @result 1000
 *
 * @name outerWidth
 * @type Number
 * @cat Dimensions
 */
$.fn.outerWidth = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.width() :
		this.get(0).offsetWidth;
};

/**
 * Returns how many pixels the user has scrolled to the right (scrollLeft).
 * Works on containers with overflow: auto and window/document.
 *
 * @example $("#testdiv").scrollLeft()
 * @result 100
 *
 * @name scrollLeft
 * @type Number
 * @cat Dimensions
 */
$.fn.scrollLeft = function() {
	if ( this.get(0) == window || this.get(0) == document )
		return self.pageXOffset ||
			jQuery.boxModel && document.documentElement.scrollLeft ||
			document.body.scrollLeft;

	return this.get(0).scrollLeft;
};

/**
 * Returns how many pixels the user has scrolled to the bottom (scrollTop).
 * Works on containers with overflow: auto and window/document.
 *
 * @example $("#testdiv").scrollTop()
 * @result 100
 *
 * @name scrollTop
 * @type Number
 * @cat Dimensions
 */
$.fn.scrollTop = function() {
	if ( this.get(0) == window || this.get(0) == document )
		return self.pageYOffset ||
			jQuery.boxModel && document.documentElement.scrollTop ||
			document.body.scrollTop;

	return this.get(0).scrollTop;
};<commit_msg>added Brandon's offset function<commit_after>/**
 * This plugin overrides jQuery's height() and width() functions and
 * adds more handy stuff for cross-browser compatibility.
 */

/**
 * Returns the css height value for the first matched element.
 * If used on document, returns the document's height (innerHeight)
 * If used on window, returns the viewport's (window) height
 *
 * @example $("#testdiv").height()
 * @result "200px"
 *
 * @example $(document).height();
 * @result 800
 *
 * @example $(window).height();
 * @result 400
 *
 * @name height
 * @type Object
 * @cat Dimensions
 */
$.fn.height = function() {
	if ( this.get(0) == window )
		return self.innerHeight ||
			jQuery.boxModel && document.documentElement.clientHeight ||
			document.body.clientHeight;

	if ( this.get(0) == document )
		return Math.max( document.body.scrollHeight, document.body.offsetHeight );

	return this.css("height");
};

/**
 * Returns the css width value for the first matched element.
 * If used on document, returns the document's width (innerWidth)
 * If used on window, returns the viewport's (window) width
 *
 * @example $("#testdiv").width()
 * @result "200px"
 *
 * @example $(document).width();
 * @result 800
 *
 * @example $(window).width();
 * @result 400
 *
 * @name width
 * @type Object
 * @cat Dimensions
 */
$.fn.width = function() {
	if ( this.get(0) == window )
		return self.innerWidth ||
			jQuery.boxModel && document.documentElement.clientWidth ||
			document.body.clientWidth;

	if ( this.get(0) == document )
		return Math.max( document.body.scrollWidth, document.body.offsetWidth );

	return this.css("width");
};

/**
 * Returns the inner height value (without border) for the first matched element.
 * If used on document, returns the document's height (innerHeight)
 * If used on window, returns the viewport's (window) height
 *
 * @example $("#testdiv").innerHeight()
 * @result 800
 *
 * @name innerHeight
 * @type Number
 * @cat Dimensions
 */
$.fn.innerHeight = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.height() :
		this.get(0).offsetHeight - parseInt(this.css("borderTop") || 0) - parseInt(this.css("borderBottom") || 0);
};

/**
 * Returns the inner width value (without border) for the first matched element.
 * If used on document, returns the document's Width (innerWidth)
 * If used on window, returns the viewport's (window) width
 *
 * @example $("#testdiv").innerWidth()
 * @result 1000
 *
 * @name innerWidth
 * @type Number
 * @cat Dimensions
 */
$.fn.innerWidth = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.width() :
		this.get(0).offsetWidth - parseInt(this.css("borderLeft") || 0) - parseInt(this.css("borderRight") || 0);
};

/**
 * Returns the outer height value (including border) for the first matched element.
 * Cannot be used on document or window.
 *
 * @example $("#testdiv").outerHeight()
 * @result 1000
 *
 * @name outerHeight
 * @type Number
 * @cat Dimensions
 */
$.fn.outerHeight = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.height() :
		this.get(0).offsetHeight;
};

/**
 * Returns the outer width value (including border) for the first matched element.
 * Cannot be used on document or window.
 *
 * @example $("#testdiv").outerWidth()
 * @result 1000
 *
 * @name outerWidth
 * @type Number
 * @cat Dimensions
 */
$.fn.outerWidth = function() {
	return this.get(0) == window || this.get(0) == document ?
		this.width() :
		this.get(0).offsetWidth;
};

/**
 * Returns how many pixels the user has scrolled to the right (scrollLeft).
 * Works on containers with overflow: auto and window/document.
 *
 * @example $("#testdiv").scrollLeft()
 * @result 100
 *
 * @name scrollLeft
 * @type Number
 * @cat Dimensions
 */
$.fn.scrollLeft = function() {
	if ( this.get(0) == window || this.get(0) == document )
		return self.pageXOffset ||
			jQuery.boxModel && document.documentElement.scrollLeft ||
			document.body.scrollLeft;

	return this.get(0).scrollLeft;
};

/**
 * Returns how many pixels the user has scrolled to the bottom (scrollTop).
 * Works on containers with overflow: auto and window/document.
 *
 * @example $("#testdiv").scrollTop()
 * @result 100
 *
 * @name scrollTop
 * @type Number
 * @cat Dimensions
 */
$.fn.scrollTop = function() {
	if ( this.get(0) == window || this.get(0) == document )
		return self.pageYOffset ||
			jQuery.boxModel && document.documentElement.scrollTop ||
			document.body.scrollTop;

	return this.get(0).scrollTop;
};

/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 */

/**
 * This returns an object with top, left, width, height, borderLeft,
 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop,
 * pageXOffset, pageYOffset.
 *
 * The top and left values include the scroll offsets but the
 * scrollLeft and scrollTop properties of the returned object
 * are the combined scroll offets of the parent elements
 * (not including the window scroll offsets). This is not the
 * same as the element's scrollTop and scrollLeft.
 *
 * For accurate readings make sure to use pixel values.
 *
 * @name offset
 * @type Object
 * @cat Dimensions
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
/**
 * This returns an object with top, left, width, height, borderLeft,
 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop,
 * pageXOffset, pageYOffset.
 *
 * The top and left values include the scroll offsets but the
 * scrollLeft and scrollTop properties of the returned object
 * are the combined scroll offets of the parent elements
 * (not including the window scroll offsets). This is not the
 * same as the element's scrollTop and scrollLeft.
 *
 * For accurate readings make sure to use pixel values.
 *
 * @name offset
 * @type Object
 * @param String refElement This is an expression. The offset returned will be relative to the first matched element.
 * @cat Dimensions
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
/**
 * This returns an object with top, left, width, height, borderLeft,
 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop,
 * pageXOffset, pageYOffset.
 *
 * The top and left values include the scroll offsets but the
 * scrollLeft and scrollTop properties of the returned object
 * are the combined scroll offets of the parent elements
 * (not including the window scroll offsets). This is not the
 * same as the element's scrollTop and scrollLeft.
 *
 * For accurate readings make sure to use pixel values.
 *
 * @name offset
 * @type Object
 * @param jQuery refElement The offset returned will be relative to the first matched element.
 * @cat Dimensions
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
/**
 * This returns an object with top, left, width, height, borderLeft,
 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop,
 * pageXOffset, pageYOffset.
 *
 * The top and left values include the scroll offsets but the
 * scrollLeft and scrollTop properties of the returned object
 * are the combined scroll offets of the parent elements
 * (not including the window scroll offsets). This is not the
 * same as the element's scrollTop and scrollLeft.
 *
 * For accurate readings make sure to use pixel values.
 *
 * @name offset
 * @type Object
 * @param HTMLElement refElement The offset returned will be relative to this element.
 * @cat Dimensions
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
$.fn.offset = function(refElem) {
	if (!this[0]) throw '$.fn.offset requires an element.';

	refElem = (refElem) ? $(refElem)[0] : null;
	var x = 0, y = 0, elm = this[0], parent = this[0], pos = null, borders = [0,0], isElm = true, sl = 0, st = 0;
	do {
		if (parent.tagName == 'BODY' || parent.tagName == 'HTML') {
			// Safari and IE don't add margin for static and relative
			if (($.browser.safari || $.browser.msie) && pos != 'absolute') {
				x += parseInt($.css(parent, 'marginLeft')) || 0;
				y += parseInt($.css(parent, 'marginTop'))  || 0;
			}
			break;
		}

		pos    = $.css(parent, 'position');
		border = [parseInt($.css(parent, 'borderLeftWidth')) || 0,
							parseInt($.css(parent, 'borderTopWidth'))  || 0];
		sl = parent.scrollLeft;
		st = parent.scrollTop;

		x += (parent.offsetLeft || 0) + border[0] - sl;
		y += (parent.offsetTop  || 0) + border[1] - st;

		// Safari and Opera include the border already for parents with position = absolute|relative
		if (($.browser.safari || $.browser.opera) && !isElm && (pos == 'absolute' || pos == 'relative')) {
			x -= border[0];
			y -= border[1];
		}

		parent = parent.offsetParent;
		isElm  = false;
	} while(parent);

	if (refElem) {
		var offset = $(refElem).offset();
		x  = x  - offset.left;
		y  = y  - offset.top;
		sl = sl - offset.scrollLeft;
		st = st - offset.scrollTop;
	}

	return {
		top:  y,
		left: x,
		width:  elm.offsetWidth,
		height: elm.offsetHeight,
		borderTop:  parseInt($.css(elm, 'borderTopWidth'))  || 0,
		borderLeft: parseInt($.css(elm, 'borderLeftWidth')) || 0,
		marginTop:  parseInt($.css(elm, 'marginTopWidth'))  || 0,
		marginLeft: parseInt($.css(elm, 'marginLeftWidth')) || 0,
		scrollTop:  st,
		scrollLeft: sl,
		pageYOffset: window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop  || 0,
		pageXOffset: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0
	};
};<|endoftext|>


<commit_before>(function() {
    'use strict';

    angular.module('app')
        .directive('textWidget', ['$parse', '$compile', 'Lang', 'Connector', function($parse, $compile, Lang, Connector) {
            return {
                link: function(scope, element, attrs) {
                    element.removeAttr('text-widget');
                    element[0].innerHTML =  "

{{item.label}}
<svg class='text-widget'>"+
                                                "<text style='fill: #000'>{{item.value}}</text>"+
                                            "</svg>
";
                    $compile(element)(scope);
                }
            };
        }])
    .directive('resizeAfterRender', function ($timeout) {
            return {
                restrict: 'A',
                link: function (scope, element, attr) {
                    if (scope.$last)
                    if (scope.$last === true) {
                        $timeout(function (e) {
                            var childs = element[0].parentNode.children;
                            for (var i = 0; i < childs.length; i++) {
                                childs[i].style.display = "";
                                var svg = childs[i].children[1];
                                var text = svg.firstChild;
                                var bbox = text.getBBox();

                               /* var svgns = "http://www.w3.org/2000/svg";
                                var rect = document.createElementNS(svgns, 'rect');
                                rect.setAttributeNS(null, 'x', bbox.x);
                                rect.setAttributeNS(null, 'y', bbox.y);
                                rect.setAttributeNS(null, 'width', bbox.width);
                                rect.setAttributeNS(null, 'height', bbox.height);
                                svg.appendChild(rect);
*/
                                svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));

                            }
                            scope.model.rendered = true;
                        }, 0, false, element);
                    }
                }
            };
        });
})();<commit_msg>font color support in tile view<commit_after>(function() {
    'use strict';

    angular.module('app')
        .directive('textWidget', ['$parse', '$compile', 'Lang', 'Connector', function($parse, $compile, Lang, Connector) {
            return {
                link: function(scope, element, attrs) {
                    element.removeAttr('text-widget');
                    element[0].innerHTML =  "

{{item.label}}
<svg class='text-widget'>"+
                                                "<text style='fill: {{item.color}}'>{{item.value}}</text>"+
                                            "</svg>
";
                    $compile(element)(scope);
                }
            };
        }])
    .directive('resizeAfterRender', function ($timeout) {
            return {
                restrict: 'A',
                link: function (scope, element, attr) {
                    if (scope.$last)
                    if (scope.$last === true) {
                        $timeout(function (e) {
                            var childs = element[0].parentNode.children;
                            for (var i = 0; i < childs.length; i++) {
                                childs[i].style.display = "";
                                var svg = childs[i].children[1];
                                var text = svg.firstChild;
                                var bbox = text.getBBox();

                               /* var svgns = "http://www.w3.org/2000/svg";
                                var rect = document.createElementNS(svgns, 'rect');
                                rect.setAttributeNS(null, 'x', bbox.x);
                                rect.setAttributeNS(null, 'y', bbox.y);
                                rect.setAttributeNS(null, 'width', bbox.width);
                                rect.setAttributeNS(null, 'height', bbox.height);
                                svg.appendChild(rect);
*/
                                svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));

                            }
                            scope.model.rendered = true;
                        }, 0, false, element);
                    }
                }
            };
        });
})();<|endoftext|>


<commit_before>'use strict';
const fs = require('fs');
const _ = require('lodash');

fs.readFile('input.txt', 'utf8', (error, contents) => {
  let split = contents.split('\n');
  // pull out the substitutions by filtering on '=>'
  let subs = split.filter(s => s.indexOf('=>') > 0);
  // the last line of the input is the molecule
  let molecule = split[split.length - 1];

  let results = doSubstitutions(molecule, subs);
  console.log(results.length);
});

const doSubstitutions = function(molecule, subs) {
  let results = [];

  subs.forEach(sub => {
    sub = sub.split(' => ');
    let re = new RegExp(sub[0], 'g');
    let indices = [];
    let i = -1;

    while ((i = molecule.indexOf(sub[0], i+1)) >= 0) {
      indices.push(i);
    }

    for (let n = 0; n < indices.length; n++) {
      let begin = molecule.substr(0, indices[n]);
      let rest = molecule.substr(indices[n] + sub[0].length);

      results.push(begin + sub[1] + rest);
    }
  });

  return _.uniq(results);
};
<commit_msg>Solve day 19 part 2<commit_after>'use strict';
const fs = require('fs');
const _ = require('lodash');

fs.readFile('input.txt', 'utf8', (error, contents) => {
  let split = contents.split('\n');
  // pull out the substitutions by filtering on '=>'
  let subs = split.filter(s => s.indexOf('=>') > 0);
  // the last line of the input is the molecule
  let molecule = split[split.length - 1];

  // part 1
  let results = doSubstitutions(molecule, subs);
  console.log('Part 1: ' + results.length);

  // part 2
  countTransformations(molecule);
});

const doSubstitutions = function(molecule, subs) {
  let results = [];

  subs.forEach(sub => {
    sub = sub.split(' => ');
    let re = new RegExp(sub[0], 'g');
    let indices = [];
    let i = -1;

    while ((i = molecule.indexOf(sub[0], i+1)) >= 0) {
      indices.push(i);
    }

    for (let n = 0; n < indices.length; n++) {
      let begin = molecule.substr(0, indices[n]);
      let rest = molecule.substr(indices[n] + sub[0].length);

      results.push(begin + sub[1] + rest);
    }
  });

  return _.uniq(results);
};

/**
I unfortunately can not take credit for these insights about part 2, taken from
https://www.reddit.com/r/adventofcode/comments/3xflz8/day_19_solutions/cy4etju
*/
const countTransformations = function(molecule) {
  // Count of all total elements in the molecule
  let elements = molecule.match(/[A-Z]/g);
  // "Rn" and "Ar" are boundaries of multiple possible transformations,
  // can be thought of as "(" and ")". They are not "real" elements themselves.
  // "Y" is the separator within an "Rn" & "Ar" boundary, similar to a ",".
  let Rns = molecule.match(/Rn/g);
  let Ars = molecule.match(/Ar/g);
  let Ys = molecule.match(/Y/g);

  // So, the minimum possible transformations to create the molecule starting
  // from "e" can be described as: elements - Rns - Ars - 2*Ys - 1
  let transforms = elements.length - Rns.length - Ars.length - (2 * Ys.length) - 1;
  console.log('Minumum transformations required: ' + transforms);
}
<|endoftext|>


<commit_before>angular.module('ot.service.buildfilter', [
    'ot.service.core',
    'ot.service.form'
])
    .service('otBuildFilterService', function (ot, $q, $http, otFormService) {
        var self = {};

        /**
         * Creating a new build filter
         * @param config.branchId ID of the branch
         * @param config.buildFilterForm Build filter form
         * @return Promise with the created filter
         */
        self.createBuildFilter = function (config) {
            var result = {};
            var d = $q.defer();
            otFormService.display({
                title: "New filter",
                form: config.buildFilterForm.form,
                submit: function (filterData) {
                    // Stores locally the filter data if named
                    if (filterData.name) {
                        // TODO self.storeForBranch(config, filterData);
                    }
                    // Stores locally as current
                    self.storeCurrent(config, filterData);
                    // Stores for the reuse
                    result.filterData = filterData;
                    // OK
                    return true;
                }
            }).then(function () {
                d.resolve(result.filterData);
            });
            return d.promise;
        };

        self.storeCurrent = function (config, filterData) {
            localStorage.setItem('build_filter_' + config.branchId + '_current',
                JSON.stringify(filterData)
            );
        };

        return self;
    })
;<commit_msg>Build filter: storing the named filters locally<commit_after>angular.module('ot.service.buildfilter', [
    'ot.service.core',
    'ot.service.form'
])
    .service('otBuildFilterService', function (ot, $q, $http, otFormService) {
        var self = {};

        /**
         * Creating a new build filter
         * @param config.branchId ID of the branch
         * @param config.buildFilterForm Build filter form
         * @return Promise with the created filter
         */
        self.createBuildFilter = function (config) {
            var result = {};
            var d = $q.defer();
            otFormService.display({
                title: "New filter",
                form: config.buildFilterForm.form,
                submit: function (filterData) {
                    // Stores locally the filter data if named
                    if (filterData.name) {
                        self.storeForBranch(config, filterData);
                    }
                    // Stores locally as current
                    self.storeCurrent(config, filterData);
                    // Stores for the reuse
                    result.filterData = filterData;
                    // OK
                    return true;
                }
            }).then(function () {
                d.resolve(result.filterData);
            });
            return d.promise;
        };

        self.storeCurrent = function (config, filterData) {
            localStorage.setItem('build_filter_' + config.branchId + '_current',
                JSON.stringify(filterData)
            );
        };

        self.storeForBranch = function (config, filterData) {
            // Gets the store for this branch
            var store = self.getStoreForBranch(config.branchId);
            // Stores the resource in the store
            store[filterData.name] = {
                name: filterData.name,
                type: config.buildFilterForm.type,
                filter: filterData
            };
            // Saves the store back
            localStorage.setItem(self.getStoreIdForBranch(config.branchId),
                JSON.stringify(store)
            );
        };

        self.getStoreForBranch = function (branchId) {
            var json = localStorage.getItem(self.getStoreIdForBranch(branchId));
            if (json) {
                return JSON.parse(json);
            } else {
                return {};
            }
        };

        self.getStoreIdForBranch = function (branchId) {
            return 'build_filter_' + branchId;
        };

        return self;
    })
;<|endoftext|>


<commit_before>define([
	'jquery',
	'underscore',
	'backbone',
	'x-editable',

	'backendServiceM',
	'chartM'
	],
	function ($, _, Backbone, xEditable, backendServiceM, chartM) {

		var debounceDelay = 100;
		var endsWith = function(str, suffix) { return str.indexOf(suffix, str.length - suffix.length) !== -1; };

		var SituationFormV = Backbone.View.extend({
			el: 'form[name="situation"]',
			events: {
				'change :input': 'onInputChange',
				'click :input.add': 'onAddButtonClicked',
				'click button.simulate': 'onSimulateButtonClicked',
				'keypress :input': 'onKeyPress'
			},
			model: backendServiceM,
			submitTriggered: false,
			initialize: function() {
				this.setupXeditable();
				this.listenTo(this.model, 'change:formData', this.render);
			},
			onAddButtonClicked: function(evt) {
				evt.preventDefault();
				var doReloadForm = false;
				var formDataStr = this.$el.serialize();
				// Add clicked button to form data.
				var $button = $(evt.target);
				var name = $button.attr('name');
				if ( ! _.isUndefined(name)) {
					doReloadForm = true;
					var value = $button.attr('value');
					formDataStr += '&' + name + '=' + value;
				}
				this.submit(formDataStr, doReloadForm);
			},
			onInputChange: _.debounce(function(evt) {
				var $input = $(evt.target);
				if ($input.parents('.modal').length === 0 && $(evt.target).parents('.editableform').length === 0) {
					var formDataStr = this.$el.serialize();
					this.submit(formDataStr, false);
				}
			}, debounceDelay),
			onKeyPress: function(evt) {
				if (evt.keyCode === 13 && $(evt.target).parents('.editableform').length === 0) {
					evt.preventDefault();
					var formDataStr = this.$el.serialize();
					var doReloadForm = endsWith(evt.target.name, '.prenom');
					this.submit(formDataStr, doReloadForm);
				}
			},
			onSimulateButtonClicked: function(evt) {
				evt.preventDefault();
				var formDataStr = this.$el.serialize();
				this.submit(formDataStr, false);
			},
			render: function() {
				var formData = this.model.get('formData');
				if ( ! _.isUndefined(formData.html)) {
					this.$el.replaceWith($(formData.html));
					this.setupXeditable();
				}
				if (_.isUndefined(formData.errors)) {
					this.$el.find('.error').remove();
				}
				return this;
			},
			setupXeditable: function() {
				this.$el.find('.x-editable').editable({
					url: _.bind(function(data) {
						var $hidden = this.$el.find('[name="' + data.name + '"]');
						$hidden.val(data.value);
						var individuId = this.$el.find('[data-name="' + data.name + '"]').data('id');
						this.updatePrenoms(individuId, data.value);
						var formDataStr = this.$el.serialize();
						this.submit(formDataStr, false);
					}, this)
				});
			},
			submit: function(formDataStr, doReloadForm) {
				if (this.submitTriggered) {
					return;
				}
				this.submitTriggered = true;
				this.model.saveForm(formDataStr, _.bind(function() {
					this.submitTriggered = false;
					var formData = this.model.get('formData');
					if (_.isUndefined(formData.errors)) {
						if (doReloadForm) {
							this.model.fetchForm();
						} else {
							chartM.simulate();
						}
					}
				}, this));
			},
			updatePrenoms: function(individuId, prenom) {
				this.$el.find('option[value="' + individuId + '"]').text(prenom);
			}
		});

		return SituationFormV;

	}
);
<commit_msg>Code quality.<commit_after>define([
	'jquery',
	'underscore',
	'backbone',
	'x-editable',

	'backendServiceM',
	'chartM'
	],
	function ($, _, Backbone, xEditable, backendServiceM, chartM) {

		var debounceDelay = 100;
		var endsWith = function(str, suffix) { return str.indexOf(suffix, str.length - suffix.length) !== -1; };

		var SituationFormV = Backbone.View.extend({
			el: 'form[name="situation"]',
			events: {
				'change :input': 'onInputChange',
				'click :input.add': 'onAddButtonClicked',
				'click button.simulate': 'onSimulateButtonClicked',
				'keypress :input': 'onKeyPress'
			},
			model: backendServiceM,
			submitTriggered: false,
			initialize: function() {
				this.setupXeditable();
				this.listenTo(this.model, 'change:formData', this.render);
			},
			onAddButtonClicked: function(evt) {
				evt.preventDefault();
				var doReloadForm = false;
				var formDataStr = this.$el.serialize();
				// Add clicked button to form data.
				var $button = $(evt.target);
				var name = $button.attr('name');
				if ( ! _.isUndefined(name)) {
					doReloadForm = true;
					var value = $button.attr('value');
					formDataStr += '&' + name + '=' + value;
				}
				this.submit(formDataStr, doReloadForm);
			},
			onInputChange: _.debounce(function(evt) {
				var $input = $(evt.target);
				if ($input.parents('.modal').length === 0 && $(evt.target).parents('.editableform').length === 0) {
					var formDataStr = this.$el.serialize();
					this.submit(formDataStr, false);
				}
			}, debounceDelay),
			onKeyPress: function(evt) {
				if (evt.keyCode === 13 && $(evt.target).parents('.editableform').length === 0) {
					evt.preventDefault();
					var formDataStr = this.$el.serialize();
					var doReloadForm = endsWith(evt.target.name, '.prenom');
					this.submit(formDataStr, doReloadForm);
				}
			},
			onSimulateButtonClicked: function(evt) {
				evt.preventDefault();
				var formDataStr = this.$el.serialize();
				this.submit(formDataStr, false);
			},
			render: function() {
				var formData = this.model.get('formData');
				if ( ! _.isUndefined(formData.html)) {
					this.$el.replaceWith($(formData.html));
					this.setupXeditable();
				}
				if (_.isUndefined(formData.errors)) {
					this.$el.find('.error').remove();
				}
				return this;
			},
			setupXeditable: function() {
				this.$el.find('.x-editable').editable({
					url: _.bind(function(data) {
						var $hidden = this.$el.find('[name="' + data.name + '"]');
						$hidden.val(data.value);
						var individuId = this.$el.find('[data-name="' + data.name + '"]').data('id');
						this.updatePrenoms(individuId, data.value);
						var formDataStr = this.$el.serialize();
						this.submit(formDataStr, false);
					}, this)
				});
			},
			submit: function(formDataStr, doReloadForm) {
				if (this.submitTriggered) {
					return;
				}
				this.submitTriggered = true;
				this.model.saveForm(formDataStr, _.bind(function() {
					this.submitTriggered = false;
					var formData = this.model.get('formData');
					if (_.isUndefined(formData.errors)) {
						if (doReloadForm) {
							this.model.fetchForm();
						} else {
							chartM.simulate();
						}
					}
				}, this));
			},
			updatePrenoms: function(individuId, prenom) {
				this.$el.find('option[value="' + individuId + '"]').text(prenom);
			}
		});

		return SituationFormV;

	}
);
<|endoftext|>


<commit_before>// TODO(drheld): Count duchies / dukes / etc here.
var special_counts = new Object();

var scores = new Object();
var decks = new Object();

var deck_spot;
var points_spot;
var started = false;
var last_player = "";
var last_reveal_card = "";

function debugString() {
  return "[Scores: " + JSON.stringify(scores) + "] " +
         "[Cards: " + JSON.stringify(decks) + "]";
}

function pointsForCard(card) {
  if (card == undefined) {
    alert("Undefined card for points...");
    return 0;
  }
  if (card.indexOf("Colony") == 0) return 10;
  if (card.indexOf("Province") == 0) return 6;
  if (card.indexOf("Duchy") == 0) return 3;
  if (card.indexOf("Estate") == 0) return 1;
  if (card.indexOf("Curse") == 0) return -1;

  if (card.indexOf("Island") == 0) return 2;
  if (card.indexOf("Nobles") == 0) return 2;
  if (card.indexOf("Harem") == 0) return 2;
  if (card.indexOf("Great Hall") == 0) return 1;

  return 0;
}

function changeScore(player, points) {
  if (typeof scores[player] == "undefined") {
    scores[player] = 3;
  }
  points = parseInt(points);
  scores[player] = scores[player] + points;
}

function gainCard(player, card, count) {
  if (player == null) return;
  count = parseInt(count);

  if (typeof decks[player] == "undefined") {
    decks[player] = 10;
  }

  changeScore(player, pointsForCard(card) * count);
  decks[player] = decks[player] + count;
}

function findTrailingPlayer(text) {
  var arr = text.match(/ ([A-Za-z0-9]+)\./);
  if (arr.length == 2) {
    return arr[1];
  }
  return null;
}

function maybeHandleTurnChange(text) {
  if (text.indexOf("---") != -1) {
    // This must be a turn start.
    if (text.match(/Your turn/) != null) {
      last_player = "You";
    } else {
      var arr = text.match(/--- (.+)'s turn ---/);
      if (arr != null && arr.length == 2) {
        last_player = arr[1];
      } else {
        alert("Couldn't handle turn change: " + text);
      }
    }
    return true;
  }
  return false;
}

function maybeReturnToSupply(text) {
  if (text.indexOf("it to the supply") != -1) {
    gainCard(last_player, last_reveal_card, -1);
    return true;
  } else {
    var arr = text.match("([0-9]*) copies to the supply");
    if (arr != null && arr.length == 2) {
      gainCard(last_player, last_reveal_card, -arr[1]);
      return true;
    }
  }
  return false;
}

function maybeHandleSwindler(elems, text) {
  if (text.indexOf("replacing your") != -1) {
    if (elems.length == 2) {
      gainCard("You", elems[0].innerText, -1);
      gainCard("You", elems[1].innerText, 1);
    } else {
      alert("Replacing your has " + elems.length + " elements.");
    }
    return true;
  }
  if (text.indexOf("You replace") != -1) {
    if (elems.length == 2) {
      var arr = text.match("You replace ([^']*)'");
      if (arr != null && arr.length == 2) {
        gainCard(arr[1], elems[0].innerText, -1);
        gainCard(arr[1], elems[1].innerText, 1);
      } else {
        alert("Could not split: " + text);
      }
    } else {
      alert("Replacing your has " + elems.length + " elements.");
    }
    return true;
  }
  return false;
}

function maybeHandleSeaHag(elems, text_arr) {
  if (elems.length == 2 && pointsForCard(elems[1].innerText) == -1) {
    gainCard(text_arr[0], elems[1].innerText, 1);
    return true;
  }
}

function maybeHandleTrashing(elems, text, text_arr) {
  if (text_arr[0] == "trashing" ||  text_arr[1] == "trash") {
    for (elem in elems) {
      if (elems[elem].innerText != undefined) {
        var card = elems[elem].innerText;
        var count = getCardCount(card, text);
        gainCard(last_player, card, -count);
      }
    }
    return true;
  }
  return false;
}

function maybeHandleVp(text) {
  var re = new RegExp("[+]([0-9]+) ▼");
  var arr = (text.match(re));
  if (arr != null && arr.length == 2) {
    alert("arr[1] is " + arr[1]);
    changeScore(last_player, arr[1]);
  }
}

function getCardCount(card, text) {
  var count = 1;
  var re = new RegExp("([0-9]+) " + card);
  var arr = (text.match(re));
  if (arr != null && arr.length == 2) {
    count = arr[1];
  }
  return count;
}

function handleLogEntry(node) {
  // Gaining VP could happen in combination with other stuff.
  maybeHandleVp(node.innerText);

  elems = node.getElementsByTagName("span");
  if (elems.length == 0) {
    if (maybeHandleTurnChange(node.innerText)) return;
    if (maybeReturnToSupply(node.innerText)) return;
    return;
  }

  // Remove leading stuff from the text.
  var text = node.innerText.split(" ");
  var i = 0;
  for (i = 0; i < text.length; i++) {
    if (text[i].match(/[A-Za-z0-9]/) != null) break;
  }
  if (i == text.length) return;
  text = text.slice(i);

  if (maybeHandleSwindler(elems, node.innerText)) return;
  if (maybeHandleSeaHag(elems, text)) return;
  if (maybeHandleTrashing(elems, node.innerText, text)) return;

  if (text[0] == "trashing" ||  text[1] == "trash") {
    for (elem in elems) {
      if (elems[elem].innerText != undefined) {
        var card = elems[elem].innerText;
        var count = getCardCount(card, node.innerText);
        gainCard(last_player, card, -count);
      }
    }
    return;
  }

  // Expect one element from here on out.
  if (elems.length > 1) return;

  // It's a single card action.
  var card = elems[0].innerText;

  if (text[0].indexOf("gaining") == 0) {
    var count = getCardCount(card, node.innerText);
    gainCard(last_player, card, count);
    return;
  }

  var player = text[0];
  var action = text[1];
  var delta = 0;
  if (action.indexOf("buy") == 0 || action.indexOf("gain") == 0) {
    var count = getCardCount(card, node.innerText);
    gainCard(player, card, count);
  } else if (action.indexOf("pass") == 0) {
    gainCard(player, card, -1);
    var other_player = findTrailingPlayer(node.innerText);
    gainCard(other_player, card, 1);
  } else if (action.indexOf("receive") == 0) {
    gainCard(player, card, 1);
    var other_player = findTrailingPlayer(node.innerText);
    gainCard(other_player, card, -1);
  } else if (action.indexOf("reveal") == 0) {
    last_reveal_card = card;
  }
}

function updateScores() {
  if (points_spot == undefined) return;
  var print_scores = "Points: "
  for (var score in scores) {
    print_scores = print_scores + " " + score + "=" + scores[score];
  }
  points_spot.innerHTML = print_scores;
}

function updateDeck() {
  if (deck_spot == undefined) return;
  var print_deck = "Cards: "
  for (var deck in decks) {
    print_deck = print_deck + " " + deck + "=" + decks[deck];
  }
  deck_spot.innerHTML = print_deck;
}

function initialize() {
  started = true;
  special_counts = new Object();
  scores = new Object();
  decks = new Object();

  updateScores();
  updateDeck();
}

function handle(doc) {
  if (doc.constructor == HTMLDivElement &&
      doc.innerText.indexOf("Say") == 0) {
    initialize();
    deck_spot = doc.children[5];
    points_spot = doc.children[6];
  }

  if (doc.constructor == HTMLElement && doc.parentNode.id == "log" &&
      doc.innerText.indexOf("Turn order") != -1) {
    initialize();
  }

  if (started && doc.constructor == HTMLElement && doc.parentNode.id == "log") {
    handleLogEntry(doc);
  }

  if (started) {
    updateScores();
    updateDeck();
  }
}

document.body.addEventListener('DOMNodeInserted', function(ev) {
  handle(ev.target);
});
<commit_msg>Remove forgotten alert statement.<commit_after>// TODO(drheld): Count duchies / dukes / etc here.
var special_counts = new Object();

var scores = new Object();
var decks = new Object();

var deck_spot;
var points_spot;
var started = false;
var last_player = "";
var last_reveal_card = "";

function debugString() {
  return "[Scores: " + JSON.stringify(scores) + "] " +
         "[Cards: " + JSON.stringify(decks) + "]";
}

function pointsForCard(card) {
  if (card == undefined) {
    alert("Undefined card for points...");
    return 0;
  }
  if (card.indexOf("Colony") == 0) return 10;
  if (card.indexOf("Province") == 0) return 6;
  if (card.indexOf("Duchy") == 0) return 3;
  if (card.indexOf("Estate") == 0) return 1;
  if (card.indexOf("Curse") == 0) return -1;

  if (card.indexOf("Island") == 0) return 2;
  if (card.indexOf("Nobles") == 0) return 2;
  if (card.indexOf("Harem") == 0) return 2;
  if (card.indexOf("Great Hall") == 0) return 1;

  return 0;
}

function changeScore(player, points) {
  if (typeof scores[player] == "undefined") {
    scores[player] = 3;
  }
  points = parseInt(points);
  scores[player] = scores[player] + points;
}

function gainCard(player, card, count) {
  if (player == null) return;
  count = parseInt(count);

  if (typeof decks[player] == "undefined") {
    decks[player] = 10;
  }

  changeScore(player, pointsForCard(card) * count);
  decks[player] = decks[player] + count;
}

function findTrailingPlayer(text) {
  var arr = text.match(/ ([A-Za-z0-9]+)\./);
  if (arr.length == 2) {
    return arr[1];
  }
  return null;
}

function maybeHandleTurnChange(text) {
  if (text.indexOf("---") != -1) {
    // This must be a turn start.
    if (text.match(/Your turn/) != null) {
      last_player = "You";
    } else {
      var arr = text.match(/--- (.+)'s turn ---/);
      if (arr != null && arr.length == 2) {
        last_player = arr[1];
      } else {
        alert("Couldn't handle turn change: " + text);
      }
    }
    return true;
  }
  return false;
}

function maybeReturnToSupply(text) {
  if (text.indexOf("it to the supply") != -1) {
    gainCard(last_player, last_reveal_card, -1);
    return true;
  } else {
    var arr = text.match("([0-9]*) copies to the supply");
    if (arr != null && arr.length == 2) {
      gainCard(last_player, last_reveal_card, -arr[1]);
      return true;
    }
  }
  return false;
}

function maybeHandleSwindler(elems, text) {
  if (text.indexOf("replacing your") != -1) {
    if (elems.length == 2) {
      gainCard("You", elems[0].innerText, -1);
      gainCard("You", elems[1].innerText, 1);
    } else {
      alert("Replacing your has " + elems.length + " elements.");
    }
    return true;
  }
  if (text.indexOf("You replace") != -1) {
    if (elems.length == 2) {
      var arr = text.match("You replace ([^']*)'");
      if (arr != null && arr.length == 2) {
        gainCard(arr[1], elems[0].innerText, -1);
        gainCard(arr[1], elems[1].innerText, 1);
      } else {
        alert("Could not split: " + text);
      }
    } else {
      alert("Replacing your has " + elems.length + " elements.");
    }
    return true;
  }
  return false;
}

function maybeHandleSeaHag(elems, text_arr) {
  if (elems.length == 2 && pointsForCard(elems[1].innerText) == -1) {
    gainCard(text_arr[0], elems[1].innerText, 1);
    return true;
  }
}

function maybeHandleTrashing(elems, text, text_arr) {
  if (text_arr[0] == "trashing" ||  text_arr[1] == "trash") {
    for (elem in elems) {
      if (elems[elem].innerText != undefined) {
        var card = elems[elem].innerText;
        var count = getCardCount(card, text);
        gainCard(last_player, card, -count);
      }
    }
    return true;
  }
  return false;
}

function maybeHandleVp(text) {
  var re = new RegExp("[+]([0-9]+) ▼");
  var arr = (text.match(re));
  if (arr != null && arr.length == 2) {
    changeScore(last_player, arr[1]);
  }
}

function getCardCount(card, text) {
  var count = 1;
  var re = new RegExp("([0-9]+) " + card);
  var arr = (text.match(re));
  if (arr != null && arr.length == 2) {
    count = arr[1];
  }
  return count;
}

function handleLogEntry(node) {
  // Gaining VP could happen in combination with other stuff.
  maybeHandleVp(node.innerText);

  elems = node.getElementsByTagName("span");
  if (elems.length == 0) {
    if (maybeHandleTurnChange(node.innerText)) return;
    if (maybeReturnToSupply(node.innerText)) return;
    return;
  }

  // Remove leading stuff from the text.
  var text = node.innerText.split(" ");
  var i = 0;
  for (i = 0; i < text.length; i++) {
    if (text[i].match(/[A-Za-z0-9]/) != null) break;
  }
  if (i == text.length) return;
  text = text.slice(i);

  if (maybeHandleSwindler(elems, node.innerText)) return;
  if (maybeHandleSeaHag(elems, text)) return;
  if (maybeHandleTrashing(elems, node.innerText, text)) return;

  if (text[0] == "trashing" ||  text[1] == "trash") {
    for (elem in elems) {
      if (elems[elem].innerText != undefined) {
        var card = elems[elem].innerText;
        var count = getCardCount(card, node.innerText);
        gainCard(last_player, card, -count);
      }
    }
    return;
  }

  // Expect one element from here on out.
  if (elems.length > 1) return;

  // It's a single card action.
  var card = elems[0].innerText;

  if (text[0].indexOf("gaining") == 0) {
    var count = getCardCount(card, node.innerText);
    gainCard(last_player, card, count);
    return;
  }

  var player = text[0];
  var action = text[1];
  var delta = 0;
  if (action.indexOf("buy") == 0 || action.indexOf("gain") == 0) {
    var count = getCardCount(card, node.innerText);
    gainCard(player, card, count);
  } else if (action.indexOf("pass") == 0) {
    gainCard(player, card, -1);
    var other_player = findTrailingPlayer(node.innerText);
    gainCard(other_player, card, 1);
  } else if (action.indexOf("receive") == 0) {
    gainCard(player, card, 1);
    var other_player = findTrailingPlayer(node.innerText);
    gainCard(other_player, card, -1);
  } else if (action.indexOf("reveal") == 0) {
    last_reveal_card = card;
  }
}

function updateScores() {
  if (points_spot == undefined) return;
  var print_scores = "Points: "
  for (var score in scores) {
    print_scores = print_scores + " " + score + "=" + scores[score];
  }
  points_spot.innerHTML = print_scores;
}

function updateDeck() {
  if (deck_spot == undefined) return;
  var print_deck = "Cards: "
  for (var deck in decks) {
    print_deck = print_deck + " " + deck + "=" + decks[deck];
  }
  deck_spot.innerHTML = print_deck;
}

function initialize() {
  started = true;
  special_counts = new Object();
  scores = new Object();
  decks = new Object();

  updateScores();
  updateDeck();
}

function handle(doc) {
  if (doc.constructor == HTMLDivElement &&
      doc.innerText.indexOf("Say") == 0) {
    initialize();
    deck_spot = doc.children[5];
    points_spot = doc.children[6];
  }

  if (doc.constructor == HTMLElement && doc.parentNode.id == "log" &&
      doc.innerText.indexOf("Turn order") != -1) {
    initialize();
  }

  if (started && doc.constructor == HTMLElement && doc.parentNode.id == "log") {
    handleLogEntry(doc);
  }

  if (started) {
    updateScores();
    updateDeck();
  }
}

document.body.addEventListener('DOMNodeInserted', function(ev) {
  handle(ev.target);
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  AppRegistry,
  AsyncStorage,
  ListView,
  Navigator,
  Image,
  StyleSheet,
  Text,
  TextInput,
  TouchableHighlight,
  View,
} from 'react-native';

import PlayDates from './PlayDates';
import MainScene from './MainScene';
import UserDogs from './UserDogs';

class PlayDateCreate extends Component {
  constructor(props) {
    super(props);
    this.state={
      userID: false
    };
  }

  createGroupPressed() {
    console.log('createGroupPressed');
    // AsyncStorage.getItem("userID")
    //             .then((value) => { this.setState( {"userID": value} ); })
    //             .done();
    console.log('this.state: ' + this.state);
    let data = {
      method: 'POST',
      body: JSON.stringify({
        name: this.state.name, time_day: this.state.time_day, location: this.state.location, description: this.state.description, user_id: "21"
      }),
      headers: {
        'Accept':       'application/json',
        'Content-Type': 'application/json'
      }
    }
    fetch('http://localhost:3000/playdates', data)
        .then((response) => response.json())  // promise
        .then((responseData) => console.log(responseData))
        .catch((error) => console.log("boo"));
    this.props.navigator.pop();
  }

  componentDidMount() {
    console.log("PlayDateCreate: componentDidMount: " + this.props);
  }

  render() {
    // var playdate = this.state.playdate;

    return (
      <View style={styles.container}>
        <Text style={styles.pageTitle}>
          Create your new PlayDate
        </Text>

        <Text style={styles.label}>Group Name:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.name}
          onChangeText={(text) => this.setState({name: text})}
        />

        <Text style={styles.label}>Location:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.location}
          onChangeText={(text) => this.setState({location: text})}
        />

        <Text style={styles.label}>Time & Day of Week:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.time_day}
          onChangeText={(text) => this.setState({time_day: text})}
        />

        <Text style={styles.label}>Description:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.description}
          onChangeText={(text) => this.setState({description: text})}
        />

        <TouchableHighlight
          style={styles.button}
          onPress={() => this.createGroupPressed()}>
          <Text>Create PlayDate</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  text: {
    fontSize: 14,
  },
  button: {
    borderWidth: 2,
    borderRadius: 12,
    padding: 10,
    backgroundColor: 'antiquewhite'
  },
  inputText: {
    height: 30,
    borderColor: 'gray',
    borderWidth: 1,
    borderRadius: 16,
    padding: 10,
    backgroundColor: '#EBFAFF',
    marginBottom: 10,
  },
  textArea: {
    height: 100,
  },
  label: {
    fontSize: 14,
  }
});

module.exports = PlayDateCreate;
<commit_msg>Continue PlayDateCreate cleanup<commit_after>import React, { Component } from 'react';
import {
  AppRegistry,
  AsyncStorage,
  ListView,
  Navigator,
  Image,
  StyleSheet,
  Text,
  TextInput,
  TouchableHighlight,
  View,
} from 'react-native';

import PlayDates from './PlayDates';
import MainScene from './MainScene';
import UserDogs from './UserDogs';

class PlayDateCreate extends Component {
  constructor(props) {
    super(props);
    this.state={
      userID: false
    };
  }

  createGroupPressed() {
    console.log('createGroupPressed');
    // AsyncStorage.getItem("userID")
    //             .then((value) => { this.setState( {"userID": value} ); })
    //             .done();
    console.log('this.state: ' + this.state);
    let data = {
      method: 'POST',
      body: JSON.stringify({
        name: this.state.name, time_day: this.state.time_day, location: this.state.location, description: this.state.description, user_id: "21"
      }),
      headers: {
        'Accept':       'application/json',
        'Content-Type': 'application/json'
      }
    }
    fetch('http://localhost:3000/playdates', data)
        .then((response) => response.json())  // promise
        .then((responseData) => console.log(responseData))
        .catch((error) => console.log("boo"));
    this.props.navigator.pop();
  }

  componentDidMount() {
    console.log("PlayDateCreate: componentDidMount: " + this.props);
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.pageTitle}>
          Create your new PlayDate
        </Text>

        <Text style={styles.label}>Group Name:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.name}
          onChangeText={(text) => this.setState({name: text})}
        />

        <Text style={styles.label}>Location:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.location}
          onChangeText={(text) => this.setState({location: text})}
        />

        <Text style={styles.label}>Time & Day of Week:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.time_day}
          onChangeText={(text) => this.setState({time_day: text})}
        />

        <Text style={styles.label}>Description:</Text>
        <TextInput
          style={styles.inputText}
          value={this.state.description}
          onChangeText={(text) => this.setState({description: text})}
        />

        <TouchableHighlight
          style={styles.button}
          onPress={() => this.createGroupPressed()}>
          <Text>Create PlayDate</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  text: {
    fontSize: 14,
  },
  button: {
    borderWidth: 2,
    borderRadius: 12,
    padding: 10,
    backgroundColor: 'antiquewhite'
  },
  inputText: {
    height: 30,
    borderColor: 'gray',
    borderWidth: 1,
    borderRadius: 16,
    padding: 10,
    backgroundColor: '#EBFAFF',
    marginBottom: 10,
  },
  textArea: {
    height: 100,
  },
  label: {
    fontSize: 14,
  }
});

module.exports = PlayDateCreate;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.auth',
  name: 'Group',

  implements: [ 'foam.nanos.auth.EnabledAware' ],

  requires: [ 'foam.nanos.app.AppConfig' ],

  documentation: 'A Group of Users.',

  tableColumns: [ 'id', 'description', 'defaultMenu', 'parent' ],

  searchColumns: [ ],

  properties: [
    {
      class: 'String',
      name: 'id',
      documentation: 'Unique name of the Group.'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: true
    },
    {
      class: 'String',
      name: 'description',
      documentation: 'Description of the Group.'
    },
    {
      class: 'Reference',
      name: 'parent',
      targetDAOKey: 'groupDAO',
      of: 'foam.nanos.auth.Group',
      documentation: 'Parent group to inherit permissions from.'
    },
    {
      class: 'FObjectArray',
      of: 'foam.nanos.auth.Permission',
      name: 'permissions',
      documentation: 'Permissions set on group.'
    },
    {
      class: 'StringArray',
      of: 'foam.nanos.auth.Permission',
      name: 'permissions2',
      view: 'foam.u2.view.StringArrayRowView',
      documentation: 'Permissions set on group.'
    },
    {
      class: 'Reference',
      targetDAOKey: 'menuDAO',
      name: 'defaultMenu',
      documentation: 'Menu user redirects to after login.',
      of: 'foam.nanos.menu.Menu'
    },
    {
      class: 'Image',
      name: 'logo',
      documentation: 'Group logo.',
      displayWidth: 60
    },
    {
      class: 'String',
      name: 'topNavigation',
      value: 'foam.nanos.u2.navigation.TopNavigation',
      displayWidth: 45
    },
    {
      class: 'String',
      name: 'footerView',
      value: 'foam.nanos.u2.navigation.FooterView',
      displayWidth: 45
    },
    {
      class: 'String',
      name: 'groupCSS',
      view: { class: 'foam.u2.tag.TextArea', rows: 16, cols: 60 },
    },
    {
      class: 'Color',
      name: 'primaryColor',
      documentation: 'The following color properties can determine the color scheme of the GUI.'
    },
    { class: 'Color', name: 'secondaryColor' },
    { class: 'Color', name: 'accentColor' },
    { class: 'Color', name: 'tableColor' },
    { class: 'Color', name: 'tableHoverColor' },
    {
      class: 'String',
      name: 'url',
      value: null
    }
/*    {
      class: 'FObjectProperty',
      of: 'foam.nanos.app.AppConfig',
      name: 'appConfig',
      factory: function() { return this.AppConfig.create(); },
      documentation: 'Custom application configuration for group.'
    }
*/
    /*
      FUTURE
    {
      class: 'FObjectProperty',
      of: 'AuthConfig',
      documentation: 'Custom authentication settings for this group.'
    }
    */
  ],

  javaImports: [
    'foam.core.X',
    'foam.dao.DAO',
    'foam.nanos.app.AppConfig',
    'foam.nanos.session.Session',
    'foam.util.SafetyUtil',
    'org.eclipse.jetty.server.Request',
    'javax.servlet.http.HttpServletRequest'
  ],

  methods: [
    {
      name: 'implies',
      javaReturns: 'Boolean',
      args: [
        {
          name: 'permission',
          javaType: 'java.security.Permission'
        }
      ],
      javaCode: `
        if ( getPermissions() == null ) return false;
        for ( int i = 0 ; i < permissions_.length ; i++ ) {
          if ( new javax.security.auth.AuthPermission(permissions_[i].getId()).implies(permission) ) {
            return true;
          }
        }
        return false;`
      ,
      code: function(permissionId) {
        if ( this.permissions == null ) return false;

        for ( var i = 0 ; i < this.permissions.length ; i++ )
          if ( this.permissions[i].implies(permissionId) ) return true;

        return false;
      }
    },
    {
      name: 'getAppConfig',
      javaReturns: 'AppConfig',
      args: [
        {
          name: 'x',
          javaType: 'X'
        }
      ],
      javaCode: `
DAO userDAO         = (DAO) x.get("localUserDAO");
DAO groupDAO        = (DAO) x.get("groupDAO");
AppConfig config    = (AppConfig) ((AppConfig) x.get("appConfig")).fclone();

Session session = x.get(Session.class);
if ( session != null ) {
  User user = (User) userDAO.find(session.getUserId());
  if ( user != null ) {
    Group group    = (Group) groupDAO.find(user.getGroup());
    if ( ! SafetyUtil.isEmpty(group.getUrl()) ) {
      // populate AppConfig url with group url
      config.setUrl(group.getUrl());
    } else {
      // populate AppConfig url with request's RootUrl
      HttpServletRequest req = x.get(HttpServletRequest.class);
      if ( ! SafetyUtil.isEmpty(config.getUrl()) && ! SafetyUtil.isEmpty(req.getRequestURI())) {
        String curConfigUrl = config.getUrl();
        String request = ((Request) req).getRootURL().toString();

        // check it's http or https
        if ( curConfigUrl.startsWith("https") ) {
          config.setUrl("https" + request.substring(4));
        } else {
          config.setUrl(request);
        }
      }
    }
  }
}

return config;
        `
    }
  ]
});
<commit_msg>formatting<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.auth',
  name: 'Group',

  implements: [ 'foam.nanos.auth.EnabledAware' ],

  requires: [ 'foam.nanos.app.AppConfig' ],

  documentation: 'A Group of Users.',

  tableColumns: [ 'id', 'description', 'defaultMenu', 'parent' ],

  searchColumns: [ ],

  properties: [
    {
      class: 'String',
      name: 'id',
      documentation: 'Unique name of the Group.'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: true
    },
    {
      class: 'String',
      name: 'description',
      documentation: 'Description of the Group.'
    },
    {
      class: 'Reference',
      name: 'parent',
      targetDAOKey: 'groupDAO',
      of: 'foam.nanos.auth.Group',
      documentation: 'Parent group to inherit permissions from.'
    },
    {
      class: 'FObjectArray',
      of: 'foam.nanos.auth.Permission',
      name: 'permissions',
      documentation: 'Permissions set on group.'
    },
    {
      class: 'StringArray',
      of: 'foam.nanos.auth.Permission',
      name: 'permissions2',
      view: 'foam.u2.view.StringArrayRowView',
      documentation: 'Permissions set on group.'
    },
    {
      class: 'Reference',
      targetDAOKey: 'menuDAO',
      name: 'defaultMenu',
      documentation: 'Menu user redirects to after login.',
      of: 'foam.nanos.menu.Menu'
    },
    {
      class: 'Image',
      name: 'logo',
      documentation: 'Group logo.',
      displayWidth: 60
    },
    {
      class: 'String',
      name: 'topNavigation',
      value: 'foam.nanos.u2.navigation.TopNavigation',
      displayWidth: 45
    },
    {
      class: 'String',
      name: 'footerView',
      value: 'foam.nanos.u2.navigation.FooterView',
      displayWidth: 45
    },
    {
      class: 'String',
      name: 'groupCSS',
      view: { class: 'foam.u2.tag.TextArea', rows: 16, cols: 60 },
    },
    {
      class: 'Color',
      name: 'primaryColor',
      documentation: 'The following color properties can determine the color scheme of the GUI.'
    },
    { class: 'Color', name: 'secondaryColor' },
    { class: 'Color', name: 'accentColor' },
    { class: 'Color', name: 'tableColor' },
    { class: 'Color', name: 'tableHoverColor' },
    {
      class: 'String',
      name: 'url',
      value: null
    }
/*    {
      class: 'FObjectProperty',
      of: 'foam.nanos.app.AppConfig',
      name: 'appConfig',
      factory: function() { return this.AppConfig.create(); },
      documentation: 'Custom application configuration for group.'
    }
*/
    /*
      FUTURE
    {
      class: 'FObjectProperty',
      of: 'AuthConfig',
      documentation: 'Custom authentication settings for this group.'
    }
    */
  ],

  javaImports: [
    'foam.core.X',
    'foam.dao.DAO',
    'foam.nanos.app.AppConfig',
    'foam.nanos.session.Session',
    'foam.util.SafetyUtil',
    'org.eclipse.jetty.server.Request',
    'javax.servlet.http.HttpServletRequest'
  ],

  methods: [
    {
      name: 'implies',
      javaReturns: 'Boolean',
      args: [
        {
          name: 'permission',
          javaType: 'java.security.Permission'
        }
      ],
      javaCode: `
        if ( getPermissions() == null ) return false;
        for ( int i = 0 ; i < permissions_.length ; i++ ) {
          if ( new javax.security.auth.AuthPermission(permissions_[i].getId()).implies(permission) ) {
            return true;
          }
        }
        return false;`
      ,
      code: function(permissionId) {
        if ( this.permissions == null ) return false;

        for ( var i = 0 ; i < this.permissions.length ; i++ )
          if ( this.permissions[i].implies(permissionId) ) return true;

        return false;
      }
    },
    {
      name: 'getAppConfig',
      javaReturns: 'AppConfig',
      args: [
        {
          name: 'x',
          javaType: 'X'
        }
      ],
      javaCode: `
DAO userDAO         = (DAO) x.get("localUserDAO");
DAO groupDAO        = (DAO) x.get("groupDAO");
AppConfig config    = (AppConfig) ((AppConfig) x.get("appConfig")).fclone();

Session session = x.get(Session.class);
if ( session != null ) {
  User user = (User) userDAO.find(session.getUserId());
  if ( user != null ) {
    Group group    = (Group) groupDAO.find(user.getGroup());
    if ( ! SafetyUtil.isEmpty(group.getUrl()) ) {
      //populate AppConfig url with group url
      config.setUrl(group.getUrl());
    } else {
      //populate AppConfig url with request's RootUrl
      HttpServletRequest req = x.get(HttpServletRequest.class);
      if ( ! SafetyUtil.isEmpty(config.getUrl()) && ! SafetyUtil.isEmpty(req.getRequestURI())) {
        String curConfigUrl = config.getUrl();
        String request = ((Request) req).getRootURL().toString();

        //check it's http or https
        if ( curConfigUrl.startsWith("https") ) {
          config.setUrl("https" + request.substring(4));
        } else {
          config.setUrl(request);
        }
      }
    }
  }
}

return config;
        `
    }
  ]
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

 foam.CLASS({
  package: 'foam.nanos.ruler',
  name: 'Rule',

  documentation: 'Rule model represents rules(actions) that need to be applied in case passed object satisfies provided predicate.',

  implements: [
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  javaImports: [
    'foam.core.ContextAware',
    'foam.core.FObject',
    'foam.core.X',
    'foam.core.DirectAgency',
    'foam.nanos.logger.Logger',
    'java.util.Collection',
    'foam.nanos.ruler.RuleGroup'
  ],

  tableColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'documentation',
    'createdBy',
    'lastModifiedBy'
  ],

  searchColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'operation',
    'after',
    'validity'
  ],

  sections: [
    {
      name: 'basicInfo',
      order: 100
    },
    {
      name: '_defaultSection',
      permissionRequired: true
    }
  ],

  properties: [
    {
      class: 'String',
      name: 'id',
      updateMode: 'RO',
      tableWidth: 200,
      section: 'basicInfo'
    },
    {
      class: 'Int',
      name: 'priority',
      documentation: 'Priority defines the order in which rules are to be applied.'+
      'Rules with a higher priority are to be applied first.'+
      'The convention for values is ints that are multiple of 10.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 50,
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'documentation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: {
        class: 'foam.u2.tag.TextArea',
        rows: 12, cols: 80
      },
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'daoKey',
      documentation: 'dao name that the rule is applied on.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return {
          class: 'foam.u2.view.RichChoiceView',
          search: true,
          sections: [
            {
              heading: 'Services',
              dao: X.nSpecDAO.where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            }
          ]
        };
      },
      tableWidth: 125
    },
    {
      class: 'Enum',
      of: 'foam.nanos.ruler.Operations',
      name: 'operation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines when the rules is to be applied: put/removed'
    },
    {
      class: 'Boolean',
      name: 'after',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines if the rule needs to be applied before or after operation is completed'+
      'E.g. on dao.put: before object was stored in a dao or after.'
    },
    {
      class: 'foam.mlang.predicate.PredicateProperty',
      name: 'predicate',
      javaFactory: `
      return foam.mlang.MLang.TRUE;
      `,
      documentation: 'predicate is checked against an object; if returns true, the action is executed.'+
      'Defaults to return true.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'action',
      view: { class: 'foam.u2.view.JSONTextView' },
      documentation: 'The action to be executed if predicates returns true for passed object.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'asyncAction',
      hidden: true,
      documentation: 'The action to be executed asynchronously if predicates returns true for passed object.'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: true,
      documentation: 'Enables the rule.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 70,
      section: 'basicInfo'
    },
    {
      class: 'Boolean',
      name: 'saveHistory',
      value: false,
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Determines if history of rule execution should be saved.',
      help: 'Automatically sets to true when validity is greater than zero.',
      adapt: function(_, nu) {
        return nu || this.validity > 0;
      }
    },
    {
      class: 'Int',
      name: 'validity',
      documentation: 'Validity of the rule (in days) for automatic rescheduling.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      postSet: function(_, nu) {
        if ( nu > 0
          && ! this.saveHistory
        ) {
          this.saveHistory = true;
        }
      }
    },
    {
      class: 'Object',
      name: 'cmd',
      transient: true,
      hidden: true,
      javaFactory: `
        if ( Operations.CREATE == getOperation()
          || Operations.UPDATE == getOperation()
          || Operations.CREATE_OR_UPDATE == getOperation()
        ) {
          return RulerDAO.PUT_CMD;
        }
        return null;
      `
    },
    {
      class: 'DateTime',
      name: 'created',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        this.__subSubContext__.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        this.__subSubContext__.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    }
  ],

  methods: [
    {
      name: 'f',
      type: 'Boolean',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        }
      ],
      javaCode: `
        try {
          return getEnabled()
            && getPredicate().f(
              x.put("NEW", obj).put("OLD", oldObj)
            );
        } catch ( Throwable t ) {
          try {
            return getPredicate().f(obj);
          } catch ( Throwable th ) { }

          ((Logger) x.get("logger")).error(
            "Failed to evaluate predicate of rule: " + getId(), t);
          return false;
        }
      `
    },
    {
      name: 'apply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
        {
          name: 'agency',
          type: 'foam.core.Agency'
        }
      ],
      javaCode: `
        getAction().applyAction(x, obj, oldObj, ruler, rule, agency);
      `
    },
    {
      name: 'asyncApply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
      ],
      javaCode: `
        getAsyncAction().applyAction(x, obj, oldObj, ruler, rule, new DirectAgency());
        if ( ! getAfter() ) {
          ruler.getDelegate().cmd_(x.put("OBJ", obj), getCmd());
        }
      `
    },
    {
      name: 'updateRule',
      type: 'foam.nanos.ruler.Rule',
      documentation: 'since rules are stored as lists in the RulerDAO we use listeners to update them whenever ruleDAO is updated.' +
      'the method provides logic for modifying already stored rule. If not overridden, the incoming rule will be stored in the list as it is.',
      args: [
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        }
      ],
      javaCode: `
      return rule;`
    }
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(`
        public static Rule findById(Collection<Rule> listRule, String passedId) {
          return listRule.stream().filter(rule -> passedId.equals(rule.getId())).findFirst().orElse(null);
        }
        `);
      }
    }
  ]
});
<commit_msg>Update<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

 foam.CLASS({
  package: 'foam.nanos.ruler',
  name: 'Rule',

  documentation: 'Rule model represents rules(actions) that need to be applied in case passed object satisfies provided predicate.',

  implements: [
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  imports: [
    'userDAO'
  ],

  javaImports: [
    'foam.core.ContextAware',
    'foam.core.FObject',
    'foam.core.X',
    'foam.core.DirectAgency',
    'foam.nanos.logger.Logger',
    'java.util.Collection',
    'foam.nanos.ruler.RuleGroup'
  ],

  tableColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'documentation',
    'createdBy',
    'lastModifiedBy'
  ],

  searchColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'operation',
    'after',
    'validity'
  ],

  sections: [
    {
      name: 'basicInfo',
      order: 100
    },
    {
      name: '_defaultSection',
      permissionRequired: true
    }
  ],

  properties: [
    {
      class: 'String',
      name: 'id',
      updateMode: 'RO',
      tableWidth: 200,
      section: 'basicInfo'
    },
    {
      class: 'Int',
      name: 'priority',
      documentation: 'Priority defines the order in which rules are to be applied.'+
      'Rules with a higher priority are to be applied first.'+
      'The convention for values is ints that are multiple of 10.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 50,
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'documentation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: {
        class: 'foam.u2.tag.TextArea',
        rows: 12, cols: 80
      },
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'daoKey',
      documentation: 'dao name that the rule is applied on.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return {
          class: 'foam.u2.view.RichChoiceView',
          search: true,
          sections: [
            {
              heading: 'Services',
              dao: X.nSpecDAO.where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            }
          ]
        };
      },
      tableWidth: 125
    },
    {
      class: 'Enum',
      of: 'foam.nanos.ruler.Operations',
      name: 'operation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines when the rules is to be applied: put/removed'
    },
    {
      class: 'Boolean',
      name: 'after',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines if the rule needs to be applied before or after operation is completed'+
      'E.g. on dao.put: before object was stored in a dao or after.'
    },
    {
      class: 'foam.mlang.predicate.PredicateProperty',
      name: 'predicate',
      javaFactory: `
      return foam.mlang.MLang.TRUE;
      `,
      documentation: 'predicate is checked against an object; if returns true, the action is executed.'+
      'Defaults to return true.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'action',
      view: { class: 'foam.u2.view.JSONTextView' },
      documentation: 'The action to be executed if predicates returns true for passed object.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'asyncAction',
      hidden: true,
      documentation: 'The action to be executed asynchronously if predicates returns true for passed object.'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: true,
      documentation: 'Enables the rule.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 70,
      section: 'basicInfo'
    },
    {
      class: 'Boolean',
      name: 'saveHistory',
      value: false,
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Determines if history of rule execution should be saved.',
      help: 'Automatically sets to true when validity is greater than zero.',
      adapt: function(_, nu) {
        return nu || this.validity > 0;
      }
    },
    {
      class: 'Int',
      name: 'validity',
      documentation: 'Validity of the rule (in days) for automatic rescheduling.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      postSet: function(_, nu) {
        if ( nu > 0
          && ! this.saveHistory
        ) {
          this.saveHistory = true;
        }
      }
    },
    {
      class: 'Object',
      name: 'cmd',
      transient: true,
      hidden: true,
      javaFactory: `
        if ( Operations.CREATE == getOperation()
          || Operations.UPDATE == getOperation()
          || Operations.CREATE_OR_UPDATE == getOperation()
        ) {
          return RulerDAO.PUT_CMD;
        }
        return null;
      `
    },
    {
      class: 'DateTime',
      name: 'created',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    }
  ],

  methods: [
    {
      name: 'f',
      type: 'Boolean',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        }
      ],
      javaCode: `
        try {
          return getEnabled()
            && getPredicate().f(
              x.put("NEW", obj).put("OLD", oldObj)
            );
        } catch ( Throwable t ) {
          try {
            return getPredicate().f(obj);
          } catch ( Throwable th ) { }

          ((Logger) x.get("logger")).error(
            "Failed to evaluate predicate of rule: " + getId(), t);
          return false;
        }
      `
    },
    {
      name: 'apply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
        {
          name: 'agency',
          type: 'foam.core.Agency'
        }
      ],
      javaCode: `
        getAction().applyAction(x, obj, oldObj, ruler, rule, agency);
      `
    },
    {
      name: 'asyncApply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
      ],
      javaCode: `
        getAsyncAction().applyAction(x, obj, oldObj, ruler, rule, new DirectAgency());
        if ( ! getAfter() ) {
          ruler.getDelegate().cmd_(x.put("OBJ", obj), getCmd());
        }
      `
    },
    {
      name: 'updateRule',
      type: 'foam.nanos.ruler.Rule',
      documentation: 'since rules are stored as lists in the RulerDAO we use listeners to update them whenever ruleDAO is updated.' +
      'the method provides logic for modifying already stored rule. If not overridden, the incoming rule will be stored in the list as it is.',
      args: [
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        }
      ],
      javaCode: `
      return rule;`
    }
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(`
        public static Rule findById(Collection<Rule> listRule, String passedId) {
          return listRule.stream().filter(rule -> passedId.equals(rule.getId())).findFirst().orElse(null);
        }
        `);
      }
    }
  ]
});
<|endoftext|>


<commit_before>(function(){

    'use strict';

    angular.module("sflFormWizard", [])

        .directive('formWizard', ['$http', function($http) {

            this.template = function() {
                return $http.get('angular-form-wizard-directive.html').then(function(response) { return response; });
            };

            this.linker = function(scope, element, attributes) {
                scope.formWizardEnabled = true;
                scope.formWizardSelectedIndex = 0;
                scope.formWizardMaxIndex = fieldsetCount;
            };

            return {
                restrict: 'E',
                scope: true,
                compile: function(element, attributes) {

                    var navigatorHtmlPrefix = '
';
                    var navigatorHtmlSuffix = '
' +
                        '<button class="btn btn-default" ' +
                            'ng-click="formWizardSelectedIndex = formWizardSelectedIndex-1" ' +
                            'ng-disabled="formWizardSelectedIndex <= 0">PREV</button>' +
                        '<button class="btn btn-default" ' +
                            'ng-click="formWizardSelectedIndex = formWizardSelectedIndex+1" ' +
                            'ng-disabled="formWizardSelectedIndex >= formWizardMaxIndex">NEXT</button>' +
                        '

';

                    var form = element.find('form');
                    form.addClass('panel-body');

                    var fieldsetTitles = [];

                    angular.forEach(form.find('fieldset'), function(value, key) {
                        var fieldset = angular.element(value);
                        var legend = fieldset.find('legend');
                        fieldsetTitles.push(legend ? legend.text() : 'Step ' + (key+1));
                        fieldset.attr('data-form-wizard-index', key);
                        fieldset.attr('ng-show', 'formWizardSelectedIndex == ' + key);
                    });

                    if(fieldsetTitles.length) {
                        var navigatorHtml = '
';
                        angular.forEach(fieldsetTitles, function(value, key) {
                            navigatorHtml += '<button type="button" ' +
                                'class="btn btn-default" ' +
                                'ng-class="{ active: formWizardSelectedIndex == ' + key + ', }" ' +
                                'ng-click="formWizardSelectedIndex = ' + key + '">' +
                                '' + (key+1) + ' ' + value + '</button>'
                        });
                        navigatorHtml += '
';
                    }

                    element.prepend(navigatorHtmlPrefix + navigatorHtml + navigatorHtmlSuffix);

                    form.wrap('

');

                    return function(scope, element, attributes) {
                        scope.formWizardEnabled = true;
                        scope.formWizardSelectedIndex = 0;
                        scope.formWizardMaxIndex = fieldsetTitles.length - 1;
                    };
                }
            };
        }]);
})();
<commit_msg>Update form-wizard-directive.js<commit_after>(function(){

    'use strict';

    angular.module("sfl.form.wizard", [])

        .directive('formWizard', ['$http', function($http) {

            this.template = function() {
                return $http.get('angular-form-wizard-directive.html').then(function(response) { return response; });
            };

            this.linker = function(scope, element, attributes) {
                scope.formWizardEnabled = true;
                scope.formWizardSelectedIndex = 0;
                scope.formWizardMaxIndex = fieldsetCount;
            };

            return {
                restrict: 'E',
                scope: true,
                compile: function(element, attributes) {

                    var navigatorHtmlPrefix = '
';
                    var navigatorHtmlSuffix = '
' +
                        '<button class="btn btn-default" ' +
                            'ng-click="formWizardSelectedIndex = formWizardSelectedIndex-1" ' +
                            'ng-disabled="formWizardSelectedIndex <= 0">PREV</button>' +
                        '<button class="btn btn-default" ' +
                            'ng-click="formWizardSelectedIndex = formWizardSelectedIndex+1" ' +
                            'ng-disabled="formWizardSelectedIndex >= formWizardMaxIndex">NEXT</button>' +
                        '

';

                    var form = element.find('form');
                    form.addClass('panel-body');

                    var fieldsetTitles = [];

                    angular.forEach(form.find('fieldset'), function(value, key) {
                        var fieldset = angular.element(value);
                        var legend = fieldset.find('legend');
                        fieldsetTitles.push(legend ? legend.text() : 'Step ' + (key+1));
                        fieldset.attr('data-form-wizard-index', key);
                        fieldset.attr('ng-show', 'formWizardSelectedIndex == ' + key);
                    });

                    if(fieldsetTitles.length) {
                        var navigatorHtml = '
';
                        angular.forEach(fieldsetTitles, function(value, key) {
                            navigatorHtml += '<button type="button" ' +
                                'class="btn btn-default" ' +
                                'ng-class="{ active: formWizardSelectedIndex == ' + key + ', }" ' +
                                'ng-click="formWizardSelectedIndex = ' + key + '">' +
                                '' + (key+1) + ' ' + value + '</button>'
                        });
                        navigatorHtml += '
';
                    }

                    element.prepend(navigatorHtmlPrefix + navigatorHtml + navigatorHtmlSuffix);

                    form.wrap('

');

                    return function(scope, element, attributes) {
                        scope.formWizardEnabled = true;
                        scope.formWizardSelectedIndex = 0;
                        scope.formWizardMaxIndex = fieldsetTitles.length - 1;
                    };
                }
            };
        }]);
})();
<|endoftext|>


<commit_before>var Backbone = require('backbone');
var Router = require('builder/routes/router');

Backbone.history.start({ pushState: false, hashChange: true, root: 'builder/id' });

// // Mock this, because it fails
// Router.getCurrentRoute = function () {
//   return '/la/promosio';
// };

describe('routes/router', function () {
  var editorModel;
  var modals;
  var handleModalsRouteSpy;
  var handleAnalysesRouteSpy;
  var onChangeRouteSpy;

  beforeAll(function () {
    editorModel = new Backbone.Model({
      edition: false
    });

    widgetDefinitionsCollection = {
      trigger: jasmine.createSpy()
    };

    modals = {
      destroy: jasmine.createSpy()
    };

    handleModalsRouteSpy = jasmine.createSpy('handleModalsRouteSpy');
    handleAnalysesRouteSpy = jasmine.createSpy('handleAnalysesRouteSpy');
    handleWidgetRouteSpy = jasmine.createSpy('handleWidgetRouteSpy');

    onChangeRouteSpy = spyOn(Router, '_onChangeRoute');

    Router.init({
      modals: modals,
      editorModel: editorModel,
      widgetDefinitionsCollection: widgetDefinitionsCollection,
      handleModalsRoute: handleModalsRouteSpy,
      handleAnalysesRoute: handleAnalysesRouteSpy,
      handleWidgetRoute: handleWidgetRouteSpy,
    });

    spyOn(Backbone.History.prototype, 'matchRoot').and.returnValue(true);
  });

  afterEach(function () {
    // Reset URL Hashtag. If the URL keeps the hashtag, the test will fail next time.
    window.history.pushState('', document.title, window.location.pathname + window.location.search);
  });

  describe('._initBinds', function () {
    it('should handle analyses route', function () {
      onChangeRouteSpy.and.callThrough();
      editorModel.set({ edition: true }, { silent: true });

      Router.navigate('/layer/l1-1/analyses/a1');

      var routeModel = Router.getRouteModel().get('currentRoute');

      expect(handleModalsRouteSpy).toHaveBeenCalledWith(routeModel, modals);
      expect(handleAnalysesRouteSpy).toHaveBeenCalledWith(routeModel);
      expect(editorModel.get('edition')).toBe(false);
    });

    it('should handle widget route', function () {
      onChangeRouteSpy.and.callThrough();

      Router.navigate('/widget/widget-1337');

      var routeModel = Router.getRouteModel().get('currentRoute');

      expect(handleWidgetRouteSpy).toHaveBeenCalledWith(routeModel, widgetDefinitionsCollection);
    });
  });
});
<commit_msg>Fix linter<commit_after>var Backbone = require('backbone');
var Router = require('builder/routes/router');

Backbone.history.start({ pushState: false, hashChange: true, root: 'builder/id' });

// // Mock this, because it fails
// Router.getCurrentRoute = function () {
//   return '/la/promosio';
// };

describe('routes/router', function () {
  var editorModel;
  var modals;
  var widgetDefinitionsCollection;
  var handleModalsRouteSpy;
  var handleAnalysesRouteSpy;
  var handleWidgetRouteSpy;
  var onChangeRouteSpy;

  beforeAll(function () {
    editorModel = new Backbone.Model({
      edition: false
    });

    widgetDefinitionsCollection = {
      trigger: jasmine.createSpy()
    };

    modals = {
      destroy: jasmine.createSpy()
    };

    handleModalsRouteSpy = jasmine.createSpy('handleModalsRouteSpy');
    handleAnalysesRouteSpy = jasmine.createSpy('handleAnalysesRouteSpy');
    handleWidgetRouteSpy = jasmine.createSpy('handleWidgetRouteSpy');

    onChangeRouteSpy = spyOn(Router, '_onChangeRoute');

    Router.init({
      modals: modals,
      editorModel: editorModel,
      widgetDefinitionsCollection: widgetDefinitionsCollection,
      handleModalsRoute: handleModalsRouteSpy,
      handleAnalysesRoute: handleAnalysesRouteSpy,
      handleWidgetRoute: handleWidgetRouteSpy
    });

    spyOn(Backbone.History.prototype, 'matchRoot').and.returnValue(true);
  });

  afterEach(function () {
    // Reset URL Hashtag. If the URL keeps the hashtag, the test will fail next time.
    window.history.pushState('', document.title, window.location.pathname + window.location.search);
  });

  describe('._initBinds', function () {
    it('should handle analyses route', function () {
      onChangeRouteSpy.and.callThrough();
      editorModel.set({ edition: true }, { silent: true });

      Router.navigate('/layer/l1-1/analyses/a1');

      var routeModel = Router.getRouteModel().get('currentRoute');

      expect(handleModalsRouteSpy).toHaveBeenCalledWith(routeModel, modals);
      expect(handleAnalysesRouteSpy).toHaveBeenCalledWith(routeModel);
      expect(editorModel.get('edition')).toBe(false);
    });

    it('should handle widget route', function () {
      onChangeRouteSpy.and.callThrough();

      Router.navigate('/widget/widget-1337');

      var routeModel = Router.getRouteModel().get('currentRoute');

      expect(handleWidgetRouteSpy).toHaveBeenCalledWith(routeModel, widgetDefinitionsCollection);
    });
  });
});
<|endoftext|>